btrfs: pass root owner to read_tree_block
authorJosef Bacik <josef@toxicpanda.com>
Thu, 5 Nov 2020 15:45:18 +0000 (10:45 -0500)
committerDavid Sterba <dsterba@suse.com>
Tue, 8 Dec 2020 14:54:07 +0000 (15:54 +0100)
In order to properly set the lockdep class of a newly allocated block we
need to know the owner of the block.  For non-refcounted trees this is
straightforward, we always know in advance what tree we're reading from.
For refcounted trees we don't necessarily know, however all refcounted
trees share the same lockdep class name, tree-<level>.

Fix all the callers of read_tree_block() to pass in the root objectid
we're using.  In places like relocation and backref we could probably
unconditionally use 0, but just in case use the root when we have it,
otherwise use 0 in the cases we don't have the root as it's going to be
a refcounted tree anyway.

This is a preparation patch for further changes.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
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/backref.c
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/print-tree.c
fs/btrfs/qgroup.c
fs/btrfs/relocation.c

index 86abe34e94442cca471919dc86c7a71b8de22d19..02d7d7b2563b5cb9f0fdc7e8fc9e910731016fe3 100644 (file)
@@ -783,8 +783,8 @@ static int add_missing_keys(struct btrfs_fs_info *fs_info,
                BUG_ON(ref->key_for_search.type);
                BUG_ON(!ref->wanted_disk_byte);
 
-               eb = read_tree_block(fs_info, ref->wanted_disk_byte, 0,
-                                    ref->level - 1, NULL);
+               eb = read_tree_block(fs_info, ref->wanted_disk_byte,
+                                    ref->root_id, 0, ref->level - 1, NULL);
                if (IS_ERR(eb)) {
                        free_pref(ref);
                        return PTR_ERR(eb);
@@ -1331,7 +1331,7 @@ again:
                                struct extent_buffer *eb;
 
                                eb = read_tree_block(fs_info, ref->parent, 0,
-                                                    ref->level, NULL);
+                                                    0, ref->level, NULL);
                                if (IS_ERR(eb)) {
                                        ret = PTR_ERR(eb);
                                        goto out;
index 467f90af5563a1610d3aac2a292ba5eae9fc9971..e2673c29e7333cbcb81e1780affd8a2c352db0fa 100644 (file)
@@ -1353,7 +1353,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
        if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
                btrfs_tree_read_unlock(eb_root);
                free_extent_buffer(eb_root);
-               old = read_tree_block(fs_info, logical, 0, level, NULL);
+               old = read_tree_block(fs_info, logical, root->root_key.objectid,
+                                     0, level, NULL);
                if (WARN_ON(IS_ERR(old) || !extent_buffer_uptodate(old))) {
                        if (!IS_ERR(old))
                                free_extent_buffer(old);
@@ -1760,6 +1761,7 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent,
 
        btrfs_node_key_to_cpu(parent, &first_key, slot);
        eb = read_tree_block(parent->fs_info, btrfs_node_blockptr(parent, slot),
+                            btrfs_header_owner(parent),
                             btrfs_node_ptr_generation(parent, slot),
                             level - 1, &first_key);
        if (!IS_ERR(eb) && !extent_buffer_uptodate(eb)) {
@@ -2349,8 +2351,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
                reada_for_search(fs_info, p, level, slot, key->objectid);
 
        ret = -EAGAIN;
-       tmp = read_tree_block(fs_info, blocknr, gen, parent_level - 1,
-                             &first_key);
+       tmp = read_tree_block(fs_info, blocknr, root->root_key.objectid,
+                             gen, parent_level - 1, &first_key);
        if (!IS_ERR(tmp)) {
                /*
                 * If the read above didn't mark this buffer up to date,
index 012e66601270a2ef7f6ceacd7ce5bb2834015926..763121380942b7abb5e29a7c86249c5881f2bfbc 100644 (file)
@@ -966,13 +966,14 @@ struct extent_buffer *btrfs_find_create_tree_block(
  * Read tree block at logical address @bytenr and do variant basic but critical
  * verification.
  *
+ * @owner_root:                the objectid of the root owner for this block.
  * @parent_transid:    expected transid of this tree block, skip check if 0
  * @level:             expected level, mandatory check
  * @first_key:         expected key in slot 0, skip check if NULL
  */
 struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
-                                     u64 parent_transid, int level,
-                                     struct btrfs_key *first_key)
+                                     u64 owner_root, u64 parent_transid,
+                                     int level, struct btrfs_key *first_key)
 {
        struct extent_buffer *buf = NULL;
        int ret;
@@ -1295,7 +1296,7 @@ static struct btrfs_root *read_tree_root_path(struct btrfs_root *tree_root,
        level = btrfs_root_level(&root->root_item);
        root->node = read_tree_block(fs_info,
                                     btrfs_root_bytenr(&root->root_item),
-                                    generation, level, NULL);
+                                    key->objectid, generation, level, NULL);
        if (IS_ERR(root->node)) {
                ret = PTR_ERR(root->node);
                root->node = NULL;
@@ -2249,8 +2250,9 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
                return -ENOMEM;
 
        log_tree_root->node = read_tree_block(fs_info, bytenr,
-                                             fs_info->generation + 1,
-                                             level, NULL);
+                                             BTRFS_TREE_LOG_OBJECTID,
+                                             fs_info->generation + 1, level,
+                                             NULL);
        if (IS_ERR(log_tree_root->node)) {
                btrfs_warn(fs_info, "failed to read log tree");
                ret = PTR_ERR(log_tree_root->node);
@@ -2636,6 +2638,7 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
                generation = btrfs_super_generation(sb);
                level = btrfs_super_root_level(sb);
                tree_root->node = read_tree_block(fs_info, btrfs_super_root(sb),
+                                                 BTRFS_ROOT_TREE_OBJECTID,
                                                  generation, level, NULL);
                if (IS_ERR(tree_root->node)) {
                        handle_error = true;
@@ -3124,6 +3127,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 
        chunk_root->node = read_tree_block(fs_info,
                                           btrfs_super_chunk_root(disk_super),
+                                          BTRFS_CHUNK_TREE_OBJECTID,
                                           generation, level, NULL);
        if (IS_ERR(chunk_root->node) ||
            !extent_buffer_uptodate(chunk_root->node)) {
index 009f505d6c9792f1e5e469743798b956611b4d80..41588babf2eddd18fdf104148398592689125f25 100644 (file)
@@ -43,8 +43,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info);
 int btrfs_verify_level_key(struct extent_buffer *eb, int level,
                           struct btrfs_key *first_key, u64 parent_transid);
 struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
-                                     u64 parent_transid, int level,
-                                     struct btrfs_key *first_key);
+                                     u64 owner_root, u64 parent_transid,
+                                     int level, struct btrfs_key *first_key);
 struct extent_buffer *btrfs_find_create_tree_block(
                                                struct btrfs_fs_info *fs_info,
                                                u64 bytenr);
index 5d54819aada7e0074be6cc843280f5d882ca2d8c..90f1ec0802bda18d5e7cfe3e13412e56e6090349 100644 (file)
@@ -5077,8 +5077,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
        if (!next) {
                if (reada && level == 1)
                        reada_walk_down(trans, root, wc, path);
-               next = read_tree_block(fs_info, bytenr, generation, level - 1,
-                                      &first_key);
+               next = read_tree_block(fs_info, bytenr, root->root_key.objectid,
+                                      generation, level - 1, &first_key);
                if (IS_ERR(next)) {
                        return PTR_ERR(next);
                } else if (!extent_buffer_uptodate(next)) {
index 8db99117531db723b7b137d96dd16a3eb14f9010..fe5e0026129d521041f78f08c8a5b83a54b7620a 100644 (file)
@@ -390,6 +390,7 @@ void btrfs_print_tree(struct extent_buffer *c, bool follow)
 
                btrfs_node_key_to_cpu(c, &first_key, i);
                next = read_tree_block(fs_info, btrfs_node_blockptr(c, i),
+                                      btrfs_header_owner(c),
                                       btrfs_node_ptr_generation(c, i),
                                       level - 1, &first_key);
                if (IS_ERR(next)) {
index 9ba1e62a65330a93c642a4491cea99fb4611a129..fe3046007f52abad65bcf437b1d22910574d6ff0 100644 (file)
@@ -4208,7 +4208,7 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
        spin_unlock(&blocks->lock);
 
        /* Read out reloc subtree root */
-       reloc_eb = read_tree_block(fs_info, block->reloc_bytenr,
+       reloc_eb = read_tree_block(fs_info, block->reloc_bytenr, 0,
                                   block->reloc_generation, block->level,
                                   &block->first_key);
        if (IS_ERR(reloc_eb)) {
index 9f80f5352dfdc012215b75ffe497a650de07182e..7ebada33502faab2c66af85bed7f3818eb008650 100644 (file)
@@ -2413,7 +2413,7 @@ static int get_tree_block_key(struct btrfs_fs_info *fs_info,
 {
        struct extent_buffer *eb;
 
-       eb = read_tree_block(fs_info, block->bytenr, block->key.offset,
+       eb = read_tree_block(fs_info, block->bytenr, 0, block->key.offset,
                             block->level, NULL);
        if (IS_ERR(eb)) {
                return PTR_ERR(eb);
@@ -3038,7 +3038,7 @@ int add_data_references(struct reloc_control *rc,
        while ((ref_node = ulist_next(leaves, &leaf_uiter))) {
                struct extent_buffer *eb;
 
-               eb = read_tree_block(fs_info, ref_node->val, 0, 0, NULL);
+               eb = read_tree_block(fs_info, ref_node->val, 0, 0, 0, NULL);
                if (IS_ERR(eb)) {
                        ret = PTR_ERR(eb);
                        break;