diff --git a/kernel-shared/free-space-tree.c b/kernel-shared/free-space-tree.c index 0a13b1d6..7ac75c20 100644 --- a/kernel-shared/free-space-tree.c +++ b/kernel-shared/free-space-tree.c @@ -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, + }; - ret = clear_free_space_tree(trans, free_space_root); - if (ret) - goto abort; + 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 = btrfs_delete_and_free_root(trans, free_space_root); - if (!ret) - ret = btrfs_commit_transaction(trans, tree_root); + 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) + goto abort; + } + ret = btrfs_commit_transaction(trans, tree_root); abort: return ret; }