@@ -1248,18 +1248,35 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
if (IS_ERR(trans))
return PTR_ERR(trans);
- features = btrfs_super_compat_ro_flags(fs_info->super_copy);
- features &= ~(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID |
- BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE);
- btrfs_set_super_compat_ro_flags(fs_info->super_copy, features);
+ if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+ struct btrfs_key key = {
+ .objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
+ .type = BTRFS_ROOT_ITEM_KEY,
+ .offset = 0,
+ };
+
+ while (key.offset < fs_info->nr_global_roots) {
+ free_space_root = btrfs_global_root(fs_info, &key);
+ ret = clear_free_space_tree(trans, free_space_root);
+ if (ret)
+ goto abort;
+ key.offset++;
+ }
+ } else {
+ features = btrfs_super_compat_ro_flags(fs_info->super_copy);
+ features &= ~(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID |
+ BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE);
+ btrfs_set_super_compat_ro_flags(fs_info->super_copy, features);
- ret = clear_free_space_tree(trans, free_space_root);
- if (ret)
- goto abort;
+ ret = clear_free_space_tree(trans, free_space_root);
+ if (ret)
+ goto abort;
- ret = btrfs_delete_and_free_root(trans, free_space_root);
- if (!ret)
- ret = btrfs_commit_transaction(trans, tree_root);
+ ret = btrfs_delete_and_free_root(trans, free_space_root);
+ if (ret)
+ goto abort;
+ }
+ ret = btrfs_commit_transaction(trans, tree_root);
abort:
return ret;
}
With extent tree v2 we'll have multiple free space trees, and we can't just unset the feature flags for the free space tree. Fix this to loop through all of the free space trees and clear them out properly. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- kernel-shared/free-space-tree.c | 37 ++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-)