mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	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 <wqu@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
		
							parent
							
								
									6217b0fadd
								
							
						
					
					
						commit
						2abc726ab4
					
				
					 1 changed files with 16 additions and 4 deletions
				
			
		|  | @ -1511,6 +1511,10 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans, | |||
| 	int clear_rsv = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!rc || !rc->create_reloc_tree || | ||||
| 	    root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The subvolume has reloc tree but the swap is finished, no need to | ||||
| 	 * create/update the dead reloc tree | ||||
|  | @ -1524,10 +1528,6 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans, | |||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!rc || !rc->create_reloc_tree || | ||||
| 	    root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (!trans->reloc_reserved) { | ||||
| 		rsv = trans->block_rsv; | ||||
| 		trans->block_rsv = rc->block_rsv; | ||||
|  | @ -2369,6 +2369,18 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, | |||
| 			trans = NULL; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * At this point we no longer have a reloc_control, so we can't | ||||
| 		 * depend on btrfs_init_reloc_root to update our last_trans. | ||||
| 		 * | ||||
| 		 * But that's ok, we started the trans handle on our | ||||
| 		 * corresponding fs_root, which means it's been added to the | ||||
| 		 * dirty list.  At commit time we'll still call | ||||
| 		 * btrfs_update_reloc_root() and update our root item | ||||
| 		 * appropriately. | ||||
| 		 */ | ||||
| 		reloc_root->last_trans = trans->transid; | ||||
| 		trans->block_rsv = rc->block_rsv; | ||||
| 
 | ||||
| 		replaced = 0; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Josef Bacik
						Josef Bacik