mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
btrfs: check block group before marking it unused in balance_remap_chunks()
Fix a potential segfault in balance_remap_chunks(): if we quit early
because btrfs_inc_block_group_ro() fails, all the remaining items in the
chunks list will still have their bg value set to NULL. It's thus not
safe to dereference this pointer without checking first.
Reported-by: Chris Mason <clm@fb.com>
Link: https://lore.kernel.org/linux-btrfs/20260125120717.1578828-1-clm@meta.com/
Fixes: 81e5a4551c ("btrfs: allow balancing remap tree")
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Mark Harmstone <mark@harmstone.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
057495ccc0
commit
adbb0ebacc
|
|
@ -4277,20 +4277,29 @@ static int balance_remap_chunks(struct btrfs_fs_info *fs_info, struct btrfs_path
|
|||
end:
|
||||
while (!list_empty(chunks)) {
|
||||
bool is_unused;
|
||||
struct btrfs_block_group *bg;
|
||||
|
||||
rci = list_first_entry(chunks, struct remap_chunk_info, list);
|
||||
|
||||
spin_lock(&rci->bg->lock);
|
||||
is_unused = !btrfs_is_block_group_used(rci->bg);
|
||||
spin_unlock(&rci->bg->lock);
|
||||
bg = rci->bg;
|
||||
if (bg) {
|
||||
/*
|
||||
* This is a bit racy and the 'used' status can change
|
||||
* but this is not a problem as later functions will
|
||||
* verify it again.
|
||||
*/
|
||||
spin_lock(&bg->lock);
|
||||
is_unused = !btrfs_is_block_group_used(bg);
|
||||
spin_unlock(&bg->lock);
|
||||
|
||||
if (is_unused)
|
||||
btrfs_mark_bg_unused(rci->bg);
|
||||
if (is_unused)
|
||||
btrfs_mark_bg_unused(bg);
|
||||
|
||||
if (rci->made_ro)
|
||||
btrfs_dec_block_group_ro(rci->bg);
|
||||
if (rci->made_ro)
|
||||
btrfs_dec_block_group_ro(bg);
|
||||
|
||||
btrfs_put_block_group(rci->bg);
|
||||
btrfs_put_block_group(bg);
|
||||
}
|
||||
|
||||
list_del(&rci->list);
|
||||
kfree(rci);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user