* [PATCH] ext3 getblocks() support for read
@ 2005-11-30 16:26 Badari Pulavarty
2005-12-02 0:59 ` Mingming Cao
0 siblings, 1 reply; 3+ messages in thread
From: Badari Pulavarty @ 2005-11-30 16:26 UTC (permalink / raw)
To: ext2-devel, lkml; +Cc: akpm, sct, hch, cmm
[-- Attachment #1: Type: text/plain, Size: 360 bytes --]
Hi,
Here is the patch to support ext3 getblocks() for non allocation
cases. (for reads & re-writes). This is useful with DIO reads,
DIO re-writes and to go with Christoph's getblocks() for readpages()
work.
Mingming is working on adding multiblock allocation support using
reservation (which can be incrementally added later).
Comments ?
Thanks,
Badari
[-- Attachment #2: ext3-noalloc-get-blocks.patch --]
[-- Type: text/x-patch, Size: 3106 bytes --]
Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
--- linux-2.6.15-rc2/fs/ext3/inode.c 2005-11-19 19:25:03.000000000 -0800
+++ linux-2.6.15-rc2.new/fs/ext3/inode.c 2005-11-30 08:16:36.000000000 -0800
@@ -329,8 +329,9 @@ static int ext3_block_to_path(struct ino
} else {
ext3_warning (inode->i_sb, "ext3_block_to_path", "block > big");
}
- if (boundary)
- *boundary = (i_block & (ptrs - 1)) == (final - 1);
+ if (boundary) {
+ *boundary = final - 1 - (i_block & (ptrs - 1));
+ }
return n;
}
@@ -672,8 +673,9 @@ err_out:
*/
static int
-ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
- struct buffer_head *bh_result, int create, int extend_disksize)
+ext3_get_blocks_handle(handle_t *handle, struct inode *inode, sector_t iblock,
+ int max_blocks,struct buffer_head *bh_result, int create,
+ int extend_disksize)
{
int err = -EIO;
int offsets[4];
@@ -681,9 +683,10 @@ ext3_get_block_handle(handle_t *handle,
Indirect *partial;
unsigned long goal;
int left;
- int boundary = 0;
- const int depth = ext3_block_to_path(inode, iblock, offsets, &boundary);
+ int blks_boundary = 0;
+ const int depth = ext3_block_to_path(inode, iblock, offsets, &blks_boundary);
struct ext3_inode_info *ei = EXT3_I(inode);
+ int count = 1;
J_ASSERT(handle != NULL || create == 0);
@@ -694,7 +697,18 @@ ext3_get_block_handle(handle_t *handle,
/* Simplest case - block found, no allocation needed */
if (!partial) {
+ unsigned long first_block = le32_to_cpu(chain[depth-1].key);
+
clear_buffer_new(bh_result);
+
+ /*
+ * Find all the contiguous blocks and return at once.
+ */
+ while (count < max_blocks && count <= blks_boundary &&
+ (le32_to_cpu(*(chain[depth-1].p+count)) ==
+ (first_block + count))) {
+ count++;
+ }
goto got_it;
}
@@ -772,8 +786,9 @@ ext3_get_block_handle(handle_t *handle,
set_buffer_new(bh_result);
got_it:
map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
- if (boundary)
+ if (blks_boundary == 0)
set_buffer_boundary(bh_result);
+ err = count;
/* Clean up and exit */
partial = chain + depth - 1; /* the whole chain */
cleanup:
@@ -787,6 +802,19 @@ out:
return err;
}
+static int
+ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
+ struct buffer_head *bh_result, int create, int extend_disksize)
+{
+ int ret;
+ ret = ext3_get_blocks_handle(handle, inode, iblock, 1, bh_result,
+ create, extend_disksize);
+ if (ret > 0)
+ ret = 0;
+
+ return ret;
+}
+
static int ext3_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
@@ -842,9 +870,13 @@ ext3_direct_io_get_blocks(struct inode *
get_block:
if (ret == 0)
- ret = ext3_get_block_handle(handle, inode, iblock,
- bh_result, create, 0);
- bh_result->b_size = (1 << inode->i_blkbits);
+ ret = ext3_get_blocks_handle(handle, inode, iblock,
+ max_blocks, bh_result, create, 0);
+
+ if (ret > 0)
+ bh_result->b_size = (ret << inode->i_blkbits);
+ else
+ bh_result->b_size = (1 << inode->i_blkbits);
return ret;
}
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] ext3 getblocks() support for read
2005-11-30 16:26 [PATCH] ext3 getblocks() support for read Badari Pulavarty
@ 2005-12-02 0:59 ` Mingming Cao
2005-12-02 1:09 ` Badari Pulavarty
0 siblings, 1 reply; 3+ messages in thread
From: Mingming Cao @ 2005-12-02 0:59 UTC (permalink / raw)
To: Badari Pulavarty; +Cc: ext2-devel, lkml, akpm, sct, hch
Badari Pulavarty wrote:
> Hi,
>
> Here is the patch to support ext3 getblocks() for non allocation
> cases. (for reads & re-writes). This is useful with DIO reads,
> DIO re-writes and to go with Christoph's getblocks() for readpages()
> work.
>
> Mingming is working on adding multiblock allocation support using
> reservation (which can be incrementally added later).
>
> Comments ?
>
My ext3 multiple block allocation patch posted a while ago
includes the multiple blocks map as well. Looks mostly the same way you
did here, but I like the way that how the # of mapped(or allocated)
blocks are returned.
My plan is to break the whole ext3 multiple block allocation(also does
map) patch into small patches, and re-send soon.
> @@ -681,9 +683,10 @@ ext3_get_block_handle(handle_t *handle,
> Indirect *partial;
> unsigned long goal;
> int left;
> - int boundary = 0;
> - const int depth = ext3_block_to_path(inode, iblock, offsets, &boundary);
> + int blks_boundary = 0;
> + const int depth = ext3_block_to_path(inode, iblock, offsets, &blks_boundary);
> struct ext3_inode_info *ei = EXT3_I(inode);
> + int count = 1;
>
> J_ASSERT(handle != NULL || create == 0);
>
> @@ -694,7 +697,18 @@ ext3_get_block_handle(handle_t *handle,
>
> /* Simplest case - block found, no allocation needed */
> if (!partial) {
> + unsigned long first_block = le32_to_cpu(chain[depth-1].key);
> +
> clear_buffer_new(bh_result);
> +
> + /*
> + * Find all the contiguous blocks and return at once.
> + */
> + while (count < max_blocks && count <= blks_boundary &&
> + (le32_to_cpu(*(chain[depth-1].p+count)) ==
> + (first_block + count))) {
> + count++;
> + }
> goto got_it;
> }
>
Here we need to be careful about the branch we just read, since we are
looking up multiple blocks (they are on the same branch) at the same
time, it is possible that during the look up, another threads is
trucating the same branch we are trying to map. Before since we are
doing only one look up, a simple verify_chain() should be safe.
The simple way is, for the non-allocation case, take the truncate_sem
before the ext3_get_branch, like for the allocation-case, even for the
simple case -- but that probably will slow down the non-allocation,
probably a bad option. But we could re-check(calling
verify_chain())inside the while loop.
Mingming
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] ext3 getblocks() support for read
2005-12-02 0:59 ` Mingming Cao
@ 2005-12-02 1:09 ` Badari Pulavarty
0 siblings, 0 replies; 3+ messages in thread
From: Badari Pulavarty @ 2005-12-02 1:09 UTC (permalink / raw)
To: Mingming Cao; +Cc: ext2-devel, lkml, akpm, sct, hch
On Thu, 2005-12-01 at 16:59 -0800, Mingming Cao wrote:
> Badari Pulavarty wrote:
> > Hi,
> >
> > Here is the patch to support ext3 getblocks() for non allocation
> > cases. (for reads & re-writes). This is useful with DIO reads,
> > DIO re-writes and to go with Christoph's getblocks() for readpages()
> > work.
> >
> > Mingming is working on adding multiblock allocation support using
> > reservation (which can be incrementally added later).
> >
> > Comments ?
> >
>
> My ext3 multiple block allocation patch posted a while ago
> includes the multiple blocks map as well. Looks mostly the same way you
> did here, but I like the way that how the # of mapped(or allocated)
> blocks are returned.
>
> My plan is to break the whole ext3 multiple block allocation(also does
> map) patch into small patches, and re-send soon.
Cool. Can you handle this one too then ?
>
> > @@ -681,9 +683,10 @@ ext3_get_block_handle(handle_t *handle,
> > Indirect *partial;
> > unsigned long goal;
> > int left;
> > - int boundary = 0;
> > - const int depth = ext3_block_to_path(inode, iblock, offsets, &boundary);
> > + int blks_boundary = 0;
> > + const int depth = ext3_block_to_path(inode, iblock, offsets, &blks_boundary);
> > struct ext3_inode_info *ei = EXT3_I(inode);
> > + int count = 1;
> >
> > J_ASSERT(handle != NULL || create == 0);
> >
> > @@ -694,7 +697,18 @@ ext3_get_block_handle(handle_t *handle,
> >
> > /* Simplest case - block found, no allocation needed */
> > if (!partial) {
> > + unsigned long first_block = le32_to_cpu(chain[depth-1].key);
> > +
> > clear_buffer_new(bh_result);
> > +
> > + /*
> > + * Find all the contiguous blocks and return at once.
> > + */
> > + while (count < max_blocks && count <= blks_boundary &&
> > + (le32_to_cpu(*(chain[depth-1].p+count)) ==
> > + (first_block + count))) {
> > + count++;
> > + }
> > goto got_it;
> > }
> >
> Here we need to be careful about the branch we just read, since we are
> looking up multiple blocks (they are on the same branch) at the same
> time, it is possible that during the look up, another threads is
> trucating the same branch we are trying to map. Before since we are
> doing only one look up, a simple verify_chain() should be safe.
>
> The simple way is, for the non-allocation case, take the truncate_sem
> before the ext3_get_branch, like for the allocation-case, even for the
> simple case -- but that probably will slow down the non-allocation,
> probably a bad option. But we could re-check(calling
> verify_chain())inside the while loop.
I don't think we can slowdown non-allocation read case, may be re-check
is a better idea ?
Thanks,
Badari
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-12-02 1:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-30 16:26 [PATCH] ext3 getblocks() support for read Badari Pulavarty
2005-12-02 0:59 ` Mingming Cao
2005-12-02 1:09 ` 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.