OSDN Git Service

btrfs: add code to support the block group root
authorJosef Bacik <josef@toxicpanda.com>
Wed, 15 Dec 2021 20:40:07 +0000 (15:40 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 14 Mar 2022 12:13:48 +0000 (13:13 +0100)
This code adds the on disk structures for the block group root, which
will hold the block group items for extent tree v2.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/print-tree.c
include/trace/events/btrfs.h
include/uapi/linux/btrfs_tree.h

index 54424b3..f460a7b 100644 (file)
@@ -274,8 +274,14 @@ struct btrfs_super_block {
        /* the UUID written into btree blocks */
        u8 metadata_uuid[BTRFS_FSID_SIZE];
 
+       /* Extent tree v2 */
+       __le64 block_group_root;
+       __le64 block_group_root_generation;
+       u8 block_group_root_level;
+
        /* future expansion */
-       __le64 reserved[28];
+       u8 reserved8[7];
+       __le64 reserved[25];
        u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
        struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
 
@@ -657,6 +663,7 @@ struct btrfs_fs_info {
        struct btrfs_root *quota_root;
        struct btrfs_root *uuid_root;
        struct btrfs_root *data_reloc_root;
+       struct btrfs_root *block_group_root;
 
        /* the log root tree is a directory of all the other log roots */
        struct btrfs_root *log_root_tree;
@@ -2349,6 +2356,17 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup,
 BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup,
                   num_devices, 64);
 
+/*
+ * For extent tree v2 we overload the extent root with the block group root, as
+ * we will have multiple extent roots.
+ */
+BTRFS_SETGET_STACK_FUNCS(backup_block_group_root, struct btrfs_root_backup,
+                        extent_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_gen, struct btrfs_root_backup,
+                        extent_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_level,
+                        struct btrfs_root_backup, extent_root_level, 8);
+
 /* struct btrfs_balance_item */
 BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64);
 
@@ -2483,6 +2501,13 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
 BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64);
 BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
                         uuid_tree_generation, 64);
+BTRFS_SETGET_STACK_FUNCS(super_block_group_root, struct btrfs_super_block,
+                        block_group_root, 64);
+BTRFS_SETGET_STACK_FUNCS(super_block_group_root_generation,
+                        struct btrfs_super_block,
+                        block_group_root_generation, 64);
+BTRFS_SETGET_STACK_FUNCS(super_block_group_root_level, struct btrfs_super_block,
+                        block_group_root_level, 8);
 
 int btrfs_super_csum_size(const struct btrfs_super_block *s);
 const char *btrfs_super_csum_name(u16 csum_type);
index e014cb8..fe13497 100644 (file)
@@ -1727,6 +1727,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
        btrfs_put_root(fs_info->uuid_root);
        btrfs_put_root(fs_info->fs_root);
        btrfs_put_root(fs_info->data_reloc_root);
+       btrfs_put_root(fs_info->block_group_root);
        btrfs_check_leaked_roots(fs_info);
        btrfs_extent_buffer_leak_debug_check(fs_info);
        kfree(fs_info->super_copy);
@@ -2095,7 +2096,6 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 {
        const int next_backup = info->backup_root_index;
        struct btrfs_root_backup *root_backup;
-       struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
        struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
 
        root_backup = info->super_for_commit->super_roots + next_backup;
@@ -2121,11 +2121,23 @@ static void backup_super_roots(struct btrfs_fs_info *info)
        btrfs_set_backup_chunk_root_level(root_backup,
                               btrfs_header_level(info->chunk_root->node));
 
-       btrfs_set_backup_extent_root(root_backup, extent_root->node->start);
-       btrfs_set_backup_extent_root_gen(root_backup,
-                              btrfs_header_generation(extent_root->node));
-       btrfs_set_backup_extent_root_level(root_backup,
-                              btrfs_header_level(extent_root->node));
+       if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+               btrfs_set_backup_block_group_root(root_backup,
+                                       info->block_group_root->node->start);
+               btrfs_set_backup_block_group_root_gen(root_backup,
+                       btrfs_header_generation(info->block_group_root->node));
+               btrfs_set_backup_block_group_root_level(root_backup,
+                       btrfs_header_level(info->block_group_root->node));
+       } else {
+               struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+
+               btrfs_set_backup_extent_root(root_backup,
+                                            extent_root->node->start);
+               btrfs_set_backup_extent_root_gen(root_backup,
+                               btrfs_header_generation(extent_root->node));
+               btrfs_set_backup_extent_root_level(root_backup,
+                                       btrfs_header_level(extent_root->node));
+       }
 
        /*
         * we might commit during log recovery, which happens before we set
@@ -2269,6 +2281,7 @@ static void free_root_pointers(struct btrfs_fs_info *info, bool free_chunk_root)
        free_root_extent_buffers(info->uuid_root);
        free_root_extent_buffers(info->fs_root);
        free_root_extent_buffers(info->data_reloc_root);
+       free_root_extent_buffers(info->block_group_root);
        if (free_chunk_root)
                free_root_extent_buffers(info->chunk_root);
 }
@@ -2964,8 +2977,20 @@ static int load_important_roots(struct btrfs_fs_info *fs_info)
        gen = btrfs_super_generation(sb);
        level = btrfs_super_root_level(sb);
        ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
-       if (ret)
+       if (ret) {
                btrfs_warn(fs_info, "couldn't read tree root");
+               return ret;
+       }
+
+       if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+               return 0;
+
+       bytenr = btrfs_super_block_group_root(sb);
+       gen = btrfs_super_block_group_root_generation(sb);
+       level = btrfs_super_block_group_root_level(sb);
+       ret = load_super_root(fs_info->block_group_root, bytenr, gen, level);
+       if (ret)
+               btrfs_warn(fs_info, "couldn't read block group root");
        return ret;
 }
 
@@ -2978,6 +3003,16 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
        int ret = 0;
        int i;
 
+       if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+               struct btrfs_root *root;
+
+               root = btrfs_alloc_root(fs_info, BTRFS_BLOCK_GROUP_TREE_OBJECTID,
+                                       GFP_KERNEL);
+               if (!root)
+                       return -ENOMEM;
+               fs_info->block_group_root = root;
+       }
+
        for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
                if (handle_error) {
                        if (!IS_ERR(tree_root->node))
index 5e8bef4..2e10514 100644 (file)
@@ -111,6 +111,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
 
 static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info)
 {
+       if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+               return fs_info->block_group_root;
        return btrfs_extent_root(fs_info, 0);
 }
 
index 0775ae9..524fdb0 100644 (file)
@@ -23,6 +23,7 @@ static const struct root_name_map root_map[] = {
        { BTRFS_QUOTA_TREE_OBJECTID,            "QUOTA_TREE"            },
        { BTRFS_UUID_TREE_OBJECTID,             "UUID_TREE"             },
        { BTRFS_FREE_SPACE_TREE_OBJECTID,       "FREE_SPACE_TREE"       },
+       { BTRFS_BLOCK_GROUP_TREE_OBJECTID,      "BLOCK_GROUP_TREE"      },
        { BTRFS_DATA_RELOC_TREE_OBJECTID,       "DATA_RELOC_TREE"       },
 };
 
index 0d72966..f068ff3 100644 (file)
@@ -53,6 +53,7 @@ struct btrfs_space_info;
                { BTRFS_TREE_RELOC_OBJECTID,    "TREE_RELOC"    },      \
                { BTRFS_UUID_TREE_OBJECTID,     "UUID_TREE"     },      \
                { BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" },  \
+               { BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" },\
                { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" })
 
 #define show_root_type(obj)                                            \
index 5416f1f..b069752 100644 (file)
@@ -53,6 +53,9 @@
 /* tracks free space in block groups. */
 #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
 
+/* Holds the block group items for extent tree v2. */
+#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL
+
 /* device stats in the device tree */
 #define BTRFS_DEV_STATS_OBJECTID 0ULL