fs: round len up before get mapping
Subsystems (2)
PATCH 2/3 fs: round len up before get mapping
When len is less than one block, it will be extended to one block. If start + len exceeds the boundary of the original block because of the extension, one needless block will be returned.
And this patch only tries to map blocks within range instead of mapping as many contiguous blocks as possible at once. That's because comparing to extent-based files, find mapping for indirect-based files could be time-consuming, especially after we found the last extent we need, we don't care how long the next extent, and should return right after find a mapped block or EOF.
--- fs/ioctl.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
fs/ioctl.c +9 -11
@@ -276,23 +276,21 @@ int __generic_block_fiemap(struct inode *inode, len = isize - start; } -/* -* Some filesystems can't deal with being asked to map less than -* blocksize, so make sure our len is at least block length. -*/ -if (logical_to_blk (inode, len) ==0 ) - len =blk_to_logical (inode,1 ); - start_blk =logical_to_blk (inode, start); last_blk =logical_to_blk (inode, start + len -1 ); do { + memset(&map_bh, 0, sizeof(struct buffer_head)); /* - * we set b_size to the total size we want so it will map as - * many contiguous blocks as possible at once + * Some filesystems would round down b_size to align + * with block size, if len isn't aligned already, the last + * block may not be returned. Let's round it up first. */ - memset(&map_bh, 0, sizeof(struct buffer_head)); - map_bh.b_size = len; + if (last_blk > start_blk) + map_bh.b_size = blk_to_logical(inode, + last_blk - start_blk + 1); + else + map_bh.b_size = blk_to_logical(inode, 1); ret = get_block(inode, start_blk, &map_bh, 0); if (ret)
Signature · 1 line
1.7.9.5
Re: [PATCH 2/3] round len up before get mapping
Quoted 16 lines · Fan Li
When len is less than one block, it will be extended to one block. If start + len exceeds the boundary of the original block because of the extension, one needless block will be returned.
And this patch only tries to map blocks within range instead of mapping as many contiguous blocks as possible at once. That's because comparing to extent-based files, find mapping for indirect-based files could be time-consuming, especially after we found the last extent we need, we don't care how long the next extent, and should return right after find a mapped block or EOF.
Quoted 1 line
Signed-off-by Fan Li <[email protected]>
Quoted 44 lines
---
fs/ioctl.c| 20 +++++++++-----------1 file changed, 9 insertions(+), 11 deletions(-)fs/ioctl.c +9
-12@@ -276,23 +276,21 @@ int __generic_block_fiemap(struct inode *inode, len = isize - start; } -/* -* Some filesystems can't deal with being asked to map less than -* blocksize, so make sure our len is at least block length. -*/ -if (logical_to_blk (inode, len) ==0 ) - len =blk_to_logical (inode,1 ); - start_blk =logical_to_blk (inode, start); last_blk =logical_to_blk (inode, start + len -1 ); do { + memset(&map_bh, 0, sizeof(struct buffer_head)); /* - * we set b_size to the total size we want so it will map as - * many contiguous blocks as possible at once + * Some filesystems would round down b_size to align + * with block size, if len isn't aligned already, the last + * block may not be returned. Let's round it up first. */ - memset(&map_bh, 0, sizeof(struct buffer_head)); - map_bh.b_size = len; + if (last_blk > start_blk) + map_bh.b_size = blk_to_logical(inode, + last_blk - start_blk + 1); + else + map_bh.b_size = blk_to_logical(inode, 1); ret = get_block(inode, start_blk, &map_bh, 0); if (ret) --1.7.9.5
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers, Andreas