summaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2020-03-04 11:18:25 -0500
committerDavid Sterba <dsterba@suse.com>2020-03-23 17:01:57 +0100
commitfb2d83eefef4e1c717205bac71cb1941edf8ae11 (patch)
tree641e169a18601367fa60f5dbaba8e2a969233bf3 /fs/btrfs
parent8e19c9732ad1d127b5575a10f4fbcacf740500ff (diff)
btrfs: unset reloc control if we fail to recover
If we fail to load an fs root, or fail to start a transaction we can bail without unsetting the reloc control, which leads to problems later when we free the reloc control but still have it attached to the file system. In the normal path we'll end up calling unset_reloc_control() twice, but all it does is set fs_info->reloc_control = NULL, and we can only have one balance at a time so it's not racey. CC: stable@vger.kernel.org # 5.4+ 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>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/relocation.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index d7f3d2197fa1..78537541059b 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4460,9 +4460,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
trans = btrfs_join_transaction(rc->extent_root);
if (IS_ERR(trans)) {
- unset_reloc_control(rc);
err = PTR_ERR(trans);
- goto out_free;
+ goto out_unset;
}
rc->merge_reloc_tree = 1;
@@ -4482,7 +4481,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
if (IS_ERR(fs_root)) {
err = PTR_ERR(fs_root);
list_add_tail(&reloc_root->root_list, &reloc_roots);
- goto out_free;
+ goto out_unset;
}
err = __add_reloc_root(reloc_root);
@@ -4493,7 +4492,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
err = btrfs_commit_transaction(trans);
if (err)
- goto out_free;
+ goto out_unset;
merge_reloc_roots(rc);
@@ -4509,7 +4508,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
ret = clean_dirty_subvols(rc);
if (ret < 0 && !err)
err = ret;
-out_free:
+out_unset:
+ unset_reloc_control(rc);
kfree(rc);
out:
if (!list_empty(&reloc_roots))