All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH] map multiple blocks at a time in mpage_readpages()
@ 2006-02-14 17:49 Badari Pulavarty
  2006-02-14 19:27 ` christoph
  2006-02-14 23:30 ` Daniel Phillips
  0 siblings, 2 replies; 6+ messages in thread
From: Badari Pulavarty @ 2006-02-14 17:49 UTC (permalink / raw)
  To: christoph, akpm, mcao; +Cc: linux-fsdevel, lkml

[-- Attachment #1: Type: text/plain, Size: 751 bytes --]

Hi,

I re-did the support for mpage_readpages() to map multiple blocks
at a time (basically, get_blocks()). Instead of adding new
get_blocks() and pass it around, I use "bh->b_size" to indicate
how much of disk mapping we are interested in to get_block().

This way no changes existing interfaces and no new routines need.
Filesystem can choose to ignore the passed in "bh->b_size" value
and map one block at a time (ext2, reiser3, etc..)

Currently, I modified JFS & XFS to make use of it and support
multiple blocks and planning to integrate with Mingming's ext3
multiblock work (which is in -mm). 

Todo:

1) Integrate with Mingming's multiblock get_block() support for ext3.

2) kill .*_get_blocks() added for DIO ?


Comments ?

Thanks,
Badari



[-- Attachment #2: getblocks-readpages.patch --]
[-- Type: text/x-patch, Size: 9200 bytes --]

This patch changes mpage_readpages() and get_block() to
get the disk mapping information for multiple blocks at the 
same time. 

Instead of adding new get_blocks() and pass it around every
where, I overload b_size of bufferhead to pass in how much
disk mapping we are requesting. Only the filesystems who
care to use this information and provide multiple disk
blocks at a time can choose to do so. 

No changes are needed for the filesystems who wants to ignore this.

Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>

 fs/buffer.c                 |    6 ++
 fs/jfs/inode.c              |    3 -
 fs/mpage.c                  |   91 +++++++++++++++++++++++++++++++++++---------
 fs/xfs/linux-2.6/xfs_aops.c |    4 -
 4 files changed, 84 insertions(+), 20 deletions(-)

Index: linux-2.6.16-rc3/fs/mpage.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/mpage.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/mpage.c	2006-02-14 08:39:02.000000000 -0800
@@ -165,7 +165,9 @@ map_buffer_to_page(struct page *page, st
 
 static struct bio *
 do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
-			sector_t *last_block_in_bio, get_block_t get_block)
+			sector_t *last_block_in_bio, struct buffer_head *map_bh,
+			unsigned long *first_logical_block, int *map_valid,
+			get_block_t get_block)
 {
 	struct inode *inode = page->mapping->host;
 	const unsigned blkbits = inode->i_blkbits;
@@ -177,29 +179,63 @@ do_mpage_readpage(struct bio *bio, struc
 	unsigned page_block;
 	unsigned first_hole = blocks_per_page;
 	struct block_device *bdev = NULL;
-	struct buffer_head bh;
 	int length;
 	int fully_mapped = 1;
+	unsigned nblocks, i;
 
 	if (page_has_buffers(page))
 		goto confused;
 
 	block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
 	last_block = (i_size_read(inode) + blocksize - 1) >> blkbits;
+	page_block = 0;
+
+	/*
+	 * Map blocks using the result from the last get_blocks call first.
+	 */
+	nblocks = map_bh->b_size >> blkbits;
+	if (*map_valid &&
+	    block_in_file > *first_logical_block &&
+	    block_in_file < (*first_logical_block + nblocks)) {
+		unsigned map_offset = block_in_file - *first_logical_block;
+		unsigned last = nblocks - map_offset;
+
+		for (i = 0; ; i++) {
+			if (i == last) {
+				*map_valid = 0;
+				break;
+			} else if (page_block == blocks_per_page)
+				break;
+			blocks[page_block] = map_bh->b_blocknr + map_offset + i;
+			page_block++;
+			block_in_file++;
+		}
+		bdev = map_bh->b_bdev;
+	}
+
+	/*
+	 * Then do more get_blocks calls until we are done with this page.
+	 */
+	map_bh->b_page = page;
+	while (page_block < blocks_per_page) {
+		map_bh->b_state = 0;
+		map_bh->b_size = 0;
 
-	bh.b_page = page;
-	for (page_block = 0; page_block < blocks_per_page;
-				page_block++, block_in_file++) {
-		bh.b_state = 0;
 		if (block_in_file < last_block) {
-			if (get_block(inode, block_in_file, &bh, 0))
+			map_bh->b_size = (last_block - block_in_file) << blkbits;
+			if (get_block(inode, block_in_file, map_bh, 0))
 				goto confused;
+			*first_logical_block = block_in_file;
+			*map_valid  = 1;
 		}
 
-		if (!buffer_mapped(&bh)) {
+		if (!buffer_mapped(map_bh)) {
 			fully_mapped = 0;
 			if (first_hole == blocks_per_page)
 				first_hole = page_block;
+			page_block++;
+			block_in_file++;
+			*map_valid = 0;
 			continue;
 		}
 
@@ -209,8 +245,8 @@ do_mpage_readpage(struct bio *bio, struc
 		 * we just collected from get_block into the page's buffers
 		 * so readpage doesn't have to repeat the get_block call
 		 */
-		if (buffer_uptodate(&bh)) {
-			map_buffer_to_page(page, &bh, page_block);
+		if (buffer_uptodate(map_bh)) {
+			map_buffer_to_page(page, map_bh, page_block);
 			goto confused;
 		}
 	
@@ -218,10 +254,20 @@ do_mpage_readpage(struct bio *bio, struc
 			goto confused;		/* hole -> non-hole */
 
 		/* Contiguous blocks? */
-		if (page_block && blocks[page_block-1] != bh.b_blocknr-1)
+		if (page_block && blocks[page_block-1] != map_bh->b_blocknr-1)
 			goto confused;
-		blocks[page_block] = bh.b_blocknr;
-		bdev = bh.b_bdev;
+		nblocks = map_bh->b_size >> blkbits;
+		for (i = 0; ; i++) {
+			if (i == nblocks) {
+				*map_valid = 0;
+				break;
+			} else if (page_block == blocks_per_page)
+				break;
+			blocks[page_block] = map_bh->b_blocknr + i;
+			page_block++;
+			block_in_file++;
+		}
+		bdev = map_bh->b_bdev;
 	}
 
 	if (first_hole != blocks_per_page) {
@@ -260,7 +306,7 @@ alloc_new:
 		goto alloc_new;
 	}
 
-	if (buffer_boundary(&bh) || (first_hole != blocks_per_page))
+	if (buffer_boundary(map_bh) || (first_hole != blocks_per_page))
 		bio = mpage_bio_submit(READ, bio);
 	else
 		*last_block_in_bio = blocks[blocks_per_page - 1];
@@ -331,6 +377,9 @@ mpage_readpages(struct address_space *ma
 	unsigned page_idx;
 	sector_t last_block_in_bio = 0;
 	struct pagevec lru_pvec;
+	struct buffer_head map_bh;
+	unsigned long first_logical_block = 0;
+	int map_valid = 0;
 
 	pagevec_init(&lru_pvec, 0);
 	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
@@ -342,7 +391,9 @@ mpage_readpages(struct address_space *ma
 					page->index, GFP_KERNEL)) {
 			bio = do_mpage_readpage(bio, page,
 					nr_pages - page_idx,
-					&last_block_in_bio, get_block);
+					&last_block_in_bio, &map_bh,
+					&first_logical_block,
+					&map_valid, get_block);
 			if (!pagevec_add(&lru_pvec, page))
 				__pagevec_lru_add(&lru_pvec);
 		} else {
@@ -364,9 +415,14 @@ int mpage_readpage(struct page *page, ge
 {
 	struct bio *bio = NULL;
 	sector_t last_block_in_bio = 0;
+	struct buffer_head map_bh;
+	unsigned long first_logical_block = 0;
+	int map_valid = 0;
+
 
-	bio = do_mpage_readpage(bio, page, 1,
-			&last_block_in_bio, get_block);
+	bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio,
+			&map_bh, &first_logical_block, &map_valid,
+			get_block);
 	if (bio)
 		mpage_bio_submit(READ, bio);
 	return 0;
@@ -472,6 +528,7 @@ __mpage_writepage(struct bio *bio, struc
 	for (page_block = 0; page_block < blocks_per_page; ) {
 
 		map_bh.b_state = 0;
+		map_bh.b_size = 1 << blkbits;
 		if (get_block(inode, block_in_file, &map_bh, 1))
 			goto confused;
 		if (buffer_new(&map_bh))
Index: linux-2.6.16-rc3/fs/buffer.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/buffer.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/buffer.c	2006-02-14 08:40:21.000000000 -0800
@@ -1785,6 +1785,7 @@ static int __block_write_full_page(struc
 			clear_buffer_dirty(bh);
 			set_buffer_uptodate(bh);
 		} else if (!buffer_mapped(bh) && buffer_dirty(bh)) {
+			bh->b_size = 1 << inode->i_blkbits;
 			err = get_block(inode, block, bh, 1);
 			if (err)
 				goto recover;
@@ -1938,6 +1939,7 @@ static int __block_prepare_write(struct 
 		if (buffer_new(bh))
 			clear_buffer_new(bh);
 		if (!buffer_mapped(bh)) {
+			bh->b_size = 1 << inode->i_blkbits;
 			err = get_block(inode, block, bh, 1);
 			if (err)
 				break;
@@ -2093,6 +2095,7 @@ int block_read_full_page(struct page *pa
 
 			fully_mapped = 0;
 			if (iblock < lblock) {
+				bh->b_size = 1 << inode->i_blkbits;
 				err = get_block(inode, iblock, bh, 0);
 				if (err)
 					SetPageError(page);
@@ -2414,6 +2417,7 @@ int nobh_prepare_write(struct page *page
 		create = 1;
 		if (block_start >= to)
 			create = 0;
+		map_bh.b_size = 1 << blkbits;
 		ret = get_block(inode, block_in_file + block_in_page,
 					&map_bh, create);
 		if (ret)
@@ -2674,6 +2678,7 @@ int block_truncate_page(struct address_s
 
 	err = 0;
 	if (!buffer_mapped(bh)) {
+		bh->b_size = 1 << inode->i_blkbits;
 		err = get_block(inode, iblock, bh, 0);
 		if (err)
 			goto unlock;
@@ -2760,6 +2765,7 @@ sector_t generic_block_bmap(struct addre
 	struct inode *inode = mapping->host;
 	tmp.b_state = 0;
 	tmp.b_blocknr = 0;
+	tmp.b_size = 1 << inode->i_blkbits;
 	get_block(inode, block, &tmp, 0);
 	return tmp.b_blocknr;
 }
Index: linux-2.6.16-rc3/fs/jfs/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/jfs/inode.c	2006-02-14 09:43:06.000000000 -0800
+++ linux-2.6.16-rc3/fs/jfs/inode.c	2006-02-14 09:43:51.000000000 -0800
@@ -257,7 +257,8 @@ jfs_get_blocks(struct inode *ip, sector_
 static int jfs_get_block(struct inode *ip, sector_t lblock,
 			 struct buffer_head *bh_result, int create)
 {
-	return jfs_get_blocks(ip, lblock, 1, bh_result, create);
+	return jfs_get_blocks(ip, lblock, bh_result->b_size >> ip->i_blkbits,
+			bh_result, create);
 }
 
 static int jfs_writepage(struct page *page, struct writeback_control *wbc)
Index: linux-2.6.16-rc3/fs/xfs/linux-2.6/xfs_aops.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/xfs/linux-2.6/xfs_aops.c	2006-02-14 09:43:06.000000000 -0800
+++ linux-2.6.16-rc3/fs/xfs/linux-2.6/xfs_aops.c	2006-02-14 09:43:33.000000000 -0800
@@ -1136,8 +1136,8 @@ linvfs_get_block(
 	struct buffer_head	*bh_result,
 	int			create)
 {
-	return __linvfs_get_block(inode, iblock, 0, bh_result,
-					create, 0, BMAPI_WRITE);
+	return __linvfs_get_block(inode, iblock, bh_result->b_size >> inode->i_blkbits,
+				bh_result, create, 0, BMAPI_WRITE);
 }
 
 STATIC int

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC][PATCH] map multiple blocks at a time in mpage_readpages()
  2006-02-14 17:49 [RFC][PATCH] map multiple blocks at a time in mpage_readpages() Badari Pulavarty
@ 2006-02-14 19:27 ` christoph
  2006-02-14 21:53   ` Badari Pulavarty
  2006-02-14 22:53   ` Badari Pulavarty
  2006-02-14 23:30 ` Daniel Phillips
  1 sibling, 2 replies; 6+ messages in thread
From: christoph @ 2006-02-14 19:27 UTC (permalink / raw)
  To: Badari Pulavarty; +Cc: christoph, akpm, mcao, linux-fsdevel, lkml

On Tue, Feb 14, 2006 at 09:49:07AM -0800, Badari Pulavarty wrote:
> Hi,
> 
> I re-did the support for mpage_readpages() to map multiple blocks
> at a time (basically, get_blocks()). Instead of adding new
> get_blocks() and pass it around, I use "bh->b_size" to indicate
> how much of disk mapping we are interested in to get_block().
> 
> This way no changes existing interfaces and no new routines need.
> Filesystem can choose to ignore the passed in "bh->b_size" value
> and map one block at a time (ext2, reiser3, etc..)

Hmm.  Given that we only use buffer_heads for page-cache backed I/O
bh->b_size should always be set properly and this would be fine.

If we could completely get rid of ->get_blocks that be a nice cleanup
in all the fs drivers.  OTOH I still wonder whether ->get_block should
use a small structure that just contains the information needed with
easy to decipher names..

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC][PATCH] map multiple blocks at a time in mpage_readpages()
  2006-02-14 19:27 ` christoph
@ 2006-02-14 21:53   ` Badari Pulavarty
  2006-02-14 22:53   ` Badari Pulavarty
  1 sibling, 0 replies; 6+ messages in thread
From: Badari Pulavarty @ 2006-02-14 21:53 UTC (permalink / raw)
  To: christoph; +Cc: akpm, mcao, linux-fsdevel, lkml

On Tue, 2006-02-14 at 20:27 +0100, christoph wrote:
> On Tue, Feb 14, 2006 at 09:49:07AM -0800, Badari Pulavarty wrote:
> > Hi,
> > 
> > I re-did the support for mpage_readpages() to map multiple blocks
> > at a time (basically, get_blocks()). Instead of adding new
> > get_blocks() and pass it around, I use "bh->b_size" to indicate
> > how much of disk mapping we are interested in to get_block().
> > 
> > This way no changes existing interfaces and no new routines need.
> > Filesystem can choose to ignore the passed in "bh->b_size" value
> > and map one block at a time (ext2, reiser3, etc..)
> 
> Hmm.  Given that we only use buffer_heads for page-cache backed I/O
> bh->b_size should always be set properly and this would be fine.
> 
> If we could completely get rid of ->get_blocks that be a nice cleanup
> in all the fs drivers. 

Yes. Sir !! 
As mentioned in my note, I am already doing that :)
Only problem is, it changes the existing exported interface :(

>  OTOH I still wonder whether ->get_block should
> use a small structure that just contains the information needed with
> easy to decipher names..

While ago, I did look at that. There is nothing much to trim in
the bufferhead. Most of this useful for FS, IO or JBD :(

Thanks,
Badari


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC][PATCH] map multiple blocks at a time in mpage_readpages()
  2006-02-14 19:27 ` christoph
  2006-02-14 21:53   ` Badari Pulavarty
@ 2006-02-14 22:53   ` Badari Pulavarty
  1 sibling, 0 replies; 6+ messages in thread
From: Badari Pulavarty @ 2006-02-14 22:53 UTC (permalink / raw)
  To: christoph; +Cc: akpm, mcao, linux-fsdevel, lkml

[-- Attachment #1: Type: text/plain, Size: 1078 bytes --]

On Tue, 2006-02-14 at 20:27 +0100, christoph wrote:
> On Tue, Feb 14, 2006 at 09:49:07AM -0800, Badari Pulavarty wrote:
> > Hi,
> > 
> > I re-did the support for mpage_readpages() to map multiple blocks
> > at a time (basically, get_blocks()). Instead of adding new
> > get_blocks() and pass it around, I use "bh->b_size" to indicate
> > how much of disk mapping we are interested in to get_block().
> > 
> > This way no changes existing interfaces and no new routines need.
> > Filesystem can choose to ignore the passed in "bh->b_size" value
> > and map one block at a time (ext2, reiser3, etc..)
> 
> Hmm.  Given that we only use buffer_heads for page-cache backed I/O
> bh->b_size should always be set properly and this would be fine.
> 
> If we could completely get rid of ->get_blocks that be a nice cleanup
> in all the fs drivers.  

Here is the patch to remove ->get_blocks from all fs.
Unfortunately, some filesystems (ext3, reiser3) does extra stuff
in ->getblocks() for DIO. So I can't quite get rid of them :(
But in general, it cleans up a lot.

Thanks,
Badari




[-- Attachment #2: remove-getblocks.patch --]
[-- Type: text/x-patch, Size: 15719 bytes --]

Index: linux-2.6.16-rc3/fs/direct-io.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/direct-io.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/direct-io.c	2006-02-14 14:32:11.000000000 -0800
@@ -86,12 +86,12 @@ struct dio {
 	unsigned first_block_in_page;	/* doesn't change, Used only once */
 	int boundary;			/* prev block is at a boundary */
 	int reap_counter;		/* rate limit reaping */
-	get_blocks_t *get_blocks;	/* block mapping function */
+	get_block_t *get_block;		/* block mapping function */
 	dio_iodone_t *end_io;		/* IO completion function */
 	sector_t final_block_in_bio;	/* current final block in bio + 1 */
 	sector_t next_block_for_io;	/* next block to be put under IO,
 					   in dio_blocks units */
-	struct buffer_head map_bh;	/* last get_blocks() result */
+	struct buffer_head map_bh;	/* last get_block() result */
 
 	/*
 	 * Deferred addition of a page to the dio.  These variables are
@@ -210,9 +210,9 @@ static struct page *dio_get_page(struct 
 
 /*
  * Called when all DIO BIO I/O has been completed - let the filesystem
- * know, if it registered an interest earlier via get_blocks.  Pass the
+ * know, if it registered an interest earlier via get_block.  Pass the
  * private field of the map buffer_head so that filesystems can use it
- * to hold additional state between get_blocks calls and dio_complete.
+ * to hold additional state between get_block calls and dio_complete.
  */
 static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes)
 {
@@ -488,7 +488,7 @@ static int dio_bio_reap(struct dio *dio)
  * The fs is allowed to map lots of blocks at once.  If it wants to do that,
  * it uses the passed inode-relative block number as the file offset, as usual.
  *
- * get_blocks() is passed the number of i_blkbits-sized blocks which direct_io
+ * get_block() is passed the number of i_blkbits-sized blocks which direct_io
  * has remaining to do.  The fs should not map more than this number of blocks.
  *
  * If the fs has mapped a lot of blocks, it should populate bh->b_size to
@@ -501,7 +501,7 @@ static int dio_bio_reap(struct dio *dio)
  * In the case of filesystem holes: the fs may return an arbitrarily-large
  * hole by returning an appropriate value in b_size and by clearing
  * buffer_mapped().  However the direct-io code will only process holes one
- * block at a time - it will repeatedly call get_blocks() as it walks the hole.
+ * block at a time - it will repeatedly call get_block() as it walks the hole.
  */
 static int get_more_blocks(struct dio *dio)
 {
@@ -543,7 +543,8 @@ static int get_more_blocks(struct dio *d
 		 * at a higher level for inside-i_size block-instantiating
 		 * writes.
 		 */
-		ret = (*dio->get_blocks)(dio->inode, fs_startblk, fs_count,
+		map_bh->b_size = fs_count << dio->blkbits;
+		ret = (*dio->get_block)(dio->inode, fs_startblk,
 						map_bh, create);
 	}
 	return ret;
@@ -778,11 +779,11 @@ static void dio_zero_block(struct dio *d
  * happily perform page-sized but 512-byte aligned IOs.  It is important that
  * blockdev IO be able to have fine alignment and large sizes.
  *
- * So what we do is to permit the ->get_blocks function to populate bh.b_size
+ * So what we do is to permit the ->get_block function to populate bh.b_size
  * with the size of IO which is permitted at this offset and this i_blkbits.
  *
  * For best results, the blockdev should be set up with 512-byte i_blkbits and
- * it should set b_size to PAGE_SIZE or more inside get_blocks().  This gives
+ * it should set b_size to PAGE_SIZE or more inside get_block().  This gives
  * fine alignment but still allows this function to work in PAGE_SIZE units.
  */
 static int do_direct_IO(struct dio *dio)
@@ -942,7 +943,7 @@ out:
 static ssize_t
 direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, 
 	const struct iovec *iov, loff_t offset, unsigned long nr_segs, 
-	unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io,
+	unsigned blkbits, get_block_t get_block, dio_iodone_t end_io,
 	struct dio *dio)
 {
 	unsigned long user_addr; 
@@ -964,7 +965,7 @@ direct_io_worker(int rw, struct kiocb *i
 
 	dio->boundary = 0;
 	dio->reap_counter = 0;
-	dio->get_blocks = get_blocks;
+	dio->get_block = get_block;
 	dio->end_io = end_io;
 	dio->map_bh.b_private = NULL;
 	dio->final_block_in_bio = -1;
@@ -1170,7 +1171,7 @@ direct_io_worker(int rw, struct kiocb *i
 ssize_t
 __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 	struct block_device *bdev, const struct iovec *iov, loff_t offset, 
-	unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
+	unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
 	int dio_lock_type)
 {
 	int seg;
@@ -1266,7 +1267,7 @@ __blockdev_direct_IO(int rw, struct kioc
 		(end > i_size_read(inode)));
 
 	retval = direct_io_worker(rw, iocb, inode, iov, offset,
-				nr_segs, blkbits, get_blocks, end_io, dio);
+				nr_segs, blkbits, get_block, end_io, dio);
 
 	if (rw == READ && dio_lock_type == DIO_LOCKING)
 		reader_with_isem = 0;
Index: linux-2.6.16-rc3/fs/ext2/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/ext2/inode.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/ext2/inode.c	2006-02-14 14:17:03.000000000 -0800
@@ -667,18 +667,6 @@ static sector_t ext2_bmap(struct address
 	return generic_block_bmap(mapping,block,ext2_get_block);
 }
 
-static int
-ext2_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
-			struct buffer_head *bh_result, int create)
-{
-	int ret;
-
-	ret = ext2_get_block(inode, iblock, bh_result, create);
-	if (ret == 0)
-		bh_result->b_size = (1 << inode->i_blkbits);
-	return ret;
-}
-
 static ssize_t
 ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
 			loff_t offset, unsigned long nr_segs)
@@ -687,7 +675,7 @@ ext2_direct_IO(int rw, struct kiocb *ioc
 	struct inode *inode = file->f_mapping->host;
 
 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-				offset, nr_segs, ext2_get_blocks, NULL);
+				offset, nr_segs, ext2_get_block, NULL);
 }
 
 static int
Index: linux-2.6.16-rc3/fs/ext3/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/ext3/inode.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/ext3/inode.c	2006-02-14 14:17:49.000000000 -0800
@@ -806,8 +806,7 @@ static int ext3_get_block(struct inode *
 
 static int
 ext3_direct_io_get_blocks(struct inode *inode, sector_t iblock,
-		unsigned long max_blocks, struct buffer_head *bh_result,
-		int create)
+		struct buffer_head *bh_result, int create)
 {
 	handle_t *handle = journal_current_handle();
 	int ret = 0;
Index: linux-2.6.16-rc3/fs/fat/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/fat/inode.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/fat/inode.c	2006-02-14 14:21:21.000000000 -0800
@@ -101,11 +101,11 @@ static int __fat_get_blocks(struct inode
 }
 
 static int fat_get_blocks(struct inode *inode, sector_t iblock,
-			  unsigned long max_blocks,
 			  struct buffer_head *bh_result, int create)
 {
 	struct super_block *sb = inode->i_sb;
 	int err;
+	unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
 
 	err = __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
 	if (err)
Index: linux-2.6.16-rc3/fs/hfs/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/hfs/inode.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/hfs/inode.c	2006-02-14 14:24:06.000000000 -0800
@@ -98,17 +98,6 @@ static int hfs_releasepage(struct page *
 	return res ? try_to_free_buffers(page) : 0;
 }
 
-static int hfs_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
-			  struct buffer_head *bh_result, int create)
-{
-	int ret;
-
-	ret = hfs_get_block(inode, iblock, bh_result, create);
-	if (!ret)
-		bh_result->b_size = (1 << inode->i_blkbits);
-	return ret;
-}
-
 static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
 		const struct iovec *iov, loff_t offset, unsigned long nr_segs)
 {
@@ -116,7 +105,7 @@ static ssize_t hfs_direct_IO(int rw, str
 	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
 
 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-				  offset, nr_segs, hfs_get_blocks, NULL);
+				  offset, nr_segs, hfs_get_block, NULL);
 }
 
 static int hfs_writepages(struct address_space *mapping,
Index: linux-2.6.16-rc3/fs/hfsplus/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/hfsplus/inode.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/hfsplus/inode.c	2006-02-14 14:13:42.000000000 -0800
@@ -93,17 +93,6 @@ static int hfsplus_releasepage(struct pa
 	return res ? try_to_free_buffers(page) : 0;
 }
 
-static int hfsplus_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
-			      struct buffer_head *bh_result, int create)
-{
-	int ret;
-
-	ret = hfsplus_get_block(inode, iblock, bh_result, create);
-	if (!ret)
-		bh_result->b_size = (1 << inode->i_blkbits);
-	return ret;
-}
-
 static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
 		const struct iovec *iov, loff_t offset, unsigned long nr_segs)
 {
@@ -111,7 +100,7 @@ static ssize_t hfsplus_direct_IO(int rw,
 	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
 
 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-				  offset, nr_segs, hfsplus_get_blocks, NULL);
+				  offset, nr_segs, hfsplus_get_block, NULL);
 }
 
 static int hfsplus_writepages(struct address_space *mapping,
Index: linux-2.6.16-rc3/fs/ocfs2/aops.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/ocfs2/aops.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/ocfs2/aops.c	2006-02-14 14:26:45.000000000 -0800
@@ -538,7 +538,6 @@ bail:
  * 					fs_count, map_bh, dio->rw == WRITE);
  */
 static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
-				     unsigned long max_blocks,
 				     struct buffer_head *bh_result, int create)
 {
 	int ret;
@@ -546,6 +545,7 @@ static int ocfs2_direct_IO_get_blocks(st
 	u64 p_blkno;
 	int contig_blocks;
 	unsigned char blocksize_bits;
+	unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
 
 	if (!inode || !bh_result) {
 		mlog(ML_ERROR, "inode or bh_result is null\n");
Index: linux-2.6.16-rc3/fs/reiserfs/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/reiserfs/inode.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/reiserfs/inode.c	2006-02-14 14:16:17.000000000 -0800
@@ -466,7 +466,6 @@ static int reiserfs_get_block_create_0(s
    direct_IO request. */
 static int reiserfs_get_blocks_direct_io(struct inode *inode,
 					 sector_t iblock,
-					 unsigned long max_blocks,
 					 struct buffer_head *bh_result,
 					 int create)
 {
Index: linux-2.6.16-rc3/fs/xfs/linux-2.6/xfs_aops.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/xfs/linux-2.6/xfs_aops.c	2006-02-14 09:43:33.000000000 -0800
+++ linux-2.6.16-rc3/fs/xfs/linux-2.6/xfs_aops.c	2006-02-14 14:31:01.000000000 -0800
@@ -1144,12 +1144,11 @@ STATIC int
 linvfs_get_blocks_direct(
 	struct inode		*inode,
 	sector_t		iblock,
-	unsigned long		max_blocks,
 	struct buffer_head	*bh_result,
 	int			create)
 {
-	return __linvfs_get_block(inode, iblock, max_blocks, bh_result,
-					create, 1, BMAPI_WRITE|BMAPI_DIRECT);
+	return __linvfs_get_block(inode, iblock, bh_result->b_size >> inode->i_blkbits,
+				bh_result, create, 1, BMAPI_WRITE|BMAPI_DIRECT);
 }
 
 STATIC void
Index: linux-2.6.16-rc3/include/linux/fs.h
===================================================================
--- linux-2.6.16-rc3.orig/include/linux/fs.h	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/include/linux/fs.h	2006-02-14 14:11:54.000000000 -0800
@@ -240,9 +240,6 @@ extern void __init files_init(unsigned l
 struct buffer_head;
 typedef int (get_block_t)(struct inode *inode, sector_t iblock,
 			struct buffer_head *bh_result, int create);
-typedef int (get_blocks_t)(struct inode *inode, sector_t iblock,
-			unsigned long max_blocks,
-			struct buffer_head *bh_result, int create);
 typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 			ssize_t bytes, void *private);
 
@@ -1621,7 +1618,7 @@ static inline void do_generic_file_read(
 
 ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 	struct block_device *bdev, const struct iovec *iov, loff_t offset,
-	unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
+	unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
 	int lock_type);
 
 enum {
@@ -1632,29 +1629,29 @@ enum {
 
 static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
 	struct inode *inode, struct block_device *bdev, const struct iovec *iov,
-	loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
+	loff_t offset, unsigned long nr_segs, get_block_t get_block,
 	dio_iodone_t end_io)
 {
 	return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
-				nr_segs, get_blocks, end_io, DIO_LOCKING);
+				nr_segs, get_block, end_io, DIO_LOCKING);
 }
 
 static inline ssize_t blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
 	struct inode *inode, struct block_device *bdev, const struct iovec *iov,
-	loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
+	loff_t offset, unsigned long nr_segs, get_block_t get_block,
 	dio_iodone_t end_io)
 {
 	return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
-				nr_segs, get_blocks, end_io, DIO_NO_LOCKING);
+				nr_segs, get_block, end_io, DIO_NO_LOCKING);
 }
 
 static inline ssize_t blockdev_direct_IO_own_locking(int rw, struct kiocb *iocb,
 	struct inode *inode, struct block_device *bdev, const struct iovec *iov,
-	loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
+	loff_t offset, unsigned long nr_segs, get_block_t get_block,
 	dio_iodone_t end_io)
 {
 	return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
-				nr_segs, get_blocks, end_io, DIO_OWN_LOCKING);
+				nr_segs, get_block, end_io, DIO_OWN_LOCKING);
 }
 
 extern struct file_operations generic_ro_fops;
Index: linux-2.6.16-rc3/fs/block_dev.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/block_dev.c	2006-02-12 16:27:25.000000000 -0800
+++ linux-2.6.16-rc3/fs/block_dev.c	2006-02-14 14:35:01.000000000 -0800
@@ -135,9 +135,10 @@ blkdev_get_block(struct inode *inode, se
 
 static int
 blkdev_get_blocks(struct inode *inode, sector_t iblock,
-		unsigned long max_blocks, struct buffer_head *bh, int create)
+		struct buffer_head *bh, int create)
 {
 	sector_t end_block = max_block(I_BDEV(inode));
+	unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
 
 	if ((iblock + max_blocks) > end_block) {
 		max_blocks = end_block - iblock;
Index: linux-2.6.16-rc3/fs/jfs/inode.c
===================================================================
--- linux-2.6.16-rc3.orig/fs/jfs/inode.c	2006-02-14 09:43:51.000000000 -0800
+++ linux-2.6.16-rc3/fs/jfs/inode.c	2006-02-14 14:37:28.000000000 -0800
@@ -301,7 +301,7 @@ static ssize_t jfs_direct_IO(int rw, str
 	struct inode *inode = file->f_mapping->host;
 
 	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-				offset, nr_segs, jfs_get_blocks, NULL);
+				offset, nr_segs, jfs_get_block, NULL);
 }
 
 struct address_space_operations jfs_aops = {

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC][PATCH] map multiple blocks at a time in mpage_readpages()
  2006-02-14 17:49 [RFC][PATCH] map multiple blocks at a time in mpage_readpages() Badari Pulavarty
  2006-02-14 19:27 ` christoph
@ 2006-02-14 23:30 ` Daniel Phillips
  2006-02-14 23:49   ` Badari Pulavarty
  1 sibling, 1 reply; 6+ messages in thread
From: Daniel Phillips @ 2006-02-14 23:30 UTC (permalink / raw)
  To: Badari Pulavarty; +Cc: christoph, akpm, mcao, linux-fsdevel, lkml

Badari Pulavarty wrote:
> +		for (i = 0; ; i++) {
> +			if (i == nblocks) {
> +				*map_valid = 0;
> +				break;
> +			} else if (page_block == blocks_per_page)
> +				break;
> +			blocks[page_block] = map_bh->b_blocknr + i;
> +			page_block++;
> +			block_in_file++;
> +		}

Hi Badari, a tiny nit:

		for (i = 0; ; i++) {
			if (i == nblocks) {
				*map_valid = 0;
				break;
			}
			if (page_block == blocks_per_page)
				break;
			blocks[page_block] = map_bh->b_blocknr + i;
			page_block++;
			block_in_file++;
		}

Regards,

Daniel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC][PATCH] map multiple blocks at a time in mpage_readpages()
  2006-02-14 23:30 ` Daniel Phillips
@ 2006-02-14 23:49   ` Badari Pulavarty
  0 siblings, 0 replies; 6+ messages in thread
From: Badari Pulavarty @ 2006-02-14 23:49 UTC (permalink / raw)
  To: Daniel Phillips; +Cc: christoph, akpm, mcao, linux-fsdevel, lkml

On Tue, 2006-02-14 at 15:30 -0800, Daniel Phillips wrote:
> Badari Pulavarty wrote:
> > +		for (i = 0; ; i++) {
> > +			if (i == nblocks) {
> > +				*map_valid = 0;
> > +				break;
> > +			} else if (page_block == blocks_per_page)
> > +				break;
> > +			blocks[page_block] = map_bh->b_blocknr + i;
> > +			page_block++;
> > +			block_in_file++;
> > +		}
> 
> Hi Badari, a tiny nit:
> 
> 		for (i = 0; ; i++) {
> 			if (i == nblocks) {
> 				*map_valid = 0;
> 				break;
> 			}
> 			if (page_block == blocks_per_page)
> 				break;
> 			blocks[page_block] = map_bh->b_blocknr + i;
> 			page_block++;
> 			block_in_file++;
> 		}
> 


Fixed. Wow !! People really do read others patches. Just kidding :)

Thanks,
Badari


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-02-14 23:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-02-14 17:49 [RFC][PATCH] map multiple blocks at a time in mpage_readpages() Badari Pulavarty
2006-02-14 19:27 ` christoph
2006-02-14 21:53   ` Badari Pulavarty
2006-02-14 22:53   ` Badari Pulavarty
2006-02-14 23:30 ` Daniel Phillips
2006-02-14 23:49   ` Badari Pulavarty

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.