diff mbox

[6/6] Btrfs: fix wrong extent mapping for DirectIO

Message ID 1405568654-22120-6-git-send-email-wangsl.fnst@cn.fujitsu.com (mailing list archive)
State Accepted
Headers show

Commit Message

Wang Shilong July 17, 2014, 3:44 a.m. UTC
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>
---
 fs/btrfs/inode.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

David Sterba July 24, 2014, 11:45 a.m. UTC | #1
On Thu, Jul 17, 2014 at 11:44:14AM +0800, Wang Shilong wrote:
> 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.

So this cannot happen normally (because compression and DIO do not work
together)?

> 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>
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index ed8b55c..d1ba5e4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6308,6 +6308,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;