diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
| -rw-r--r-- | fs/btrfs/extent_io.c | 18 |
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; } /* |