Btrfs: fix wrong extent mapping for DirectIO
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>
Thu, 17 Jul 2014 03:44:14 +0000 (11:44 +0800)
committerChris Mason <clm@fb.com>
Tue, 19 Aug 2014 15:52:13 +0000 (08:52 -0700)
btrfs_next_leaf() will use current leaf's last key to search
and then return a bigger one. So it may still return a file extent
item that is smaller than expected value and we will
get an overflow here for @em->len.

This is easy to reproduce for Btrfs Direct writting, it did not
cause any problem, because writting will re-insert right mapping later.

However, by hacking code to make DIO support compression, wrong extent
mapping is kept and it encounter merging failure(EEXIST) quickly.

Fix this problem by looping to find next file extent item that is bigger
than @start or we could not find anything more.

Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
Reviewed-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/inode.c

index 73fadc7ead0e4bf1805a8cfdd6a88a31f2499373..a3c6e76f5a4eab9a7a0deeed4f182bbff2e0ae05 100644 (file)
@@ -6275,6 +6275,8 @@ next:
                        goto not_found;
                if (start + len <= found_key.offset)
                        goto not_found;
+               if (start > found_key.offset)
+                       goto next;
                em->start = start;
                em->orig_start = start;
                em->len = found_key.offset - start;