diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 25 | 
1 files changed, 18 insertions, 7 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 59ea049fe7ee..fbf9006c6234 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3121,23 +3121,34 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)  {  	int ret;  	const bool cache_opt = btrfs_test_opt(fs_info, SPACE_CACHE); -	bool clear_free_space_tree = false; +	bool rebuild_free_space_tree = false;  	if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&  	    btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { -		clear_free_space_tree = true; +		rebuild_free_space_tree = true;  	} else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&  		   !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {  		btrfs_warn(fs_info, "free space tree is invalid"); -		clear_free_space_tree = true; +		rebuild_free_space_tree = true;  	} -	if (clear_free_space_tree) { -		btrfs_info(fs_info, "clearing free space tree"); -		ret = btrfs_clear_free_space_tree(fs_info); +	if (rebuild_free_space_tree) { +		btrfs_info(fs_info, "rebuilding free space tree"); +		ret = btrfs_rebuild_free_space_tree(fs_info);  		if (ret) {  			btrfs_warn(fs_info, -				   "failed to clear free space tree: %d", ret); +				   "failed to rebuild free space tree: %d", ret); +			goto out; +		} +	} + +	if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && +	    !btrfs_test_opt(fs_info, FREE_SPACE_TREE)) { +		btrfs_info(fs_info, "disabling free space tree"); +		ret = btrfs_delete_free_space_tree(fs_info); +		if (ret) { +			btrfs_warn(fs_info, +				   "failed to disable free space tree: %d", ret);  			goto out;  		}  	}  | 
