| From aca92ff6f57c000d1b4523e383c8bd6b8269b8b1 Mon Sep 17 00:00:00 2001 |
| From: Leonard Michlmayr <leonard.michlmayr@gmail.com> |
| Date: Thu, 4 Mar 2010 17:07:28 -0500 |
| Subject: ext4: correctly calculate number of blocks for fiemap |
| |
| From: Leonard Michlmayr <leonard.michlmayr@gmail.com> |
| |
| commit aca92ff6f57c000d1b4523e383c8bd6b8269b8b1 upstream. |
| |
| ext4_fiemap() rounds the length of the requested range down to |
| blocksize, which is is not the true number of blocks that cover the |
| requested region. This problem is especially impressive if the user |
| requests only the first byte of a file: not a single extent will be |
| reported. |
| |
| We fix this by calculating the last block of the region and then |
| subtract to find the number of blocks in the extents. |
| |
| Signed-off-by: Leonard Michlmayr <leonard.michlmayr@gmail.com> |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| fs/ext4/extents.c | 9 +++++++-- |
| 1 file changed, 7 insertions(+), 2 deletions(-) |
| |
| --- a/fs/ext4/extents.c |
| +++ b/fs/ext4/extents.c |
| @@ -3767,7 +3767,6 @@ int ext4_fiemap(struct inode *inode, str |
| __u64 start, __u64 len) |
| { |
| ext4_lblk_t start_blk; |
| - ext4_lblk_t len_blks; |
| int error = 0; |
| |
| /* fallback to generic here if not in extents fmt */ |
| @@ -3781,8 +3780,14 @@ int ext4_fiemap(struct inode *inode, str |
| if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) { |
| error = ext4_xattr_fiemap(inode, fieinfo); |
| } else { |
| + ext4_lblk_t len_blks; |
| + __u64 last_blk; |
| + |
| start_blk = start >> inode->i_sb->s_blocksize_bits; |
| - len_blks = len >> inode->i_sb->s_blocksize_bits; |
| + last_blk = (start + len - 1) >> inode->i_sb->s_blocksize_bits; |
| + if (last_blk >= EXT_MAX_BLOCK) |
| + last_blk = EXT_MAX_BLOCK-1; |
| + len_blks = ((ext4_lblk_t) last_blk) - start_blk + 1; |
| |
| /* |
| * Walk the extent tree gathering extent information. |