u64 system;
};
-static int make_root_dir(struct btrfs_root *root, int mixed,
- struct mkfs_allocation *allocation)
+static int create_metadata_block_groups(struct btrfs_root *root,
+ u64 metadata_profile, int mixed,
+ struct mkfs_allocation *allocation)
{
struct btrfs_trans_handle *trans;
- struct btrfs_key location;
u64 bytes_used;
u64 chunk_start = 0;
u64 chunk_size = 0;
root->fs_info->system_allocs = 1;
ret = btrfs_make_block_group(trans, root, bytes_used,
+ metadata_profile |
BTRFS_BLOCK_GROUP_SYSTEM,
BTRFS_FIRST_CHUNK_TREE_OBJECTID,
0, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
}
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root, 0,
+ metadata_profile |
BTRFS_BLOCK_GROUP_METADATA |
BTRFS_BLOCK_GROUP_DATA,
BTRFS_FIRST_CHUNK_TREE_OBJECTID,
}
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root, 0,
+ metadata_profile |
BTRFS_BLOCK_GROUP_METADATA,
BTRFS_FIRST_CHUNK_TREE_OBJECTID,
chunk_start, chunk_size);
root->fs_info->system_allocs = 0;
btrfs_commit_transaction(trans, root);
- trans = btrfs_start_transaction(root, 1);
- BUG_ON(!trans);
+
+err:
+ return ret;
+}
+
+static int create_data_block_groups(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 data_profile, int mixed,
+ struct mkfs_allocation *allocation)
+{
+ u64 chunk_start = 0;
+ u64 chunk_size = 0;
+ int ret = 0;
if (!mixed) {
ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
}
BUG_ON(ret);
ret = btrfs_make_block_group(trans, root, 0,
+ data_profile |
BTRFS_BLOCK_GROUP_DATA,
BTRFS_FIRST_CHUNK_TREE_OBJECTID,
chunk_start, chunk_size);
BUG_ON(ret);
}
+err:
+ return ret;
+}
+
+static int make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ int mixed, struct mkfs_allocation *allocation)
+{
+ struct btrfs_key location;
+ int ret;
+
ret = btrfs_make_root_dir(trans, root->fs_info->tree_root,
BTRFS_ROOT_TREE_DIR_OBJECTID);
if (ret)
if (ret)
goto err;
- btrfs_commit_transaction(trans, root);
err:
return ret;
}
static int create_raid_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 data_profile,
- int data_profile_opt, u64 metadata_profile,
- int mixed,
+ u64 metadata_profile, int mixed,
struct mkfs_allocation *allocation)
{
u64 num_devices = btrfs_super_num_devices(root->fs_info->super_copy);
u64 alloc_start = 0;
u64 metadata_profile = 0;
u64 data_profile = 0;
+ u64 default_metadata_profile = 0;
+ u64 default_data_profile = 0;
u32 nodesize = max_t(u32, sysconf(_SC_PAGESIZE),
BTRFS_MKFS_DEFAULT_NODE_SIZE);
u32 sectorsize = 4096;
}
root->fs_info->alloc_start = alloc_start;
- ret = make_root_dir(root, mixed, &allocation);
+ if (dev_cnt == 0) {
+ default_metadata_profile = metadata_profile;
+ default_data_profile = data_profile;
+ } else {
+ /*
+ * Temporary groups to store new device entries
+ */
+ default_metadata_profile = 0;
+ default_data_profile = 0;
+ }
+
+ ret = create_metadata_block_groups(root, default_metadata_profile,
+ mixed, &allocation);
+ if (ret) {
+ fprintf(stderr, "failed to create default block groups\n");
+ exit(1);
+ }
+
+ trans = btrfs_start_transaction(root, 1);
+ BUG_ON(!trans);
+
+ ret = create_data_block_groups(trans, root, default_data_profile,
+ mixed, &allocation);
+ if (ret) {
+ fprintf(stderr, "failed to create default data block groups\n");
+ exit(1);
+ }
+
+ ret = make_root_dir(trans, root, mixed, &allocation);
if (ret) {
fprintf(stderr, "failed to setup the root directory\n");
exit(1);
}
+ btrfs_commit_transaction(trans, root);
+
trans = btrfs_start_transaction(root, 1);
if (is_block_device(file))
btrfs_register_one_device(file);
if (dev_cnt == 0)
- goto raid_groups;
+ goto skip_multidev;
while (dev_cnt-- > 0) {
int old_mixed = mixed;
btrfs_register_one_device(file);
}
-raid_groups:
if (!source_dir_set) {
ret = create_raid_groups(trans, root, data_profile,
- data_profile_opt, metadata_profile,
- mixed, &allocation);
+ metadata_profile, mixed, &allocation);
BUG_ON(ret);
}
+skip_multidev:
ret = create_data_reloc_tree(trans, root);
BUG_ON(ret);