btrfs-progs: mkfs: create only desired block groups for single device

The filesystem creation has to solve some chicken-egg problems and
creates some temporary objects. In our case it's an extra single/single
pair of block groups that's not used unless the user asks that
explicitly.

Example:

Data, single: total=8.00MiB, used=64.00KiB
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=153.56MiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=16.00MiB, used=0.00B

Even with a single device filesystem and defaults, there's single
block group for metadata and system. The single device case is easy to
fix, we'll simply create the right type from the beginning.

Example:

Data, single: total=8.00MiB, used=64.00KiB
System, DUP: total=4.00MiB, used=16.00KiB
Metadata, DUP: total=136.00MiB, used=112.00KiB
GlobalReserve, single: total=16.00MiB, used=0.00B

Filesystem on top of multiple devices still leaves the single/single
groups behind.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2015-07-03 00:15:18 +02:00
parent 9ec25f25fc
commit 5f8232e5c8

34
mkfs.c
View File

@ -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);
@ -122,7 +126,7 @@ err:
}
static int create_data_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int mixed,
struct btrfs_root *root, u64 data_profile, int mixed,
struct mkfs_allocation *allocation)
{
u64 chunk_start = 0;
@ -139,6 +143,7 @@ static int create_data_block_groups(struct btrfs_trans_handle *trans,
}
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);
@ -1189,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;
@ -1547,7 +1554,19 @@ 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);
@ -1556,7 +1575,8 @@ int main(int ac, char **av)
trans = btrfs_start_transaction(root, 1);
BUG_ON(!trans);
ret = create_data_block_groups(trans, root, mixed, &allocation);
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);
@ -1576,7 +1596,7 @@ int main(int ac, char **av)
btrfs_register_one_device(file);
if (dev_cnt == 0)
goto raid_groups;
goto skip_multidev;
while (dev_cnt-- > 0) {
int old_mixed = mixed;
@ -1626,12 +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,
metadata_profile, mixed, &allocation);
BUG_ON(ret);
}
skip_multidev:
ret = create_data_reloc_tree(trans, root);
BUG_ON(ret);