diff options
author | Josef Bacik <josef@toxicpanda.com> | 2020-01-24 15:32:56 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2020-03-23 17:01:32 +0100 |
commit | bc44d7c4b2b179c4b74fba208b9908e2ecbc1b4d (patch) | |
tree | 183d1adc1dcae85af965e25476a5a6c8cbb0137b /fs/btrfs/disk-io.c | |
parent | btrfs: use btrfs_put_fs_root to free roots always (diff) | |
download | linux-bc44d7c4b2b179c4b74fba208b9908e2ecbc1b4d.tar.xz linux-bc44d7c4b2b179c4b74fba208b9908e2ecbc1b4d.zip |
btrfs: push btrfs_grab_fs_root into btrfs_get_fs_root
Now that all callers of btrfs_get_fs_root are subsequently calling
btrfs_grab_fs_root and handling dropping the ref when they are done
appropriately, go ahead and push btrfs_grab_fs_root up into
btrfs_get_fs_root.
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/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 5be61619c71b..a0c67200fb2a 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1496,6 +1496,8 @@ static struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info, spin_lock(&fs_info->fs_roots_radix_lock); root = radix_tree_lookup(&fs_info->fs_roots_radix, (unsigned long)root_id); + if (root) + root = btrfs_grab_fs_root(root); spin_unlock(&fs_info->fs_roots_radix_lock); return root; } @@ -1552,29 +1554,31 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, int ret; if (location->objectid == BTRFS_ROOT_TREE_OBJECTID) - return fs_info->tree_root; + return btrfs_grab_fs_root(fs_info->tree_root); if (location->objectid == BTRFS_EXTENT_TREE_OBJECTID) - return fs_info->extent_root; + return btrfs_grab_fs_root(fs_info->extent_root); if (location->objectid == BTRFS_CHUNK_TREE_OBJECTID) - return fs_info->chunk_root; + return btrfs_grab_fs_root(fs_info->chunk_root); if (location->objectid == BTRFS_DEV_TREE_OBJECTID) - return fs_info->dev_root; + return btrfs_grab_fs_root(fs_info->dev_root); if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) - return fs_info->csum_root; + return btrfs_grab_fs_root(fs_info->csum_root); if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID) - return fs_info->quota_root ? fs_info->quota_root : - ERR_PTR(-ENOENT); + return btrfs_grab_fs_root(fs_info->quota_root) ? + fs_info->quota_root : ERR_PTR(-ENOENT); if (location->objectid == BTRFS_UUID_TREE_OBJECTID) - return fs_info->uuid_root ? fs_info->uuid_root : - ERR_PTR(-ENOENT); + return btrfs_grab_fs_root(fs_info->uuid_root) ? + fs_info->uuid_root : ERR_PTR(-ENOENT); if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID) - return fs_info->free_space_root ? fs_info->free_space_root : - ERR_PTR(-ENOENT); + return btrfs_grab_fs_root(fs_info->free_space_root) ? + fs_info->free_space_root : ERR_PTR(-ENOENT); again: root = btrfs_lookup_fs_root(fs_info, location->objectid); if (root) { - if (check_ref && btrfs_root_refs(&root->root_item) == 0) + if (check_ref && btrfs_root_refs(&root->root_item) == 0) { + btrfs_put_fs_root(root); return ERR_PTR(-ENOENT); + } return root; } @@ -1607,8 +1611,18 @@ again: if (ret == 0) set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state); + /* + * All roots have two refs on them at all times, one for the mounted fs, + * and one for being in the radix tree. This way we only free the root + * when we are unmounting or deleting the subvolume. We get one ref + * from __setup_root, one for inserting it into the radix tree, and then + * we have the third for returning it, and the caller will put it when + * it's done with the root. + */ + btrfs_grab_fs_root(root); ret = btrfs_insert_fs_root(fs_info, root); if (ret) { + btrfs_put_fs_root(root); if (ret == -EEXIST) { btrfs_free_fs_root(root); goto again; @@ -3207,13 +3221,6 @@ int __cold open_ctree(struct super_block *sb, goto fail_qgroup; } - if (!btrfs_grab_fs_root(fs_info->fs_root)) { - fs_info->fs_root = NULL; - err = -ENOENT; - btrfs_warn(fs_info, "failed to grab a ref on the fs tree"); - goto fail_qgroup; - } - if (sb_rdonly(sb)) return 0; |