aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0007-Btrfs-progs-add-support-for-mixed-data-metadata-bloc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0007-Btrfs-progs-add-support-for-mixed-data-metadata-bloc.patch')
-rw-r--r--meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0007-Btrfs-progs-add-support-for-mixed-data-metadata-bloc.patch403
1 files changed, 403 insertions, 0 deletions
diff --git a/meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0007-Btrfs-progs-add-support-for-mixed-data-metadata-bloc.patch b/meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0007-Btrfs-progs-add-support-for-mixed-data-metadata-bloc.patch
new file mode 100644
index 0000000000..f533c5b0b4
--- /dev/null
+++ b/meta/recipes-devtools/btrfs-tools/btrfs-tools/upstream-tmp/0007-Btrfs-progs-add-support-for-mixed-data-metadata-bloc.patch
@@ -0,0 +1,403 @@
+Upstream-Status: Inappropriate [Backport]
+From e7ef1f26a25d06d5606934dced7b52f3e33f1d33 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@redhat.com>
+Date: Thu, 9 Dec 2010 18:31:08 +0000
+Subject: [PATCH 07/15] Btrfs-progs: add support for mixed data+metadata block groups
+
+So alot of crazy people (I'm looking at you Meego) want to use btrfs on phones
+and such with small devices. Unfortunately the way we split out metadata/data
+chunks it makes space usage inefficient for volumes that are smaller than
+1gigabyte. So add a -M option for mixing metadata+data, and default to this
+mixed mode if the filesystem is less than or equal to 1 gigabyte. I've tested
+this with xfstests on a 100mb filesystem and everything is a-ok.
+
+Signed-off-by: Josef Bacik <josef@redhat.com>
+Signed-off-by: Chris Mason <chris.mason@oracle.com>
+---
+ btrfs-vol.c | 4 +-
+ btrfs_cmds.c | 13 +++++-
+ ctree.h | 10 +++--
+ mkfs.c | 122 +++++++++++++++++++++++++++++++++++++++++-----------------
+ utils.c | 10 ++--
+ utils.h | 2 +-
+ 6 files changed, 112 insertions(+), 49 deletions(-)
+
+diff --git a/btrfs-vol.c b/btrfs-vol.c
+index 4ed799d..f573023 100644
+--- a/btrfs-vol.c
++++ b/btrfs-vol.c
+@@ -143,7 +143,9 @@ int main(int ac, char **av)
+ exit(1);
+ }
+ if (cmd == BTRFS_IOC_ADD_DEV) {
+- ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count);
++ int mixed = 0;
++
++ ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count, &mixed);
+ if (ret) {
+ fprintf(stderr, "Unable to init %s\n", device);
+ exit(1);
+diff --git a/btrfs_cmds.c b/btrfs_cmds.c
+index 775bfe1..c21a007 100644
+--- a/btrfs_cmds.c
++++ b/btrfs_cmds.c
+@@ -720,6 +720,7 @@ int do_add_volume(int nargs, char **args)
+ int devfd, res;
+ u64 dev_block_count = 0;
+ struct stat st;
++ int mixed = 0;
+
+ devfd = open(args[i], O_RDWR);
+ if (!devfd) {
+@@ -742,7 +743,7 @@ int do_add_volume(int nargs, char **args)
+ continue;
+ }
+
+- res = btrfs_prepare_device(devfd, args[i], 1, &dev_block_count);
++ res = btrfs_prepare_device(devfd, args[i], 1, &dev_block_count, &mixed);
+ if (res) {
+ fprintf(stderr, "ERROR: Unable to init '%s'\n", args[i]);
+ close(devfd);
+@@ -920,8 +921,14 @@ int do_df_filesystem(int nargs, char **argv)
+ memset(description, 0, 80);
+
+ if (flags & BTRFS_BLOCK_GROUP_DATA) {
+- snprintf(description, 5, "%s", "Data");
+- written += 4;
++ if (flags & BTRFS_BLOCK_GROUP_METADATA) {
++ snprintf(description, 15, "%s",
++ "Data+Metadata");
++ written += 14;
++ } else {
++ snprintf(description, 5, "%s", "Data");
++ written += 4;
++ }
+ } else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) {
+ snprintf(description, 7, "%s", "System");
+ written += 6;
+diff --git a/ctree.h b/ctree.h
+index 962c510..ed83d02 100644
+--- a/ctree.h
++++ b/ctree.h
+@@ -352,13 +352,15 @@ struct btrfs_super_block {
+ * ones specified below then we will fail to mount
+ */
+ #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
+-#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (2ULL << 0)
++#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
++#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
+
+ #define BTRFS_FEATURE_COMPAT_SUPP 0ULL
+ #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
+-#define BTRFS_FEATURE_INCOMPAT_SUPP \
+- (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
+- BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
++#define BTRFS_FEATURE_INCOMPAT_SUPP \
++ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
++ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \
++ BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
+
+ /*
+ * A leaf is full of items. offset and size tell us where to find
+diff --git a/mkfs.c b/mkfs.c
+index 2e99b95..04de93a 100644
+--- a/mkfs.c
++++ b/mkfs.c
+@@ -69,7 +69,7 @@ static u64 parse_size(char *s)
+ return atol(s) * mult;
+ }
+
+-static int make_root_dir(struct btrfs_root *root)
++static int make_root_dir(struct btrfs_root *root, int mixed)
+ {
+ struct btrfs_trans_handle *trans;
+ struct btrfs_key location;
+@@ -88,30 +88,47 @@ static int make_root_dir(struct btrfs_root *root)
+ 0, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
+ BUG_ON(ret);
+
+- ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
+- &chunk_start, &chunk_size,
+- BTRFS_BLOCK_GROUP_METADATA);
+- BUG_ON(ret);
+- ret = btrfs_make_block_group(trans, root, 0,
+- BTRFS_BLOCK_GROUP_METADATA,
+- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
+- chunk_start, chunk_size);
+- BUG_ON(ret);
++ if (mixed) {
++ ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
++ &chunk_start, &chunk_size,
++ BTRFS_BLOCK_GROUP_METADATA |
++ BTRFS_BLOCK_GROUP_DATA);
++ BUG_ON(ret);
++ ret = btrfs_make_block_group(trans, root, 0,
++ BTRFS_BLOCK_GROUP_METADATA |
++ BTRFS_BLOCK_GROUP_DATA,
++ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
++ chunk_start, chunk_size);
++ BUG_ON(ret);
++ printf("Created a data/metadata chunk of size %llu\n", chunk_size);
++ } else {
++ ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
++ &chunk_start, &chunk_size,
++ BTRFS_BLOCK_GROUP_METADATA);
++ BUG_ON(ret);
++ ret = btrfs_make_block_group(trans, root, 0,
++ BTRFS_BLOCK_GROUP_METADATA,
++ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
++ chunk_start, chunk_size);
++ BUG_ON(ret);
++ }
+
+ root->fs_info->system_allocs = 0;
+ btrfs_commit_transaction(trans, root);
+ trans = btrfs_start_transaction(root, 1);
+ BUG_ON(!trans);
+
+- ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
+- &chunk_start, &chunk_size,
+- BTRFS_BLOCK_GROUP_DATA);
+- BUG_ON(ret);
+- ret = btrfs_make_block_group(trans, root, 0,
+- BTRFS_BLOCK_GROUP_DATA,
+- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
+- chunk_start, chunk_size);
+- BUG_ON(ret);
++ if (!mixed) {
++ ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
++ &chunk_start, &chunk_size,
++ BTRFS_BLOCK_GROUP_DATA);
++ BUG_ON(ret);
++ ret = btrfs_make_block_group(trans, root, 0,
++ BTRFS_BLOCK_GROUP_DATA,
++ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
++ chunk_start, chunk_size);
++ BUG_ON(ret);
++ }
+
+ ret = btrfs_make_root_dir(trans, root->fs_info->tree_root,
+ BTRFS_ROOT_TREE_DIR_OBJECTID);
+@@ -200,7 +217,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,
+- u64 metadata_profile)
++ u64 metadata_profile, int mixed)
+ {
+ u64 num_devices = btrfs_super_num_devices(&root->fs_info->super_copy);
+ u64 allowed;
+@@ -215,20 +232,24 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
+ allowed = BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1;
+
+ if (allowed & metadata_profile) {
++ u64 meta_flags = BTRFS_BLOCK_GROUP_METADATA;
++
+ ret = create_one_raid_group(trans, root,
+ BTRFS_BLOCK_GROUP_SYSTEM |
+ (allowed & metadata_profile));
+ BUG_ON(ret);
+
+- ret = create_one_raid_group(trans, root,
+- BTRFS_BLOCK_GROUP_METADATA |
++ if (mixed)
++ meta_flags |= BTRFS_BLOCK_GROUP_DATA;
++
++ ret = create_one_raid_group(trans, root, meta_flags |
+ (allowed & metadata_profile));
+ BUG_ON(ret);
+
+ ret = recow_roots(trans, root);
+ BUG_ON(ret);
+ }
+- if (num_devices > 1 && (allowed & data_profile)) {
++ if (!mixed && num_devices > 1 && (allowed & data_profile)) {
+ ret = create_one_raid_group(trans, root,
+ BTRFS_BLOCK_GROUP_DATA |
+ (allowed & data_profile));
+@@ -274,6 +295,7 @@ static void print_usage(void)
+ fprintf(stderr, "\t -l --leafsize size of btree leaves\n");
+ fprintf(stderr, "\t -L --label set a label\n");
+ fprintf(stderr, "\t -m --metadata metadata profile, values like data profile\n");
++ fprintf(stderr, "\t -M --mixed mix metadata and data together\n");
+ fprintf(stderr, "\t -n --nodesize size of btree nodes\n");
+ fprintf(stderr, "\t -s --sectorsize min block allocation\n");
+ fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
+@@ -328,6 +350,7 @@ static struct option long_options[] = {
+ { "leafsize", 1, NULL, 'l' },
+ { "label", 1, NULL, 'L'},
+ { "metadata", 1, NULL, 'm' },
++ { "mixed", 0, NULL, 'M' },
+ { "nodesize", 1, NULL, 'n' },
+ { "sectorsize", 1, NULL, 's' },
+ { "data", 1, NULL, 'd' },
+@@ -358,10 +381,13 @@ int main(int ac, char **av)
+ int first_fd;
+ int ret;
+ int i;
++ int mixed = 0;
++ int data_profile_opt = 0;
++ int metadata_profile_opt = 0;
+
+ while(1) {
+ int c;
+- c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:V", long_options,
++ c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:VM", long_options,
+ &option_index);
+ if (c < 0)
+ break;
+@@ -371,6 +397,7 @@ int main(int ac, char **av)
+ break;
+ case 'd':
+ data_profile = parse_profile(optarg);
++ data_profile_opt = 1;
+ break;
+ case 'l':
+ leafsize = parse_size(optarg);
+@@ -380,6 +407,10 @@ int main(int ac, char **av)
+ break;
+ case 'm':
+ metadata_profile = parse_profile(optarg);
++ metadata_profile_opt = 1;
++ break;
++ case 'M':
++ mixed = 1;
+ break;
+ case 'n':
+ nodesize = parse_size(optarg);
+@@ -389,12 +420,10 @@ int main(int ac, char **av)
+ break;
+ case 'b':
+ block_count = parse_size(optarg);
+- if (block_count < 256*1024*1024) {
+- fprintf(stderr, "File system size "
+- "%llu bytes is too small, "
+- "256M is required at least\n",
+- (unsigned long long)block_count);
+- exit(1);
++ if (block_count <= 1024*1024*1024) {
++ printf("SMALL VOLUME: forcing mixed "
++ "metadata/data groups\n");
++ mixed = 1;
+ }
+ zero_end = 0;
+ break;
+@@ -439,9 +468,22 @@ int main(int ac, char **av)
+ }
+ first_fd = fd;
+ first_file = file;
+- ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count);
++ ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count,
++ &mixed);
+ if (block_count == 0)
+ block_count = dev_block_count;
++ if (mixed) {
++ if (!metadata_profile_opt)
++ metadata_profile = 0;
++ if (!data_profile_opt)
++ data_profile = 0;
++
++ if (metadata_profile != data_profile) {
++ fprintf(stderr, "With mixed block groups data and metadata "
++ "profiles must be the same\n");
++ exit(1);
++ }
++ }
+
+ blocks[0] = BTRFS_SUPER_INFO_OFFSET;
+ for (i = 1; i < 7; i++) {
+@@ -459,7 +501,7 @@ int main(int ac, char **av)
+ root = open_ctree(file, 0, O_RDWR);
+ root->fs_info->alloc_start = alloc_start;
+
+- ret = make_root_dir(root);
++ ret = make_root_dir(root, mixed);
+ if (ret) {
+ fprintf(stderr, "failed to setup the root directory\n");
+ exit(1);
+@@ -478,6 +520,8 @@ int main(int ac, char **av)
+
+ zero_end = 1;
+ while(ac-- > 0) {
++ int old_mixed = mixed;
++
+ file = av[optind++];
+ ret = check_mounted(file);
+ if (ret < 0) {
+@@ -503,8 +547,8 @@ int main(int ac, char **av)
+ continue;
+ }
+ ret = btrfs_prepare_device(fd, file, zero_end,
+- &dev_block_count);
+-
++ &dev_block_count, &mixed);
++ mixed = old_mixed;
+ BUG_ON(ret);
+
+ ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count,
+@@ -515,12 +559,20 @@ int main(int ac, char **av)
+
+ raid_groups:
+ ret = create_raid_groups(trans, root, data_profile,
+- metadata_profile);
++ metadata_profile, mixed);
+ BUG_ON(ret);
+
+ ret = create_data_reloc_tree(trans, root);
+ BUG_ON(ret);
+
++ if (mixed) {
++ struct btrfs_super_block *super = &root->fs_info->super_copy;
++ u64 flags = btrfs_super_incompat_flags(super);
++
++ flags |= BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS;
++ btrfs_set_super_incompat_flags(super, flags);
++ }
++
+ printf("fs created label %s on %s\n\tnodesize %u leafsize %u "
+ "sectorsize %u size %s\n",
+ label, first_file, nodesize, leafsize, sectorsize,
+diff --git a/utils.c b/utils.c
+index 35e17b8..ad980ae 100644
+--- a/utils.c
++++ b/utils.c
+@@ -512,7 +512,8 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
+ return 0;
+ }
+
+-int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret)
++int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
++ int *mixed)
+ {
+ u64 block_count;
+ u64 bytenr;
+@@ -532,10 +533,9 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret)
+ }
+ zero_end = 1;
+
+- if (block_count < 256 * 1024 * 1024) {
+- fprintf(stderr, "device %s is too small "
+- "(must be at least 256 MB)\n", file);
+- exit(1);
++ if (block_count < 1024 * 1024 * 1024 && !(*mixed)) {
++ printf("SMALL VOLUME: forcing mixed metadata/data groups\n");
++ *mixed = 1;
+ }
+ ret = zero_dev_start(fd);
+ if (ret) {
+diff --git a/utils.h b/utils.h
+index 9dce5b0..a28d7f4 100644
+--- a/utils.h
++++ b/utils.h
+@@ -27,7 +27,7 @@ int make_btrfs(int fd, const char *device, const char *label,
+ int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, u64 objectid);
+ int btrfs_prepare_device(int fd, char *file, int zero_end,
+- u64 *block_count_ret);
++ u64 *block_count_ret, int *mixed);
+ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, int fd, char *path,
+ u64 block_count, u32 io_width, u32 io_align,
+--
+1.7.2.3
+