btrfs: avoid re-searching tree when setting bits in an extent range
authorFilipe Manana <fdmanana@suse.com>
Thu, 17 Apr 2025 12:03:42 +0000 (13:03 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 15 May 2025 12:30:52 +0000 (14:30 +0200)
When setting bits for an extent range (set_extent_bit()), if the current
extent state record starts after the target range, we always do a jump to
the 'search_again' label, which will cause us to do a full tree search for
the next state if the current state ends before the target range. Unless
we need to reschedule, we can just grab the next state and process it,
avoiding a full tree search, even if that next state is not contiguous, as
we'll allocate and insert a new prealloc state if needed.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-io-tree.c

index 689ba1a2b2d58b135c8c86e6cf7f159261fac4f7..dd36322fbf6b588c76dbd72b9dd70077adf44ba0 100644 (file)
@@ -1226,6 +1226,22 @@ hit_next:
                if (inserted_state == prealloc)
                        prealloc = NULL;
                start = inserted_state->end + 1;
+
+               /* Beyond target range, stop. */
+               if (start > end)
+                       goto out;
+
+               if (need_resched())
+                       goto search_again;
+
+               state = next_search_state(inserted_state, end);
+               /*
+                * If there's a next state, whether contiguous or not, we don't
+                * need to unlock and start search agian. If it's not contiguous
+                * we will end up here and try to allocate a prealloc state and insert.
+                */
+               if (state)
+                       goto hit_next;
                goto search_again;
        }
        /*