summaryrefslogtreecommitdiffstats
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 @@
1Upstream-Status: Inappropriate [Backport]
2From e7ef1f26a25d06d5606934dced7b52f3e33f1d33 Mon Sep 17 00:00:00 2001
3From: Josef Bacik <josef@redhat.com>
4Date: Thu, 9 Dec 2010 18:31:08 +0000
5Subject: [PATCH 07/15] Btrfs-progs: add support for mixed data+metadata block groups
6
7So alot of crazy people (I'm looking at you Meego) want to use btrfs on phones
8and such with small devices. Unfortunately the way we split out metadata/data
9chunks it makes space usage inefficient for volumes that are smaller than
101gigabyte. So add a -M option for mixing metadata+data, and default to this
11mixed mode if the filesystem is less than or equal to 1 gigabyte. I've tested
12this with xfstests on a 100mb filesystem and everything is a-ok.
13
14Signed-off-by: Josef Bacik <josef@redhat.com>
15Signed-off-by: Chris Mason <chris.mason@oracle.com>
16---
17 btrfs-vol.c | 4 +-
18 btrfs_cmds.c | 13 +++++-
19 ctree.h | 10 +++--
20 mkfs.c | 122 +++++++++++++++++++++++++++++++++++++++++-----------------
21 utils.c | 10 ++--
22 utils.h | 2 +-
23 6 files changed, 112 insertions(+), 49 deletions(-)
24
25diff --git a/btrfs-vol.c b/btrfs-vol.c
26index 4ed799d..f573023 100644
27--- a/btrfs-vol.c
28+++ b/btrfs-vol.c
29@@ -143,7 +143,9 @@ int main(int ac, char **av)
30 exit(1);
31 }
32 if (cmd == BTRFS_IOC_ADD_DEV) {
33- ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count);
34+ int mixed = 0;
35+
36+ ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count, &mixed);
37 if (ret) {
38 fprintf(stderr, "Unable to init %s\n", device);
39 exit(1);
40diff --git a/btrfs_cmds.c b/btrfs_cmds.c
41index 775bfe1..c21a007 100644
42--- a/btrfs_cmds.c
43+++ b/btrfs_cmds.c
44@@ -720,6 +720,7 @@ int do_add_volume(int nargs, char **args)
45 int devfd, res;
46 u64 dev_block_count = 0;
47 struct stat st;
48+ int mixed = 0;
49
50 devfd = open(args[i], O_RDWR);
51 if (!devfd) {
52@@ -742,7 +743,7 @@ int do_add_volume(int nargs, char **args)
53 continue;
54 }
55
56- res = btrfs_prepare_device(devfd, args[i], 1, &dev_block_count);
57+ res = btrfs_prepare_device(devfd, args[i], 1, &dev_block_count, &mixed);
58 if (res) {
59 fprintf(stderr, "ERROR: Unable to init '%s'\n", args[i]);
60 close(devfd);
61@@ -920,8 +921,14 @@ int do_df_filesystem(int nargs, char **argv)
62 memset(description, 0, 80);
63
64 if (flags & BTRFS_BLOCK_GROUP_DATA) {
65- snprintf(description, 5, "%s", "Data");
66- written += 4;
67+ if (flags & BTRFS_BLOCK_GROUP_METADATA) {
68+ snprintf(description, 15, "%s",
69+ "Data+Metadata");
70+ written += 14;
71+ } else {
72+ snprintf(description, 5, "%s", "Data");
73+ written += 4;
74+ }
75 } else if (flags & BTRFS_BLOCK_GROUP_SYSTEM) {
76 snprintf(description, 7, "%s", "System");
77 written += 6;
78diff --git a/ctree.h b/ctree.h
79index 962c510..ed83d02 100644
80--- a/ctree.h
81+++ b/ctree.h
82@@ -352,13 +352,15 @@ struct btrfs_super_block {
83 * ones specified below then we will fail to mount
84 */
85 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
86-#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (2ULL << 0)
87+#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
88+#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
89
90 #define BTRFS_FEATURE_COMPAT_SUPP 0ULL
91 #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
92-#define BTRFS_FEATURE_INCOMPAT_SUPP \
93- (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
94- BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)
95+#define BTRFS_FEATURE_INCOMPAT_SUPP \
96+ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
97+ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \
98+ BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
99
100 /*
101 * A leaf is full of items. offset and size tell us where to find
102diff --git a/mkfs.c b/mkfs.c
103index 2e99b95..04de93a 100644
104--- a/mkfs.c
105+++ b/mkfs.c
106@@ -69,7 +69,7 @@ static u64 parse_size(char *s)
107 return atol(s) * mult;
108 }
109
110-static int make_root_dir(struct btrfs_root *root)
111+static int make_root_dir(struct btrfs_root *root, int mixed)
112 {
113 struct btrfs_trans_handle *trans;
114 struct btrfs_key location;
115@@ -88,30 +88,47 @@ static int make_root_dir(struct btrfs_root *root)
116 0, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
117 BUG_ON(ret);
118
119- ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
120- &chunk_start, &chunk_size,
121- BTRFS_BLOCK_GROUP_METADATA);
122- BUG_ON(ret);
123- ret = btrfs_make_block_group(trans, root, 0,
124- BTRFS_BLOCK_GROUP_METADATA,
125- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
126- chunk_start, chunk_size);
127- BUG_ON(ret);
128+ if (mixed) {
129+ ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
130+ &chunk_start, &chunk_size,
131+ BTRFS_BLOCK_GROUP_METADATA |
132+ BTRFS_BLOCK_GROUP_DATA);
133+ BUG_ON(ret);
134+ ret = btrfs_make_block_group(trans, root, 0,
135+ BTRFS_BLOCK_GROUP_METADATA |
136+ BTRFS_BLOCK_GROUP_DATA,
137+ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
138+ chunk_start, chunk_size);
139+ BUG_ON(ret);
140+ printf("Created a data/metadata chunk of size %llu\n", chunk_size);
141+ } else {
142+ ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
143+ &chunk_start, &chunk_size,
144+ BTRFS_BLOCK_GROUP_METADATA);
145+ BUG_ON(ret);
146+ ret = btrfs_make_block_group(trans, root, 0,
147+ BTRFS_BLOCK_GROUP_METADATA,
148+ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
149+ chunk_start, chunk_size);
150+ BUG_ON(ret);
151+ }
152
153 root->fs_info->system_allocs = 0;
154 btrfs_commit_transaction(trans, root);
155 trans = btrfs_start_transaction(root, 1);
156 BUG_ON(!trans);
157
158- ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
159- &chunk_start, &chunk_size,
160- BTRFS_BLOCK_GROUP_DATA);
161- BUG_ON(ret);
162- ret = btrfs_make_block_group(trans, root, 0,
163- BTRFS_BLOCK_GROUP_DATA,
164- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
165- chunk_start, chunk_size);
166- BUG_ON(ret);
167+ if (!mixed) {
168+ ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root,
169+ &chunk_start, &chunk_size,
170+ BTRFS_BLOCK_GROUP_DATA);
171+ BUG_ON(ret);
172+ ret = btrfs_make_block_group(trans, root, 0,
173+ BTRFS_BLOCK_GROUP_DATA,
174+ BTRFS_FIRST_CHUNK_TREE_OBJECTID,
175+ chunk_start, chunk_size);
176+ BUG_ON(ret);
177+ }
178
179 ret = btrfs_make_root_dir(trans, root->fs_info->tree_root,
180 BTRFS_ROOT_TREE_DIR_OBJECTID);
181@@ -200,7 +217,7 @@ static int create_one_raid_group(struct btrfs_trans_handle *trans,
182
183 static int create_raid_groups(struct btrfs_trans_handle *trans,
184 struct btrfs_root *root, u64 data_profile,
185- u64 metadata_profile)
186+ u64 metadata_profile, int mixed)
187 {
188 u64 num_devices = btrfs_super_num_devices(&root->fs_info->super_copy);
189 u64 allowed;
190@@ -215,20 +232,24 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
191 allowed = BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1;
192
193 if (allowed & metadata_profile) {
194+ u64 meta_flags = BTRFS_BLOCK_GROUP_METADATA;
195+
196 ret = create_one_raid_group(trans, root,
197 BTRFS_BLOCK_GROUP_SYSTEM |
198 (allowed & metadata_profile));
199 BUG_ON(ret);
200
201- ret = create_one_raid_group(trans, root,
202- BTRFS_BLOCK_GROUP_METADATA |
203+ if (mixed)
204+ meta_flags |= BTRFS_BLOCK_GROUP_DATA;
205+
206+ ret = create_one_raid_group(trans, root, meta_flags |
207 (allowed & metadata_profile));
208 BUG_ON(ret);
209
210 ret = recow_roots(trans, root);
211 BUG_ON(ret);
212 }
213- if (num_devices > 1 && (allowed & data_profile)) {
214+ if (!mixed && num_devices > 1 && (allowed & data_profile)) {
215 ret = create_one_raid_group(trans, root,
216 BTRFS_BLOCK_GROUP_DATA |
217 (allowed & data_profile));
218@@ -274,6 +295,7 @@ static void print_usage(void)
219 fprintf(stderr, "\t -l --leafsize size of btree leaves\n");
220 fprintf(stderr, "\t -L --label set a label\n");
221 fprintf(stderr, "\t -m --metadata metadata profile, values like data profile\n");
222+ fprintf(stderr, "\t -M --mixed mix metadata and data together\n");
223 fprintf(stderr, "\t -n --nodesize size of btree nodes\n");
224 fprintf(stderr, "\t -s --sectorsize min block allocation\n");
225 fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
226@@ -328,6 +350,7 @@ static struct option long_options[] = {
227 { "leafsize", 1, NULL, 'l' },
228 { "label", 1, NULL, 'L'},
229 { "metadata", 1, NULL, 'm' },
230+ { "mixed", 0, NULL, 'M' },
231 { "nodesize", 1, NULL, 'n' },
232 { "sectorsize", 1, NULL, 's' },
233 { "data", 1, NULL, 'd' },
234@@ -358,10 +381,13 @@ int main(int ac, char **av)
235 int first_fd;
236 int ret;
237 int i;
238+ int mixed = 0;
239+ int data_profile_opt = 0;
240+ int metadata_profile_opt = 0;
241
242 while(1) {
243 int c;
244- c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:V", long_options,
245+ c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:VM", long_options,
246 &option_index);
247 if (c < 0)
248 break;
249@@ -371,6 +397,7 @@ int main(int ac, char **av)
250 break;
251 case 'd':
252 data_profile = parse_profile(optarg);
253+ data_profile_opt = 1;
254 break;
255 case 'l':
256 leafsize = parse_size(optarg);
257@@ -380,6 +407,10 @@ int main(int ac, char **av)
258 break;
259 case 'm':
260 metadata_profile = parse_profile(optarg);
261+ metadata_profile_opt = 1;
262+ break;
263+ case 'M':
264+ mixed = 1;
265 break;
266 case 'n':
267 nodesize = parse_size(optarg);
268@@ -389,12 +420,10 @@ int main(int ac, char **av)
269 break;
270 case 'b':
271 block_count = parse_size(optarg);
272- if (block_count < 256*1024*1024) {
273- fprintf(stderr, "File system size "
274- "%llu bytes is too small, "
275- "256M is required at least\n",
276- (unsigned long long)block_count);
277- exit(1);
278+ if (block_count <= 1024*1024*1024) {
279+ printf("SMALL VOLUME: forcing mixed "
280+ "metadata/data groups\n");
281+ mixed = 1;
282 }
283 zero_end = 0;
284 break;
285@@ -439,9 +468,22 @@ int main(int ac, char **av)
286 }
287 first_fd = fd;
288 first_file = file;
289- ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count);
290+ ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count,
291+ &mixed);
292 if (block_count == 0)
293 block_count = dev_block_count;
294+ if (mixed) {
295+ if (!metadata_profile_opt)
296+ metadata_profile = 0;
297+ if (!data_profile_opt)
298+ data_profile = 0;
299+
300+ if (metadata_profile != data_profile) {
301+ fprintf(stderr, "With mixed block groups data and metadata "
302+ "profiles must be the same\n");
303+ exit(1);
304+ }
305+ }
306
307 blocks[0] = BTRFS_SUPER_INFO_OFFSET;
308 for (i = 1; i < 7; i++) {
309@@ -459,7 +501,7 @@ int main(int ac, char **av)
310 root = open_ctree(file, 0, O_RDWR);
311 root->fs_info->alloc_start = alloc_start;
312
313- ret = make_root_dir(root);
314+ ret = make_root_dir(root, mixed);
315 if (ret) {
316 fprintf(stderr, "failed to setup the root directory\n");
317 exit(1);
318@@ -478,6 +520,8 @@ int main(int ac, char **av)
319
320 zero_end = 1;
321 while(ac-- > 0) {
322+ int old_mixed = mixed;
323+
324 file = av[optind++];
325 ret = check_mounted(file);
326 if (ret < 0) {
327@@ -503,8 +547,8 @@ int main(int ac, char **av)
328 continue;
329 }
330 ret = btrfs_prepare_device(fd, file, zero_end,
331- &dev_block_count);
332-
333+ &dev_block_count, &mixed);
334+ mixed = old_mixed;
335 BUG_ON(ret);
336
337 ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count,
338@@ -515,12 +559,20 @@ int main(int ac, char **av)
339
340 raid_groups:
341 ret = create_raid_groups(trans, root, data_profile,
342- metadata_profile);
343+ metadata_profile, mixed);
344 BUG_ON(ret);
345
346 ret = create_data_reloc_tree(trans, root);
347 BUG_ON(ret);
348
349+ if (mixed) {
350+ struct btrfs_super_block *super = &root->fs_info->super_copy;
351+ u64 flags = btrfs_super_incompat_flags(super);
352+
353+ flags |= BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS;
354+ btrfs_set_super_incompat_flags(super, flags);
355+ }
356+
357 printf("fs created label %s on %s\n\tnodesize %u leafsize %u "
358 "sectorsize %u size %s\n",
359 label, first_file, nodesize, leafsize, sectorsize,
360diff --git a/utils.c b/utils.c
361index 35e17b8..ad980ae 100644
362--- a/utils.c
363+++ b/utils.c
364@@ -512,7 +512,8 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
365 return 0;
366 }
367
368-int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret)
369+int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret,
370+ int *mixed)
371 {
372 u64 block_count;
373 u64 bytenr;
374@@ -532,10 +533,9 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret)
375 }
376 zero_end = 1;
377
378- if (block_count < 256 * 1024 * 1024) {
379- fprintf(stderr, "device %s is too small "
380- "(must be at least 256 MB)\n", file);
381- exit(1);
382+ if (block_count < 1024 * 1024 * 1024 && !(*mixed)) {
383+ printf("SMALL VOLUME: forcing mixed metadata/data groups\n");
384+ *mixed = 1;
385 }
386 ret = zero_dev_start(fd);
387 if (ret) {
388diff --git a/utils.h b/utils.h
389index 9dce5b0..a28d7f4 100644
390--- a/utils.h
391+++ b/utils.h
392@@ -27,7 +27,7 @@ int make_btrfs(int fd, const char *device, const char *label,
393 int btrfs_make_root_dir(struct btrfs_trans_handle *trans,
394 struct btrfs_root *root, u64 objectid);
395 int btrfs_prepare_device(int fd, char *file, int zero_end,
396- u64 *block_count_ret);
397+ u64 *block_count_ret, int *mixed);
398 int btrfs_add_to_fsid(struct btrfs_trans_handle *trans,
399 struct btrfs_root *root, int fd, char *path,
400 u64 block_count, u32 io_width, u32 io_align,
401--
4021.7.2.3
403