diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 618c6890699a..46f89cbe6193 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -5574,10 +5574,24 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo, flags |= (FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN); } else if (fieinfo->fi_extents_max) { + u64 extent_gen; u64 bytenr = em->block_start - (em->start - em->orig_start); /* + * If two extent maps are merged, then their generation + * is set to the maximum between their generations. + * Otherwise its generation matches the one we have in + * corresponding file extent item. If we have a merged + * extent map, don't use its generation to speedup the + * sharedness check below. + */ + if (test_bit(EXTENT_FLAG_MERGED, &em->flags)) + extent_gen = 0; + else + extent_gen = em->generation; + + /* * As btrfs supports shared space, this information * can be exported to userspace tools via * flag FIEMAP_EXTENT_SHARED. If fi_extents_max == 0 @@ -5585,8 +5599,8 @@ int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo, * lookup stuff. */ ret = btrfs_is_data_extent_shared(root, btrfs_ino(inode), - bytenr, roots, - tmp_ulist, + bytenr, extent_gen, + roots, tmp_ulist, backref_cache); if (ret < 0) goto out_free; |