btrfs: abstract out loading the tree root
authorJosef Bacik <josef@toxicpanda.com>
Wed, 15 Dec 2021 20:40:06 +0000 (15:40 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 14 Mar 2022 12:13:48 +0000 (13:13 +0100)
We're going to be adding more roots that need to be loaded from the
super block, so abstract out the code to read the tree_root from the
super block, and use this helper for the chunk root as well.  This will
make it simpler to load the new trees in the future.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c

index 48590a3..e014cb8 100644 (file)
@@ -2930,6 +2930,45 @@ out:
        return ret;
 }
 
+static int load_super_root(struct btrfs_root *root, u64 bytenr, u64 gen, int level)
+{
+       int ret = 0;
+
+       root->node = read_tree_block(root->fs_info, bytenr,
+                                    root->root_key.objectid, gen, level, NULL);
+       if (IS_ERR(root->node)) {
+               ret = PTR_ERR(root->node);
+               root->node = NULL;
+       } else if (!extent_buffer_uptodate(root->node)) {
+               free_extent_buffer(root->node);
+               root->node = NULL;
+               ret = -EIO;
+       }
+
+       if (ret)
+               return ret;
+
+       btrfs_set_root_node(&root->root_item, root->node);
+       root->commit_root = btrfs_root_node(root);
+       btrfs_set_root_refs(&root->root_item, 1);
+       return ret;
+}
+
+static int load_important_roots(struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_super_block *sb = fs_info->super_copy;
+       u64 gen, bytenr;
+       int level, ret;
+
+       bytenr = btrfs_super_root(sb);
+       gen = btrfs_super_generation(sb);
+       level = btrfs_super_root_level(sb);
+       ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
+       if (ret)
+               btrfs_warn(fs_info, "couldn't read tree root");
+       return ret;
+}
+
 static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 {
        int backup_index = find_newest_super_backup(fs_info);
@@ -2940,9 +2979,6 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
        int i;
 
        for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
-               u64 generation;
-               int level;
-
                if (handle_error) {
                        if (!IS_ERR(tree_root->node))
                                free_extent_buffer(tree_root->node);
@@ -2967,29 +3003,13 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
                        if (ret < 0)
                                return ret;
                }
-               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;
-                       ret = PTR_ERR(tree_root->node);
-                       tree_root->node = NULL;
-                       btrfs_warn(fs_info, "couldn't read tree root");
-                       continue;
 
-               } else if (!extent_buffer_uptodate(tree_root->node)) {
+               ret = load_important_roots(fs_info);
+               if (ret) {
                        handle_error = true;
-                       ret = -EIO;
-                       btrfs_warn(fs_info, "error while reading tree root");
                        continue;
                }
 
-               btrfs_set_root_node(&tree_root->root_item, tree_root->node);
-               tree_root->commit_root = btrfs_root_node(tree_root);
-               btrfs_set_root_refs(&tree_root->root_item, 1);
-
                /*
                 * No need to hold btrfs_root::objectid_mutex since the fs
                 * hasn't been fully initialised and we are the only user
@@ -3009,8 +3029,8 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
                }
 
                /* All successful */
-               fs_info->generation = generation;
-               fs_info->last_trans_committed = generation;
+               fs_info->generation = btrfs_header_generation(tree_root->node);
+               fs_info->last_trans_committed = fs_info->generation;
                fs_info->last_reloc_trans = 0;
 
                /* Always begin writing backup roots after the one being used */
@@ -3594,21 +3614,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 
        generation = btrfs_super_chunk_root_generation(disk_super);
        level = btrfs_super_chunk_root_level(disk_super);
-
-       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)) {
+       ret = load_super_root(chunk_root, btrfs_super_chunk_root(disk_super),
+                             generation, level);
+       if (ret) {
                btrfs_err(fs_info, "failed to read chunk root");
-               if (!IS_ERR(chunk_root->node))
-                       free_extent_buffer(chunk_root->node);
-               chunk_root->node = NULL;
                goto fail_tree_roots;
        }
-       btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
-       chunk_root->commit_root = btrfs_root_node(chunk_root);
 
        read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
                           offsetof(struct btrfs_header, chunk_tree_uuid),