btrfs-progs: mkfs: create the global root's

Now that we have all of the supporting code, add the ability to create
all of the global roots for an extent tree v2 fs.  This will default to
nr_cpu's, but also allow the user to specify how many global roots they
would like.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Josef Bacik 2022-03-07 17:11:03 -05:00 committed by David Sterba
parent 1f89a5d461
commit 659f041537

View File

@ -810,6 +810,53 @@ out:
return ret;
}
static int create_global_root(struct btrfs_trans_handle *trans, u64 objectid,
int root_id)
{
struct btrfs_fs_info *fs_info = trans->fs_info;
struct btrfs_root *root;
struct btrfs_key key = {
.objectid = objectid,
.type = BTRFS_ROOT_ITEM_KEY,
.offset = root_id,
};
int ret = 0;
root = btrfs_create_tree(trans, fs_info, &key);
if (IS_ERR(root)) {
ret = PTR_ERR(root);
goto out;
}
ret = btrfs_global_root_insert(fs_info, root);
out:
if (ret)
btrfs_abort_transaction(trans, ret);
return ret;
}
static int create_global_roots(struct btrfs_trans_handle *trans,
int nr_global_roots)
{
int ret, i;
for (i = 1; i < nr_global_roots; i++) {
ret = create_global_root(trans, BTRFS_EXTENT_TREE_OBJECTID, i);
if (ret)
return ret;
ret = create_global_root(trans, BTRFS_CSUM_TREE_OBJECTID, i);
if (ret)
return ret;
ret = create_global_root(trans, BTRFS_FREE_SPACE_TREE_OBJECTID, i);
if (ret)
return ret;
}
btrfs_set_super_nr_global_roots(trans->fs_info->super_copy,
nr_global_roots);
return 0;
}
static int insert_qgroup_items(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info,
u64 qgroupid)
@ -966,13 +1013,18 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
struct btrfs_mkfs_config mkfs_cfg;
enum btrfs_csum_type csum_type = BTRFS_CSUM_TYPE_CRC32;
u64 system_group_size;
int nr_global_roots = sysconf(_SC_NPROCESSORS_ONLN);
crc32c_optimization_init();
btrfs_config_init();
while(1) {
int c;
enum { GETOPT_VAL_SHRINK = 257, GETOPT_VAL_CHECKSUM };
enum {
GETOPT_VAL_SHRINK = 257,
GETOPT_VAL_CHECKSUM,
GETOPT_VAL_GLOBAL_ROOTS,
};
static const struct option long_options[] = {
{ "byte-count", required_argument, NULL, 'b' },
{ "csum", required_argument, NULL,
@ -996,6 +1048,9 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
{ "quiet", 0, NULL, 'q' },
{ "verbose", 0, NULL, 'v' },
{ "shrink", no_argument, NULL, GETOPT_VAL_SHRINK },
#if EXPERIMENTAL
{ "num-global-roots", required_argument, NULL, GETOPT_VAL_GLOBAL_ROOTS },
#endif
{ "help", no_argument, NULL, GETOPT_VAL_HELP },
{ NULL, 0, NULL, 0}
};
@ -1100,6 +1155,9 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
case GETOPT_VAL_CHECKSUM:
csum_type = parse_csum_type(optarg);
break;
case GETOPT_VAL_GLOBAL_ROOTS:
nr_global_roots = (int)arg_strtou64(optarg);
break;
case GETOPT_VAL_HELP:
default:
print_usage(c != GETOPT_VAL_HELP);
@ -1239,6 +1297,11 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
if (features & BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2) {
features |= BTRFS_FEATURE_INCOMPAT_NO_HOLES;
runtime_features |= BTRFS_RUNTIME_FEATURE_FREE_SPACE_TREE;
if (!nr_global_roots) {
error("you must set a non-zero num-global-roots value");
exit(1);
}
}
if (zoned) {
@ -1467,6 +1530,14 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
goto error;
}
if (features & BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2) {
ret = create_global_roots(trans, nr_global_roots);
if (ret) {
error("failed to create global roots: %d", ret);
goto error;
}
}
ret = make_root_dir(trans, root);
if (ret) {
error("failed to setup the root directory: %d", ret);