diff options
author | Josef Bacik <josef@toxicpanda.com> | 2020-02-14 22:11:47 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2020-03-23 17:02:00 +0100 |
commit | c75e839414d3610e6487ae3145199c500d55f7f7 (patch) | |
tree | 68e609a6362c4f259afc2e107fffac94e743a126 /fs/btrfs/backref.c | |
parent | btrfs: make btrfs_cleanup_fs_roots use the radix tree lock (diff) | |
download | linux-c75e839414d3610e6487ae3145199c500d55f7f7.tar.xz linux-c75e839414d3610e6487ae3145199c500d55f7f7.zip |
btrfs: kill the subvol_srcu
Now that we have proper root ref counting everywhere we can kill the
subvol_srcu.
* removal of fs_info::subvol_srcu reduces size of fs_info by 1176 bytes
* the refcount_t used for the references checks for accidental 0->1
in cases where the root lifetime would not be properly protected
* there's a leak detector for roots to catch unfreed roots at umount
time
* SRCU served us well over the years but is was not a proper
synchronization mechanism for some cases
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ update changelog ]
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r-- | fs/btrfs/backref.c | 12 |
1 files changed, 1 insertions, 11 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index f2728fb3ee8f..cd2d39b60be0 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -542,24 +542,19 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info, int ret = 0; int root_level; int level = ref->level; - int index; struct btrfs_key search_key = ref->key_for_search; root_key.objectid = ref->root_id; root_key.type = BTRFS_ROOT_ITEM_KEY; root_key.offset = (u64)-1; - index = srcu_read_lock(&fs_info->subvol_srcu); - root = btrfs_get_fs_root(fs_info, &root_key, false); if (IS_ERR(root)) { - srcu_read_unlock(&fs_info->subvol_srcu, index); ret = PTR_ERR(root); goto out_free; } if (btrfs_is_testing(fs_info)) { - srcu_read_unlock(&fs_info->subvol_srcu, index); ret = -ENOENT; goto out; } @@ -571,10 +566,8 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info, else root_level = btrfs_old_root_level(root, time_seq); - if (root_level + 1 == level) { - srcu_read_unlock(&fs_info->subvol_srcu, index); + if (root_level + 1 == level) goto out; - } /* * We can often find data backrefs with an offset that is too large @@ -604,9 +597,6 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info, else ret = btrfs_search_old_slot(root, &search_key, path, time_seq); - /* root node has been locked, we can release @subvol_srcu safely here */ - srcu_read_unlock(&fs_info->subvol_srcu, index); - btrfs_debug(fs_info, "search slot in root %llu (level %d, ref count %d) returned %d for key (%llu %u %llu)", ref->root_id, level, ref->count, ret, |