From 48753c414169f92c3d7bce02cd7c10dbb52c75b5 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 8 Mar 2011 11:54:40 -0500 Subject: [PATCH] --- yaml --- r: 234091 b: refs/heads/master c: ea8efc74bd0402b4d5f663d007b4e25fa29ea778 h: refs/heads/master i: 234089: 6d6663bbc5f6c6d8eb49eea27e2bb8af418920ab 234087: b28f6fc8f9d955e8a97f4746e6b31f37905bff01 v: v3 --- [refs] | 2 +- trunk/fs/btrfs/extent_io.c | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index c3d09b791aad..2d6e983840af 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 31339acd07b4ba687906702085127895a56eb920 +refs/heads/master: ea8efc74bd0402b4d5f663d007b4e25fa29ea778 diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index ff45b80d90f0..9fcb5ede6b72 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -3046,17 +3046,38 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } while (!end) { - off = extent_map_end(em); - if (off >= max) - end = 1; + u64 offset_in_extent; + + /* break if the extent we found is outside the range */ + if (em->start >= max || extent_map_end(em) < off) + break; + + /* + * get_extent may return an extent that starts before our + * requested range. We have to make sure the ranges + * we return to fiemap always move forward and don't + * overlap, so adjust the offsets here + */ + em_start = max(em->start, off); - em_start = em->start; - em_len = em->len; + /* + * record the offset from the start of the extent + * for adjusting the disk offset below + */ + offset_in_extent = em_start - em->start; em_end = extent_map_end(em); + em_len = em_end - em_start; emflags = em->flags; disko = 0; flags = 0; + /* + * bump off for our next call to get_extent + */ + off = extent_map_end(em); + if (off >= max) + end = 1; + if (em->block_start == EXTENT_MAP_LAST_BYTE) { end = 1; flags |= FIEMAP_EXTENT_LAST; @@ -3067,7 +3088,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, flags |= (FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN); } else { - disko = em->block_start; + disko = em->block_start + offset_in_extent; } if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) flags |= FIEMAP_EXTENT_ENCODED;