btrfs-progs: extent-tree: Introduce functions to free in-memory block group cache
[platform/upstream/btrfs-progs.git] / mkfs.c
diff --git a/mkfs.c b/mkfs.c
index 084dd27..b60fc5a 100644 (file)
--- a/mkfs.c
+++ b/mkfs.c
@@ -59,8 +59,9 @@ struct mkfs_allocation {
        u64 system;
 };
 
-static int create_metadata_block_groups(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;
        u64 bytes_used;
@@ -73,6 +74,7 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
 
        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);
@@ -91,6 +93,7 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
                }
                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,
@@ -107,6 +110,7 @@ static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
                }
                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);
@@ -121,17 +125,13 @@ err:
        return ret;
 }
 
-static int make_root_dir(struct btrfs_root *root, int mixed,
-                               struct mkfs_allocation *allocation)
+static int create_data_block_groups(struct btrfs_trans_handle *trans,
+               struct btrfs_root *root, u64 data_profile, int mixed,
+               struct mkfs_allocation *allocation)
 {
-       struct btrfs_trans_handle *trans;
-       struct btrfs_key location;
        u64 chunk_start = 0;
        u64 chunk_size = 0;
-       int ret;
-
-       trans = btrfs_start_transaction(root, 1);
-       BUG_ON(!trans);
+       int ret = 0;
 
        if (!mixed) {
                ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
@@ -143,6 +143,7 @@ static int make_root_dir(struct btrfs_root *root, int mixed,
                }
                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);
@@ -150,6 +151,16 @@ static int make_root_dir(struct btrfs_root *root, int mixed,
                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)
@@ -172,7 +183,6 @@ static int make_root_dir(struct btrfs_root *root, int mixed,
        if (ret)
                goto err;
 
-       btrfs_commit_transaction(trans, root);
 err:
        return ret;
 }
@@ -242,8 +252,7 @@ static int create_one_raid_group(struct btrfs_trans_handle *trans,
 
 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);
@@ -1185,6 +1194,8 @@ int main(int ac, char **av)
        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;
@@ -1543,25 +1554,49 @@ int main(int ac, char **av)
        }
        root->fs_info->alloc_start = alloc_start;
 
-       ret = create_metadata_block_groups(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);
        }
 
-       ret = make_root_dir(root, mixed, &allocation);
+       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;
@@ -1611,13 +1646,12 @@ int main(int ac, char **av)
                        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);