Skip to content

Commit ab31321

Browse files
fdmananakdave
authored andcommitted
btrfs: fix double unlock of buffer_tree xarray when releasing subpage eb
If we break out of the loop because an extent buffer doesn't have the bit EXTENT_BUFFER_TREE_REF set, we end up unlocking the xarray twice, once before we tested for the bit and break out of the loop, and once again after the loop. Fix this by testing the bit and exiting before unlocking the xarray. The time spent testing the bit is negligible and it's not worth trying to do that outside the critical section delimited by the xarray lock due to the code complexity required to avoid it (like using a local boolean variable to track whether the xarray is locked or not). The xarray unlock only needs to be done before calling release_extent_buffer(), as that needs to lock the xarray (through xa_cmpxchg_irq()) and does a more significant amount of work. Fixes: 19d7f65 ("btrfs: convert the buffer_radix to an xarray") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Link: https://lore.kernel.org/linux-btrfs/aDRNDU0GM1_D4Xnw@stanley.mountain/ Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent b06d800 commit ab31321

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

fs/btrfs/extent_io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4316,7 +4316,6 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43164316
spin_unlock(&eb->refs_lock);
43174317
continue;
43184318
}
4319-
xa_unlock_irq(&fs_info->buffer_tree);
43204319

43214320
/*
43224321
* If tree ref isn't set then we know the ref on this eb is a
@@ -4333,6 +4332,7 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43334332
* check the folio private at the end. And
43344333
* release_extent_buffer() will release the refs_lock.
43354334
*/
4335+
xa_unlock_irq(&fs_info->buffer_tree);
43364336
release_extent_buffer(eb);
43374337
xa_lock_irq(&fs_info->buffer_tree);
43384338
}

0 commit comments

Comments
 (0)