]> git.baikalelectronics.ru Git - kernel.git/commitdiff
Btrfs: do not offset physical if we're compressed
authorJosef Bacik <jbacik@fusionio.com>
Fri, 5 Jul 2013 17:52:51 +0000 (13:52 -0400)
committerChris Mason <chris.mason@fusionio.com>
Fri, 9 Aug 2013 23:29:50 +0000 (19:29 -0400)
xfstest btrfs/276 was freaking out on slower boxes partly because fiemap was
offsetting the physical based on the extent offset.  This is perfectly fine with
uncompressed extents, however the extent offset is into the uncompressed area,
not the compressed.  So we can return a physical value that isn't at all within
the area we have allocated on disk.  Fix this by returning the start of the
extent if it is compressed no matter what the offset.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/extent_io.c

index 583d98bd065ed83ca979a2786b59ae4342380c47..fe443fece85111d69b833f9cac4e2bbb85b6ea80 100644 (file)
@@ -4048,7 +4048,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
        }
 
        while (!end) {
-               u64 offset_in_extent;
+               u64 offset_in_extent = 0;
 
                /* break if the extent we found is outside the range */
                if (em->start >= max || extent_map_end(em) < off)
@@ -4064,9 +4064,12 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 
                /*
                 * record the offset from the start of the extent
-                * for adjusting the disk offset below
+                * for adjusting the disk offset below.  Only do this if the
+                * extent isn't compressed since our in ram offset may be past
+                * what we have actually allocated on disk.
                 */
-               offset_in_extent = em_start - em->start;
+               if (!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
+                       offset_in_extent = em_start - em->start;
                em_end = extent_map_end(em);
                em_len = em_end - em_start;
                emflags = em->flags;