Skip to content

Commit e5b5596

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 <[email protected]> Link: https://lore.kernel.org/linux-btrfs/[email protected]/ Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent ae4477f commit e5b5596

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
@@ -4312,7 +4312,6 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43124312
spin_unlock(&eb->refs_lock);
43134313
continue;
43144314
}
4315-
xa_unlock_irq(&fs_info->buffer_tree);
43164315

43174316
/*
43184317
* If tree ref isn't set then we know the ref on this eb is a
@@ -4329,6 +4328,7 @@ static int try_release_subpage_extent_buffer(struct folio *folio)
43294328
* check the folio private at the end. And
43304329
* release_extent_buffer() will release the refs_lock.
43314330
*/
4331+
xa_unlock_irq(&fs_info->buffer_tree);
43324332
release_extent_buffer(eb);
43334333
xa_lock_irq(&fs_info->buffer_tree);
43344334
}

0 commit comments

Comments
 (0)