aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorFilipe Manana <[email protected]>2025-03-25 17:26:37 +0000
committerDavid Sterba <[email protected]>2025-05-15 12:30:40 +0000
commitc4669e4a8b660143ad1fc9743dcb2a3d81a74b42 (patch)
tree4881c2c3dfe646b92b7b2fa2b110fda733612c36 /fs/btrfs/extent_io.c
parentbtrfs: allow folios to be released while ordered extent is finishing (diff)
downloadkernel-c4669e4a8b660143ad1fc9743dcb2a3d81a74b42.tar.gz
kernel-c4669e4a8b660143ad1fc9743dcb2a3d81a74b42.zip
btrfs: pass a pointer to get_range_bits() to cache first search result
Allow get_range_bits() to take an extent state pointer to pointer argument so that we can cache the first extent state record in the target range, so that a caller can use it for subsequent operations without doing a full tree search. Currently the only user is try_release_extent_state(), which then does a call to __clear_extent_bit() which can use such a cached state record. Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 8a544c6e65d9..a9ecf10debd9 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2621,13 +2621,15 @@ int extent_invalidate_folio(struct extent_io_tree *tree,
static bool try_release_extent_state(struct extent_io_tree *tree,
struct folio *folio)
{
+ struct extent_state *cached_state = NULL;
u64 start = folio_pos(folio);
u64 end = start + folio_size(folio) - 1;
u32 range_bits;
u32 clear_bits;
- int ret;
+ bool ret = false;
+ int ret2;
- get_range_bits(tree, start, end, &range_bits);
+ get_range_bits(tree, start, end, &range_bits, &cached_state);
/*
* We can release the folio if it's locked only for ordered extent
@@ -2635,7 +2637,7 @@ static bool try_release_extent_state(struct extent_io_tree *tree,
*/
if ((range_bits & EXTENT_LOCKED) &&
!(range_bits & EXTENT_FINISHING_ORDERED))
- return false;
+ goto out;
clear_bits = ~(EXTENT_LOCKED | EXTENT_NODATASUM | EXTENT_DELALLOC_NEW |
EXTENT_CTLBITS | EXTENT_QGROUP_RESERVED |
@@ -2645,15 +2647,17 @@ static bool try_release_extent_state(struct extent_io_tree *tree,
* nodatasum, delalloc new and finishing ordered bits. The delalloc new
* bit will be cleared by ordered extent completion.
*/
- ret = __clear_extent_bit(tree, start, end, clear_bits, NULL, NULL);
+ ret2 = __clear_extent_bit(tree, start, end, clear_bits, &cached_state, NULL);
/*
* If clear_extent_bit failed for enomem reasons, we can't allow the
* release to continue.
*/
- if (ret < 0)
- return false;
+ if (ret2 == 0)
+ ret = true;
+out:
+ free_extent_state(cached_state);
- return true;
+ return ret;
}
/*