@@ -188,6 +188,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
u64 num_bytes;
u64 system_group_offset = BTRFS_BLOCK_RESERVED_1M_FOR_SUPER;
u64 system_group_size = BTRFS_MKFS_SYSTEM_GROUP_SIZE;
+ bool add_block_group = true;
if ((cfg->features & BTRFS_FEATURE_INCOMPAT_ZONED)) {
system_group_offset = cfg->zone_size * BTRFS_NR_SB_LOG_ZONES;
@@ -276,6 +277,36 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
for (i = 0; i < blocks_nr; i++) {
blk = blocks[i];
+ /* Add the block group item for our temporary chunk. */
+ if (cfg->blocks[blk] > system_group_offset &&
+ add_block_group) {
+ struct btrfs_block_group_item *bg_item;
+
+ add_block_group = false;
+
+ itemoff -= sizeof(*bg_item);
+ btrfs_set_disk_key_objectid(&disk_key,
+ system_group_offset);
+ btrfs_set_disk_key_offset(&disk_key,
+ system_group_size);
+ btrfs_set_disk_key_type(&disk_key,
+ BTRFS_BLOCK_GROUP_ITEM_KEY);
+ btrfs_set_item_key(buf, &disk_key, nritems);
+ btrfs_set_item_offset(buf, btrfs_item_nr(nritems),
+ itemoff);
+ btrfs_set_item_size(buf, btrfs_item_nr(nritems),
+ sizeof(*bg_item));
+
+ bg_item = btrfs_item_ptr(buf, nritems,
+ struct btrfs_block_group_item);
+ btrfs_set_block_group_used(buf, bg_item, total_used);
+ btrfs_set_block_group_flags(buf, bg_item,
+ BTRFS_BLOCK_GROUP_SYSTEM);
+ btrfs_set_block_group_chunk_objectid(buf, bg_item,
+ BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+ nritems++;
+ }
+
item_size = sizeof(struct btrfs_extent_item);
if (!skinny_metadata)
item_size += sizeof(struct btrfs_tree_block_info);
@@ -67,7 +67,6 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
struct btrfs_trans_handle *trans;
struct btrfs_space_info *sinfo;
u64 flags = BTRFS_BLOCK_GROUP_METADATA;
- u64 bytes_used;
u64 chunk_start = 0;
u64 chunk_size = 0;
u64 system_group_offset = BTRFS_BLOCK_RESERVED_1M_FOR_SUPER;
@@ -90,16 +89,12 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
trans = btrfs_start_transaction(root, 1);
BUG_ON(IS_ERR(trans));
- bytes_used = btrfs_super_bytes_used(fs_info->super_copy);
root->fs_info->system_allocs = 1;
/*
- * First temporary system chunk must match the chunk layout
- * created in make_btrfs().
+ * We already created the block group item for our temporary system
+ * chunk in make_btrfs(), so account for the size here.
*/
- ret = btrfs_make_block_group(trans, fs_info, bytes_used,
- BTRFS_BLOCK_GROUP_SYSTEM,
- system_group_offset, system_group_size);
allocation->system += system_group_size;
if (ret)
return ret;
Currently we build a bare-bones file system in make_btrfs(), and then we load it up and fill in the rest of the file system after the fact. One thing we omit in make_btrfs() is the block group item for the temporary system chunk we allocate, because we just add it after we've opened the file system. However I want to be able to generate the free space tree at make_btrfs() time, because extent tree v2 will not have an extent tree that has every block allocated in the system. In order to do this I need to make sure that the free space tree entries are added on block group creation, which is annoying if we have to add this chunk after I've created a free space tree. So make future work simpler by simply adding our block group item at make_btrfs() time, this way I can do the right things with the free space tree in the generic make block group code without needing a special case for our temporary system chunk. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- mkfs/common.c | 31 +++++++++++++++++++++++++++++++ mkfs/main.c | 9 ++------- 2 files changed, 33 insertions(+), 7 deletions(-)