]> git.hungrycats.org Git - linux/commitdiff
btrfs: hold a ref on the root in btrfs_recover_relocation
authorJosef Bacik <josef@toxicpanda.com>
Wed, 20 Nov 2019 19:57:47 +0000 (11:57 -0800)
committerJosef Bacik <josef@toxicpanda.com>
Fri, 6 Dec 2019 16:34:48 +0000 (08:34 -0800)
We look up the fs root in various places in here when recovering from a
crashed relcoation.  Make sure we hold a ref on the root whenever we
look them up.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
fs/btrfs/relocation.c

index 4e455703439bbd09ac37795b72bcd0688c342c39..d40d145588f32008c7540717a1c846abc23a62b3 100644 (file)
@@ -4542,6 +4542,10 @@ int btrfs_recover_relocation(struct btrfs_root *root)
                if (btrfs_root_refs(&reloc_root->root_item) > 0) {
                        fs_root = read_fs_root(fs_info,
                                               reloc_root->root_key.offset);
+                       if (!btrfs_grab_fs_root(fs_root)) {
+                               err = -ENOENT;
+                               goto out;
+                       }
                        if (IS_ERR(fs_root)) {
                                ret = PTR_ERR(fs_root);
                                if (ret != -ENOENT) {
@@ -4553,6 +4557,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
                                        err = ret;
                                        goto out;
                                }
+                       } else {
+                               btrfs_put_fs_root(fs_root);
                        }
                }
 
@@ -4602,10 +4608,15 @@ int btrfs_recover_relocation(struct btrfs_root *root)
                        list_add_tail(&reloc_root->root_list, &reloc_roots);
                        goto out_free;
                }
+               if (!btrfs_grab_fs_root(fs_root)) {
+                       err = -ENOENT;
+                       goto out_free;
+               }
 
                err = __add_reloc_root(reloc_root);
                BUG_ON(err < 0); /* -ENOMEM or logic error */
                fs_root->reloc_root = reloc_root;
+               btrfs_put_fs_root(fs_root);
        }
 
        err = btrfs_commit_transaction(trans);
@@ -4637,10 +4648,14 @@ out:
        if (err == 0) {
                /* cleanup orphan inode in data relocation tree */
                fs_root = read_fs_root(fs_info, BTRFS_DATA_RELOC_TREE_OBJECTID);
-               if (IS_ERR(fs_root))
+               if (IS_ERR(fs_root)) {
                        err = PTR_ERR(fs_root);
-               else
-                       err = btrfs_orphan_cleanup(fs_root);
+               } else {
+                       if (btrfs_grab_fs_root(fs_root)) {
+                               err = btrfs_orphan_cleanup(fs_root);
+                               btrfs_put_fs_root(fs_root);
+                       }
+               }
        }
        return err;
 }