Skip to content

Commit 2abc726

Browse files
josefbacikkdave
authored andcommitted
btrfs: do not init a reloc root if we aren't relocating
We previously were checking if the root had a dead root before accessing root->reloc_root in order to avoid a use-after-free type bug. However this scenario happens after we've unset the reloc control, so we would have been saved if we'd simply checked for fs_info->reloc_control. At this point during relocation we no longer need to be creating new reloc roots, so simply move this check above the reloc_root checks to avoid any future races and confusion. Reviewed-by: Qu Wenruo <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 6217b0f commit 2abc726

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

fs/btrfs/relocation.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,10 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,
15111511
int clear_rsv = 0;
15121512
int ret;
15131513

1514+
if (!rc || !rc->create_reloc_tree ||
1515+
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
1516+
return 0;
1517+
15141518
/*
15151519
* The subvolume has reloc tree but the swap is finished, no need to
15161520
* create/update the dead reloc tree
@@ -1524,10 +1528,6 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,
15241528
return 0;
15251529
}
15261530

1527-
if (!rc || !rc->create_reloc_tree ||
1528-
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
1529-
return 0;
1530-
15311531
if (!trans->reloc_reserved) {
15321532
rsv = trans->block_rsv;
15331533
trans->block_rsv = rc->block_rsv;
@@ -2369,6 +2369,18 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
23692369
trans = NULL;
23702370
goto out;
23712371
}
2372+
2373+
/*
2374+
* At this point we no longer have a reloc_control, so we can't
2375+
* depend on btrfs_init_reloc_root to update our last_trans.
2376+
*
2377+
* But that's ok, we started the trans handle on our
2378+
* corresponding fs_root, which means it's been added to the
2379+
* dirty list. At commit time we'll still call
2380+
* btrfs_update_reloc_root() and update our root item
2381+
* appropriately.
2382+
*/
2383+
reloc_root->last_trans = trans->transid;
23722384
trans->block_rsv = rc->block_rsv;
23732385

23742386
replaced = 0;

0 commit comments

Comments
 (0)