aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 15384968a84a..10ae5700ab1e 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -301,23 +301,34 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
301 int ret = 0; 301 int ret = 0;
302 int root_level; 302 int root_level;
303 int level = ref->level; 303 int level = ref->level;
304 int index;
304 305
305 root_key.objectid = ref->root_id; 306 root_key.objectid = ref->root_id;
306 root_key.type = BTRFS_ROOT_ITEM_KEY; 307 root_key.type = BTRFS_ROOT_ITEM_KEY;
307 root_key.offset = (u64)-1; 308 root_key.offset = (u64)-1;
309
310 index = srcu_read_lock(&fs_info->subvol_srcu);
311
308 root = btrfs_read_fs_root_no_name(fs_info, &root_key); 312 root = btrfs_read_fs_root_no_name(fs_info, &root_key);
309 if (IS_ERR(root)) { 313 if (IS_ERR(root)) {
314 srcu_read_unlock(&fs_info->subvol_srcu, index);
310 ret = PTR_ERR(root); 315 ret = PTR_ERR(root);
311 goto out; 316 goto out;
312 } 317 }
313 318
314 root_level = btrfs_old_root_level(root, time_seq); 319 root_level = btrfs_old_root_level(root, time_seq);
315 320
316 if (root_level + 1 == level) 321 if (root_level + 1 == level) {
322 srcu_read_unlock(&fs_info->subvol_srcu, index);
317 goto out; 323 goto out;
324 }
318 325
319 path->lowest_level = level; 326 path->lowest_level = level;
320 ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq); 327 ret = btrfs_search_old_slot(root, &ref->key_for_search, path, time_seq);
328
329 /* root node has been locked, we can release @subvol_srcu safely here */
330 srcu_read_unlock(&fs_info->subvol_srcu, index);
331
321 pr_debug("search slot in root %llu (level %d, ref count %d) returned " 332 pr_debug("search slot in root %llu (level %d, ref count %d) returned "
322 "%d for key (%llu %u %llu)\n", 333 "%d for key (%llu %u %llu)\n",
323 ref->root_id, level, ref->count, ret, 334 ref->root_id, level, ref->count, ret,