summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2020-02-06 16:24:26 +0100
committerDavid Sterba <dsterba@suse.com>2020-03-23 17:01:31 +0100
commit5168489a079aacd5626156ce5f8ab77325bcde15 (patch)
treee1512a8df8d1426c03fa999d1c0e5c3d989e2d89 /fs/btrfs/super.c
parentbtrfs: hold a ref on the root in btrfs_ioctl_send (diff)
downloadlinux-5168489a079aacd5626156ce5f8ab77325bcde15.tar.xz
linux-5168489a079aacd5626156ce5f8ab77325bcde15.zip
btrfs: hold a ref on the root in get_subvol_name_from_objectid
We lookup the name of a subvol which means we'll cross into different roots. Hold a ref while we're doing the look ups in the fs_root we're searching. 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 '')
-rw-r--r--fs/btrfs/super.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index a2c2e71af122..2c459d29e099 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1028,7 +1028,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
u64 subvol_objectid)
{
struct btrfs_root *root = fs_info->tree_root;
- struct btrfs_root *fs_root;
+ struct btrfs_root *fs_root = NULL;
struct btrfs_root_ref *root_ref;
struct btrfs_inode_ref *inode_ref;
struct btrfs_key key;
@@ -1099,6 +1099,12 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
fs_root = btrfs_get_fs_root(fs_info, &key, true);
if (IS_ERR(fs_root)) {
ret = PTR_ERR(fs_root);
+ fs_root = NULL;
+ goto err;
+ }
+ if (!btrfs_grab_fs_root(fs_root)) {
+ ret = -ENOENT;
+ fs_root = NULL;
goto err;
}
@@ -1143,6 +1149,8 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
ptr[0] = '/';
btrfs_release_path(path);
}
+ btrfs_put_fs_root(fs_root);
+ fs_root = NULL;
}
btrfs_free_path(path);
@@ -1155,6 +1163,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
return name;
err:
+ btrfs_put_fs_root(fs_root);
btrfs_free_path(path);
kfree(name);
return ERR_PTR(ret);