All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mingming Cao <cmm@us.ibm.com>
To: ext2-devel <ext2-devel@lists.sourceforge.net>,
	Andrew Morton <akpm@osdl.org>,
	"Stephen C. Tweedie" <sct@redhat.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	linux-fsdevel@vger.kernel.org
Cc: Badari Pulavarty <pbadari@us.ibm.com>,
	suparna@in.ibm.com, tytso@mit.edu, alex@clusterfs.com,
	adilger@clusterfs.com
Subject: [RFC] [PATCH 4/4]add ext3 writeback writpages
Date: Sun, 17 Jul 2005 10:41:07 -0700	[thread overview]
Message-ID: <1121622067.4609.27.camel@localhost.localdomain> (raw)
In-Reply-To: <1110839154.24286.302.camel@dyn318077bld.beaverton.ibm.com>

support multiple block allocation for ext3 writeback mode through writepages().


---

 linux-2.6.12-ming/fs/ext3/inode.c       |  131 ++++++++++++++++++++++++++++++++
 linux-2.6.12-ming/fs/mpage.c            |    8 +
 linux-2.6.12-ming/include/linux/mpage.h |   17 ++++
 3 files changed, 153 insertions(+), 3 deletions(-)

diff -puN fs/ext3/inode.c~writepages fs/ext3/inode.c
--- linux-2.6.12/fs/ext3/inode.c~writepages	2005-07-17 17:11:43.239274864 -0700
+++ linux-2.6.12-ming/fs/ext3/inode.c	2005-07-17 17:11:43.259271824 -0700
@@ -36,6 +36,7 @@
 #include <linux/writeback.h>
 #include <linux/mpage.h>
 #include <linux/uio.h>
+#include <linux/pagevec.h>
 #include "xattr.h"
 #include "acl.h"
 
@@ -1719,6 +1720,135 @@ out_fail:
 	return ret;
 }
 
+static int
+ext3_writeback_writepages(struct address_space *mapping,
+				struct writeback_control *wbc)
+{
+	struct inode *inode = mapping->host;
+	const unsigned blkbits = inode->i_blkbits;
+	int err = 0;
+	int ret = 0;
+	int done = 0;
+	unsigned int max_pages_to_cluster = 0;
+	struct pagevec pvec;
+	int nr_pages;
+	pgoff_t index;
+	pgoff_t end = -1;		/* Inclusive */
+	int scanned = 0;
+	int is_range = 0;
+	struct page *page;
+	struct mpageio mio = {
+		.bio = NULL
+	};
+
+	pagevec_init(&pvec, 0);
+	if (wbc->sync_mode == WB_SYNC_NONE) {
+		index = mapping->writeback_index; /* Start from prev offset */
+	} else {
+		index = 0;			  /* whole-file sweep */
+		scanned = 1;
+	}
+	if (wbc->start || wbc->end) {
+		index = wbc->start >> PAGE_CACHE_SHIFT;
+		end = wbc->end >> PAGE_CACHE_SHIFT;
+		is_range = 1;
+		scanned = 1;
+	}
+	max_pages_to_cluster = min(EXT3_MAX_TRANS_DATA, (pgoff_t)PAGEVEC_SIZE);
+
+retry:
+	down_read(&inode->i_alloc_sem);
+	while (!done && (index <= end) &&
+			(nr_pages = pagevec_contig_lookup_tag(&pvec, mapping,
+			&index, PAGECACHE_TAG_DIRTY,
+			min(end - index, max_pages_to_cluster-1) + 1))) {
+		unsigned i;
+
+		scanned = 1;
+		for (i = 0; i < nr_pages; i++) {
+			page = pvec.pages[i];
+
+			lock_page(page);
+
+			if (unlikely(page->mapping != mapping)) {
+				unlock_page(page);
+				break;
+			}
+
+			if (unlikely(is_range) && page->index > end) {
+				unlock_page(page);
+				break;
+			}
+
+			if (wbc->sync_mode != WB_SYNC_NONE)
+				wait_on_page_writeback(page);
+
+			if (PageWriteback(page) ||
+					!clear_page_dirty_for_io(page)) {
+				unlock_page(page);
+				break;
+			}
+		}
+
+		if (i) {
+			unsigned j;
+			handle_t *handle;
+
+			page = pvec.pages[i-1];
+			index = page->index + 1;
+			mio.final_block_in_request =
+				min(index, end) << (PAGE_CACHE_SHIFT - blkbits);
+
+			handle = ext3_journal_start(inode,
+					i + ext3_writepage_trans_blocks(inode));
+
+			if (IS_ERR(handle)) {
+				err = PTR_ERR(handle);
+				done = 1;
+			}
+			for (j = 0; j < i; j++) {
+				page = pvec.pages[j];
+				if (!done) {
+					ret = __mpage_writepage(&mio, page,
+						ext3_writepages_get_blocks, wbc,
+						ext3_writeback_writepage_helper);
+					if (ret || (--(wbc->nr_to_write) <= 0))
+						done = 1;
+				} else {
+					redirty_page_for_writepage(wbc, page);
+					unlock_page(page);
+				}
+			}
+			if (!err && mio.bio)
+				mio.bio = mpage_bio_submit(WRITE, mio.bio);
+			if (!err)
+				err = ext3_journal_stop(handle);
+			if (!ret) {
+				ret = err;
+				if (ret)
+					done = 1;
+			}
+		}
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+
+	up_read(&inode->i_alloc_sem);
+
+	if (!scanned && !done) {
+		/*
+		 * We hit the last page and there is more work to be done: wrap
+		 * back to the start of the file
+		 */
+		scanned = 1;
+		index = 0;
+		goto retry;
+	}
+	if (!is_range)
+		mapping->writeback_index = index;
+	return ret;
+}
+
 static int ext3_journalled_writepage(struct page *page,
 				struct writeback_control *wbc)
 {
@@ -1923,6 +2053,7 @@ static struct address_space_operations e
 	.readpage	= ext3_readpage,
 	.readpages	= ext3_readpages,
 	.writepage	= ext3_writeback_writepage,
+	.writepages	= ext3_writeback_writepages,
 	.sync_page	= block_sync_page,
 	.prepare_write	= ext3_prepare_write,
 	.commit_write	= ext3_writeback_commit_write,
diff -puN fs/mpage.c~writepages fs/mpage.c
--- linux-2.6.12/fs/mpage.c~writepages	2005-07-17 17:11:43.243274256 -0700
+++ linux-2.6.12-ming/fs/mpage.c	2005-07-17 17:12:43.220156384 -0700
@@ -90,7 +90,7 @@ static int mpage_end_io_write(struct bio
 	return 0;
 }
 
-static struct bio *mpage_bio_submit(int rw, struct bio *bio)
+struct bio *mpage_bio_submit(int rw, struct bio *bio)
 {
 	bio->bi_end_io = mpage_end_io_read;
 	if (rw == WRITE)
@@ -373,6 +373,7 @@ int mpage_readpage(struct page *page, ge
 }
 EXPORT_SYMBOL(mpage_readpage);
 
+#if 0
 struct mpageio {
 	struct bio *bio;
 	struct buffer_head map_bh;
@@ -383,6 +384,7 @@ struct mpageio {
 	sector_t boundary_block;
 	struct block_device *boundary_bdev;
 };
+#endif
 
 /*
  * Maps as many contiguous disk blocks as it can within the range of
@@ -450,7 +452,7 @@ static unsigned long mpage_get_more_bloc
  * written, so it can intelligently allocate a suitably-sized BIO.  For now,
  * just allocate full-size (16-page) BIOs.
  */
-static int
+int
 __mpage_writepage(struct mpageio *mio, struct page *page,
 	get_blocks_t get_blocks, struct writeback_control *wbc,
 	writepage_t writepage_fn)
@@ -532,7 +534,7 @@ __mpage_writepage(struct mpageio *mio, s
 	 */
 	BUG_ON(!PageUptodate(page));
 	block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
-	last_block = (i_size - 1) >> blkbits;
+	last_block = (i_size) >> blkbits;
 	blocks_to_skip = block_in_file - mio->block_in_file;
 	mio->block_in_file = block_in_file;
 	if (blocks_to_skip < (map_bh->b_size >> blkbits)) {
diff -puN include/linux/mpage.h~writepages include/linux/mpage.h
--- linux-2.6.12/include/linux/mpage.h~writepages	2005-07-17 17:11:43.246273800 -0700
+++ linux-2.6.12-ming/include/linux/mpage.h	2005-07-17 17:11:43.263271216 -0700
@@ -9,9 +9,23 @@
  * (And no, it doesn't do the #ifdef __MPAGE_H thing, and it doesn't do
  * nested includes.  Get it right in the .c file).
  */
+#ifndef _LINUX_BUFFER_HEAD_H
+#include <linux/buffer_head.h>
+#endif
 
 struct writeback_control;
 
+struct mpageio {
+	struct bio *bio;
+	struct buffer_head map_bh;
+	unsigned long block_in_file;
+	unsigned long final_block_in_request;
+	sector_t block_in_bio;
+	int boundary;
+	sector_t boundary_block;
+	struct block_device *boundary_bdev;
+};
+
 int mpage_readpages(struct address_space *mapping, struct list_head *pages,
 				unsigned nr_pages, get_block_t get_block);
 int mpage_readpage(struct page *page, get_block_t get_block);
@@ -23,6 +37,9 @@ int mpage_writepage(struct page *page, g
 int __mpage_writepages(struct address_space *mapping,
                 struct writeback_control *wbc, get_blocks_t get_blocks,
                 writepage_t writepage);
+int __mpage_writepage(struct mpageio *mio, struct page *page,
+        get_blocks_t get_blocks, struct writeback_control *wbc,
+        writepage_t writepage_fn);
 
 static inline int
 generic_writepages(struct address_space *mapping, struct writeback_control *wbc)

_



WARNING: multiple messages have this Message-ID (diff)
From: Mingming Cao <cmm@us.ibm.com>
To: ext2-devel <ext2-devel@lists.sourceforge.net>,
	Andrew Morton <akpm@osdl.org>,
	"Stephen C. Tweedie" <sct@redhat.com>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	linux-fsdevel@vger.kernel.org
Cc: Badari Pulavarty <pbadari@us.ibm.com>,
	suparna@in.ibm.com, tytso@mit.edu, alex@clusterfs.com,
	adilger@clusterfs.com
Subject: [RFC] [PATCH 4/4]add ext3 writeback writpages
Date: Sun, 17 Jul 2005 10:41:07 -0700	[thread overview]
Message-ID: <1121622067.4609.27.camel@localhost.localdomain> (raw)
In-Reply-To: <1110839154.24286.302.camel@dyn318077bld.beaverton.ibm.com>

support multiple block allocation for ext3 writeback mode through writepages().


---

 linux-2.6.12-ming/fs/ext3/inode.c       |  131 ++++++++++++++++++++++++++++++++
 linux-2.6.12-ming/fs/mpage.c            |    8 +
 linux-2.6.12-ming/include/linux/mpage.h |   17 ++++
 3 files changed, 153 insertions(+), 3 deletions(-)

diff -puN fs/ext3/inode.c~writepages fs/ext3/inode.c
--- linux-2.6.12/fs/ext3/inode.c~writepages	2005-07-17 17:11:43.239274864 -0700
+++ linux-2.6.12-ming/fs/ext3/inode.c	2005-07-17 17:11:43.259271824 -0700
@@ -36,6 +36,7 @@
 #include <linux/writeback.h>
 #include <linux/mpage.h>
 #include <linux/uio.h>
+#include <linux/pagevec.h>
 #include "xattr.h"
 #include "acl.h"
 
@@ -1719,6 +1720,135 @@ out_fail:
 	return ret;
 }
 
+static int
+ext3_writeback_writepages(struct address_space *mapping,
+				struct writeback_control *wbc)
+{
+	struct inode *inode = mapping->host;
+	const unsigned blkbits = inode->i_blkbits;
+	int err = 0;
+	int ret = 0;
+	int done = 0;
+	unsigned int max_pages_to_cluster = 0;
+	struct pagevec pvec;
+	int nr_pages;
+	pgoff_t index;
+	pgoff_t end = -1;		/* Inclusive */
+	int scanned = 0;
+	int is_range = 0;
+	struct page *page;
+	struct mpageio mio = {
+		.bio = NULL
+	};
+
+	pagevec_init(&pvec, 0);
+	if (wbc->sync_mode == WB_SYNC_NONE) {
+		index = mapping->writeback_index; /* Start from prev offset */
+	} else {
+		index = 0;			  /* whole-file sweep */
+		scanned = 1;
+	}
+	if (wbc->start || wbc->end) {
+		index = wbc->start >> PAGE_CACHE_SHIFT;
+		end = wbc->end >> PAGE_CACHE_SHIFT;
+		is_range = 1;
+		scanned = 1;
+	}
+	max_pages_to_cluster = min(EXT3_MAX_TRANS_DATA, (pgoff_t)PAGEVEC_SIZE);
+
+retry:
+	down_read(&inode->i_alloc_sem);
+	while (!done && (index <= end) &&
+			(nr_pages = pagevec_contig_lookup_tag(&pvec, mapping,
+			&index, PAGECACHE_TAG_DIRTY,
+			min(end - index, max_pages_to_cluster-1) + 1))) {
+		unsigned i;
+
+		scanned = 1;
+		for (i = 0; i < nr_pages; i++) {
+			page = pvec.pages[i];
+
+			lock_page(page);
+
+			if (unlikely(page->mapping != mapping)) {
+				unlock_page(page);
+				break;
+			}
+
+			if (unlikely(is_range) && page->index > end) {
+				unlock_page(page);
+				break;
+			}
+
+			if (wbc->sync_mode != WB_SYNC_NONE)
+				wait_on_page_writeback(page);
+
+			if (PageWriteback(page) ||
+					!clear_page_dirty_for_io(page)) {
+				unlock_page(page);
+				break;
+			}
+		}
+
+		if (i) {
+			unsigned j;
+			handle_t *handle;
+
+			page = pvec.pages[i-1];
+			index = page->index + 1;
+			mio.final_block_in_request =
+				min(index, end) << (PAGE_CACHE_SHIFT - blkbits);
+
+			handle = ext3_journal_start(inode,
+					i + ext3_writepage_trans_blocks(inode));
+
+			if (IS_ERR(handle)) {
+				err = PTR_ERR(handle);
+				done = 1;
+			}
+			for (j = 0; j < i; j++) {
+				page = pvec.pages[j];
+				if (!done) {
+					ret = __mpage_writepage(&mio, page,
+						ext3_writepages_get_blocks, wbc,
+						ext3_writeback_writepage_helper);
+					if (ret || (--(wbc->nr_to_write) <= 0))
+						done = 1;
+				} else {
+					redirty_page_for_writepage(wbc, page);
+					unlock_page(page);
+				}
+			}
+			if (!err && mio.bio)
+				mio.bio = mpage_bio_submit(WRITE, mio.bio);
+			if (!err)
+				err = ext3_journal_stop(handle);
+			if (!ret) {
+				ret = err;
+				if (ret)
+					done = 1;
+			}
+		}
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+
+	up_read(&inode->i_alloc_sem);
+
+	if (!scanned && !done) {
+		/*
+		 * We hit the last page and there is more work to be done: wrap
+		 * back to the start of the file
+		 */
+		scanned = 1;
+		index = 0;
+		goto retry;
+	}
+	if (!is_range)
+		mapping->writeback_index = index;
+	return ret;
+}
+
 static int ext3_journalled_writepage(struct page *page,
 				struct writeback_control *wbc)
 {
@@ -1923,6 +2053,7 @@ static struct address_space_operations e
 	.readpage	= ext3_readpage,
 	.readpages	= ext3_readpages,
 	.writepage	= ext3_writeback_writepage,
+	.writepages	= ext3_writeback_writepages,
 	.sync_page	= block_sync_page,
 	.prepare_write	= ext3_prepare_write,
 	.commit_write	= ext3_writeback_commit_write,
diff -puN fs/mpage.c~writepages fs/mpage.c
--- linux-2.6.12/fs/mpage.c~writepages	2005-07-17 17:11:43.243274256 -0700
+++ linux-2.6.12-ming/fs/mpage.c	2005-07-17 17:12:43.220156384 -0700
@@ -90,7 +90,7 @@ static int mpage_end_io_write(struct bio
 	return 0;
 }
 
-static struct bio *mpage_bio_submit(int rw, struct bio *bio)
+struct bio *mpage_bio_submit(int rw, struct bio *bio)
 {
 	bio->bi_end_io = mpage_end_io_read;
 	if (rw == WRITE)
@@ -373,6 +373,7 @@ int mpage_readpage(struct page *page, ge
 }
 EXPORT_SYMBOL(mpage_readpage);
 
+#if 0
 struct mpageio {
 	struct bio *bio;
 	struct buffer_head map_bh;
@@ -383,6 +384,7 @@ struct mpageio {
 	sector_t boundary_block;
 	struct block_device *boundary_bdev;
 };
+#endif
 
 /*
  * Maps as many contiguous disk blocks as it can within the range of
@@ -450,7 +452,7 @@ static unsigned long mpage_get_more_bloc
  * written, so it can intelligently allocate a suitably-sized BIO.  For now,
  * just allocate full-size (16-page) BIOs.
  */
-static int
+int
 __mpage_writepage(struct mpageio *mio, struct page *page,
 	get_blocks_t get_blocks, struct writeback_control *wbc,
 	writepage_t writepage_fn)
@@ -532,7 +534,7 @@ __mpage_writepage(struct mpageio *mio, s
 	 */
 	BUG_ON(!PageUptodate(page));
 	block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
-	last_block = (i_size - 1) >> blkbits;
+	last_block = (i_size) >> blkbits;
 	blocks_to_skip = block_in_file - mio->block_in_file;
 	mio->block_in_file = block_in_file;
 	if (blocks_to_skip < (map_bh->b_size >> blkbits)) {
diff -puN include/linux/mpage.h~writepages include/linux/mpage.h
--- linux-2.6.12/include/linux/mpage.h~writepages	2005-07-17 17:11:43.246273800 -0700
+++ linux-2.6.12-ming/include/linux/mpage.h	2005-07-17 17:11:43.263271216 -0700
@@ -9,9 +9,23 @@
  * (And no, it doesn't do the #ifdef __MPAGE_H thing, and it doesn't do
  * nested includes.  Get it right in the .c file).
  */
+#ifndef _LINUX_BUFFER_HEAD_H
+#include <linux/buffer_head.h>
+#endif
 
 struct writeback_control;
 
+struct mpageio {
+	struct bio *bio;
+	struct buffer_head map_bh;
+	unsigned long block_in_file;
+	unsigned long final_block_in_request;
+	sector_t block_in_bio;
+	int boundary;
+	sector_t boundary_block;
+	struct block_device *boundary_bdev;
+};
+
 int mpage_readpages(struct address_space *mapping, struct list_head *pages,
 				unsigned nr_pages, get_block_t get_block);
 int mpage_readpage(struct page *page, get_block_t get_block);
@@ -23,6 +37,9 @@ int mpage_writepage(struct page *page, g
 int __mpage_writepages(struct address_space *mapping,
                 struct writeback_control *wbc, get_blocks_t get_blocks,
                 writepage_t writepage);
+int __mpage_writepage(struct mpageio *mio, struct page *page,
+        get_blocks_t get_blocks, struct writeback_control *wbc,
+        writepage_t writepage_fn);
 
 static inline int
 generic_writepages(struct address_space *mapping, struct writeback_control *wbc)

_




-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click

  parent reply	other threads:[~2005-07-17 17:46 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1110839154.24286.302.camel@dyn318077bld.beaverton.ibm.com>
2005-07-17 17:40 ` [RFC] [PATCH 0/4]Multiple block allocation and delayed allocation for ext3 Mingming Cao
2005-07-17 17:45   ` Mingming Cao
2005-07-17 17:45     ` Mingming Cao
2005-07-17 17:40 ` [RFC] [PATCH 1/4]Multiple block " Mingming Cao
2005-07-17 17:40   ` Mingming Cao
2005-07-17 17:40 ` [RFC] [PATCH 2/4]delayed " Mingming Cao
2005-07-18  1:47   ` [Ext2-devel] " Andreas Dilger
2005-07-18 17:32     ` Mingming Cao
2005-07-19  0:25     ` Badari Pulavarty
2005-07-26 22:52   ` Andrew Morton
2005-07-26 22:52     ` Andrew Morton
2005-07-26 22:55     ` Badari Pulavarty
2005-07-26 22:55       ` Badari Pulavarty
2005-07-17 17:40 ` [RFC] [PATCH 3/4]generic getblocks() support in mpage_writepages Mingming Cao
2005-07-17 17:40   ` Mingming Cao
2005-07-17 17:41 ` Mingming Cao [this message]
2005-07-17 17:41   ` [RFC] [PATCH 4/4]add ext3 writeback writpages Mingming Cao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1121622067.4609.27.camel@localhost.localdomain \
    --to=cmm@us.ibm.com \
    --cc=adilger@clusterfs.com \
    --cc=akpm@osdl.org \
    --cc=alex@clusterfs.com \
    --cc=ext2-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbadari@us.ibm.com \
    --cc=sct@redhat.com \
    --cc=suparna@in.ibm.com \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.