summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2022-10-11 15:16:55 +0300
committerDavid Sterba <dsterba@suse.com>2022-12-05 20:00:38 +0300
commit013f9c70d293d7a47aaaeaee248ca60f745fa450 (patch)
tree85defd4da699c22295052d4b9c1ea21c34f0cbc8
parentd47704bd1c78c85831561bcf701b90dd66f811b2 (diff)
downloadlinux-013f9c70d293d7a47aaaeaee248ca60f745fa450.tar.xz
btrfs: skip unnecessary extent map searches during fiemap and lseek
If we have no outstanding extents it means we don't have any extent maps corresponding to delalloc that is flushing, as when an ordered extent is created we increment the number of outstanding extents to 1 and when we remove the ordered extent we decrement them by 1. So skip extent map tree searches if the number of outstanding ordered extents is 0, saving time as the tree is not empty if we have previously made some reads or flushed delalloc, as in those cases it can have a very large number of extent maps for files with many extents. This helps save time when processing a file range corresponding to a hole or prealloc (unwritten) extent. The next patch in the series has a performance test in its changelog and its subject is: "btrfs: skip unnecessary delalloc search during fiemap and lseek" Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/file.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 6685cb0e928c..1cf97280760e 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -3553,6 +3553,18 @@ static bool find_delalloc_subrange(struct btrfs_inode *inode, u64 start, u64 end
if (delalloc_len > 0)
*delalloc_end_ret = *delalloc_start_ret + delalloc_len - 1;
+ spin_lock(&inode->lock);
+ if (inode->outstanding_extents == 0) {
+ /*
+ * No outstanding extents means we don't have any delalloc that
+ * is flushing, so return the unflushed range found in the io
+ * tree (if any).
+ */
+ spin_unlock(&inode->lock);
+ return (delalloc_len > 0);
+ }
+ spin_unlock(&inode->lock);
+
/*
* Now also check if there's any extent map in the range that does not
* map to a hole or prealloc extent. We do this because: