OSDN Git Service

btrfs: hold a ref on the root in fixup_tree_root_location
authorJosef Bacik <josef@toxicpanda.com>
Fri, 24 Jan 2020 14:32:31 +0000 (09:32 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Mar 2020 16:01:28 +0000 (17:01 +0100)
Looking up the inode from an arbitrary tree means we need to hold a ref
on that root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/inode.c

index d105d4d..324fc79 100644 (file)
@@ -5158,6 +5158,10 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info,
                err = PTR_ERR(new_root);
                goto out;
        }
+       if (!btrfs_grab_fs_root(new_root)) {
+               err = -ENOENT;
+               goto out;
+       }
 
        *sub_root = new_root;
        location->objectid = btrfs_root_dirid(&new_root->root_item);
@@ -5400,6 +5404,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
        } else {
                inode = btrfs_iget(dir->i_sb, &location, sub_root);
        }
+       if (root != sub_root)
+               btrfs_put_fs_root(sub_root);
        srcu_read_unlock(&fs_info->subvol_srcu, index);
 
        if (!IS_ERR(inode) && root != sub_root) {