aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2013-01-07 10:10:12 +0000
committerJosef Bacik <josef@toxicpanda.com>2013-01-14 13:53:22 -0500
commitf9e4fb53938de5db01950c9dfe479703b2f5c964 (patch)
tree95e9e8326d4a39feedc591c8d05de33d5db46d96 /fs/btrfs
parent1214b53f90131fee1f950010c43e92455fe598ab (diff)
downloadkernel_goldelico_gta04-f9e4fb53938de5db01950c9dfe479703b2f5c964.zip
kernel_goldelico_gta04-f9e4fb53938de5db01950c9dfe479703b2f5c964.tar.gz
kernel_goldelico_gta04-f9e4fb53938de5db01950c9dfe479703b2f5c964.tar.bz2
Btrfs: fix a bug when llseek for delalloc bytes behind prealloc extents
xfstests case 285 complains. It it because btrfs did not try to find unwritten delalloc bytes(only dirty pages, not yet writeback) behind prealloc extents, it ends up finding nothing while we're with SEEK_DATA. Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/file.c9
-rw-r--r--fs/btrfs/inode.c11
2 files changed, 14 insertions, 6 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index fa48051..841cfe3 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2309,9 +2309,12 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
}
}
- *offset = start;
- free_extent_map(em);
- break;
+ if (!test_bit(EXTENT_FLAG_PREALLOC,
+ &em->flags)) {
+ *offset = start;
+ free_extent_map(em);
+ break;
+ }
}
}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4ddcf79..ac98384 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5623,10 +5623,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag
return em;
if (em) {
/*
- * if our em maps to a hole, there might
- * actually be delalloc bytes behind it
+ * if our em maps to
+ * - a hole or
+ * - a pre-alloc extent,
+ * there might actually be delalloc bytes behind it.
*/
- if (em->block_start != EXTENT_MAP_HOLE)
+ if (em->block_start != EXTENT_MAP_HOLE &&
+ !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
return em;
else
hole_em = em;
@@ -5708,6 +5711,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag
*/
em->block_start = hole_em->block_start;
em->block_len = hole_len;
+ if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags))
+ set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
} else {
em->start = range_start;
em->len = found;