Skip to contentSkip to conversation

ext4: fix for fiemap last-block test

PATCH In review Eric Sandeen 2 participants 3 messages Apr 28, 2009 – May 2, 2009 ext4 file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ext4: fix for fiemap last-block test

Carl Henrik Lunde reported and debugged this; the test for the last allocated block was comparing bytes to blocks in this test:

	if (logical + length - 1 == EXT_MAX_BLOCK ||
	    ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK)
		flags |= FIEMAP_EXTENT_LAST;

so any extent which ended right at 4G was stopping the extent walk. Just replacing these values with the extent block & length should fix it.

Also give blksize_bits a saner type, and reverse the order of the tests to make the more likely case tested first.

---

fs/ext4/extents.c +3 -3
Index: linux-2.6.29.x86_64/fs/ext4/extents.c
===================================================================
@@ -3087,7 +3087,7 @@ static int ext4_ext_fiemap_cb(struct ino
 		       void *data)
 {
 	struct fiemap_extent_info *fieinfo = data;
-	unsigned long blksize_bits = inode->i_sb->s_blocksize_bits;
+	unsigned char blksize_bits = inode->i_sb->s_blocksize_bits;
 	__u64	logical;
 	__u64	physical;
 	__u64	length;
@@ -3134,8 +3134,8 @@ static int ext4_ext_fiemap_cb(struct ino
 	 *
 	 * XXX this might miss a single-block extent at EXT_MAX_BLOCK
 	 */
-	if (logical + length - 1 == EXT_MAX_BLOCK ||
-	    ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK)
+	if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK ||
+	    newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK)
 		flags |= FIEMAP_EXTENT_LAST;
 
 	error = fiemap_fill_next_extent(fieinfo, logical, physical,
maintainer
#1 lore raw

Thanks, I've pulled this into the ext4 patch queue. While I was testing this, I found an additional bug in ext4's fiemap handling. I'll post that fix as a reply to this message.

- Ted

maintainer
#2 lore raw

PATCH 1/1 ext4: fix the length returned by fiemap for an unallocated extent

If the file's blocks have not yet been allocated because of delayed allocation, the length of the extent returned by fiemap is incorrect. This commit fixes this bug.

---
 fs/ext4/extents.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
fs/ext4/extents.c +8 -1
index 86c64ea..e963870 100644
@@ -3234,8 +3234,15 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
 	 * XXX this might miss a single-block extent at EXT_MAX_BLOCK
 	 */
 	if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK ||
-	    newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK)
+	    newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK) {
+		loff_t size = i_size_read(inode);
+		loff_t bs = EXT4_BLOCK_SIZE(inode->i_sb);
+
 		flags |= FIEMAP_EXTENT_LAST;
+		if ((flags & FIEMAP_EXTENT_DELALLOC) &&
+		    logical+length > size)
+			length = (size - logical + bs - 1) & ~(bs-1);
+	}
 
 	error = fiemap_fill_next_extent(fieinfo, logical, physical,
 					length, flags);
Signature · 1 line
1.6.0.4