btrfs-progs: mkfs: move source dir size calculation to its own files
[platform/upstream/btrfs-progs.git] / mkfs / main.c
1 /*
2  * Copyright (C) 2007 Oracle.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License v2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public
14  * License along with this program; if not, write to the
15  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16  * Boston, MA 021110-1307, USA.
17  */
18
19 #include "kerncompat.h"
20 #include "androidcompat.h"
21
22 #include <sys/ioctl.h>
23 #include <sys/mount.h>
24 #include "ioctl.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 /* #include <sys/dir.h> included via androidcompat.h */
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <getopt.h>
31 #include <uuid/uuid.h>
32 #include <ctype.h>
33 #include <blkid/blkid.h>
34 #include "ctree.h"
35 #include "disk-io.h"
36 #include "volumes.h"
37 #include "transaction.h"
38 #include "utils.h"
39 #include "list_sort.h"
40 #include "help.h"
41 #include "mkfs/common.h"
42 #include "mkfs/rootdir.h"
43 #include "fsfeatures.h"
44
45 static int verbose = 1;
46
47 struct mkfs_allocation {
48         u64 data;
49         u64 metadata;
50         u64 mixed;
51         u64 system;
52 };
53
54 static int create_metadata_block_groups(struct btrfs_root *root, int mixed,
55                                 struct mkfs_allocation *allocation)
56 {
57         struct btrfs_fs_info *fs_info = root->fs_info;
58         struct btrfs_trans_handle *trans;
59         u64 bytes_used;
60         u64 chunk_start = 0;
61         u64 chunk_size = 0;
62         int ret;
63
64         trans = btrfs_start_transaction(root, 1);
65         BUG_ON(IS_ERR(trans));
66         bytes_used = btrfs_super_bytes_used(fs_info->super_copy);
67
68         root->fs_info->system_allocs = 1;
69         ret = btrfs_make_block_group(trans, fs_info, bytes_used,
70                                      BTRFS_BLOCK_GROUP_SYSTEM,
71                                      BTRFS_FIRST_CHUNK_TREE_OBJECTID,
72                                      0, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
73         allocation->system += BTRFS_MKFS_SYSTEM_GROUP_SIZE;
74         if (ret)
75                 return ret;
76
77         if (mixed) {
78                 ret = btrfs_alloc_chunk(trans, fs_info,
79                                         &chunk_start, &chunk_size,
80                                         BTRFS_BLOCK_GROUP_METADATA |
81                                         BTRFS_BLOCK_GROUP_DATA);
82                 if (ret == -ENOSPC) {
83                         error("no space to allocate data/metadata chunk");
84                         goto err;
85                 }
86                 if (ret)
87                         return ret;
88                 ret = btrfs_make_block_group(trans, fs_info, 0,
89                                              BTRFS_BLOCK_GROUP_METADATA |
90                                              BTRFS_BLOCK_GROUP_DATA,
91                                              BTRFS_FIRST_CHUNK_TREE_OBJECTID,
92                                              chunk_start, chunk_size);
93                 if (ret)
94                         return ret;
95                 allocation->mixed += chunk_size;
96         } else {
97                 ret = btrfs_alloc_chunk(trans, fs_info,
98                                         &chunk_start, &chunk_size,
99                                         BTRFS_BLOCK_GROUP_METADATA);
100                 if (ret == -ENOSPC) {
101                         error("no space to allocate metadata chunk");
102                         goto err;
103                 }
104                 if (ret)
105                         return ret;
106                 ret = btrfs_make_block_group(trans, fs_info, 0,
107                                              BTRFS_BLOCK_GROUP_METADATA,
108                                              BTRFS_FIRST_CHUNK_TREE_OBJECTID,
109                                              chunk_start, chunk_size);
110                 allocation->metadata += chunk_size;
111                 if (ret)
112                         return ret;
113         }
114
115         root->fs_info->system_allocs = 0;
116         ret = btrfs_commit_transaction(trans, root);
117
118 err:
119         return ret;
120 }
121
122 static int create_data_block_groups(struct btrfs_trans_handle *trans,
123                 struct btrfs_root *root, int mixed,
124                 struct mkfs_allocation *allocation)
125 {
126         struct btrfs_fs_info *fs_info = root->fs_info;
127         u64 chunk_start = 0;
128         u64 chunk_size = 0;
129         int ret = 0;
130
131         if (!mixed) {
132                 ret = btrfs_alloc_chunk(trans, fs_info,
133                                         &chunk_start, &chunk_size,
134                                         BTRFS_BLOCK_GROUP_DATA);
135                 if (ret == -ENOSPC) {
136                         error("no space to allocate data chunk");
137                         goto err;
138                 }
139                 if (ret)
140                         return ret;
141                 ret = btrfs_make_block_group(trans, fs_info, 0,
142                                              BTRFS_BLOCK_GROUP_DATA,
143                                              BTRFS_FIRST_CHUNK_TREE_OBJECTID,
144                                              chunk_start, chunk_size);
145                 allocation->data += chunk_size;
146                 if (ret)
147                         return ret;
148         }
149
150 err:
151         return ret;
152 }
153
154 static int make_root_dir(struct btrfs_trans_handle *trans,
155                 struct btrfs_root *root)
156 {
157         struct btrfs_key location;
158         int ret;
159
160         ret = btrfs_make_root_dir(trans, root->fs_info->tree_root,
161                               BTRFS_ROOT_TREE_DIR_OBJECTID);
162         if (ret)
163                 goto err;
164         ret = btrfs_make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID);
165         if (ret)
166                 goto err;
167         memcpy(&location, &root->fs_info->fs_root->root_key, sizeof(location));
168         location.offset = (u64)-1;
169         ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root,
170                         "default", 7,
171                         btrfs_super_root_dir(root->fs_info->super_copy),
172                         &location, BTRFS_FT_DIR, 0);
173         if (ret)
174                 goto err;
175
176         ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root,
177                              "default", 7, location.objectid,
178                              BTRFS_ROOT_TREE_DIR_OBJECTID, 0);
179         if (ret)
180                 goto err;
181
182 err:
183         return ret;
184 }
185
186 static int __recow_root(struct btrfs_trans_handle *trans,
187                          struct btrfs_root *root)
188 {
189         struct extent_buffer *tmp;
190         int ret;
191
192         if (trans->transid != btrfs_root_generation(&root->root_item)) {
193                 extent_buffer_get(root->node);
194                 ret = __btrfs_cow_block(trans, root, root->node,
195                                         NULL, 0, &tmp, 0, 0);
196                 if (ret)
197                         return ret;
198                 free_extent_buffer(tmp);
199         }
200
201         return 0;
202 }
203
204 static int recow_roots(struct btrfs_trans_handle *trans,
205                        struct btrfs_root *root)
206 {
207         struct btrfs_fs_info *info = root->fs_info;
208         int ret;
209
210         ret = __recow_root(trans, info->fs_root);
211         if (ret)
212                 return ret;
213         ret = __recow_root(trans, info->tree_root);
214         if (ret)
215                 return ret;
216         ret = __recow_root(trans, info->extent_root);
217         if (ret)
218                 return ret;
219         ret = __recow_root(trans, info->chunk_root);
220         if (ret)
221                 return ret;
222         ret = __recow_root(trans, info->dev_root);
223         if (ret)
224                 return ret;
225         ret = __recow_root(trans, info->csum_root);
226         if (ret)
227                 return ret;
228
229         return 0;
230 }
231
232 static int create_one_raid_group(struct btrfs_trans_handle *trans,
233                               struct btrfs_root *root, u64 type,
234                               struct mkfs_allocation *allocation)
235
236 {
237         struct btrfs_fs_info *fs_info = root->fs_info;
238         u64 chunk_start;
239         u64 chunk_size;
240         int ret;
241
242         ret = btrfs_alloc_chunk(trans, fs_info,
243                                 &chunk_start, &chunk_size, type);
244         if (ret == -ENOSPC) {
245                 error("not enough free space to allocate chunk");
246                 exit(1);
247         }
248         if (ret)
249                 return ret;
250
251         ret = btrfs_make_block_group(trans, fs_info, 0,
252                                      type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
253                                      chunk_start, chunk_size);
254
255         type &= BTRFS_BLOCK_GROUP_TYPE_MASK;
256         if (type == BTRFS_BLOCK_GROUP_DATA) {
257                 allocation->data += chunk_size;
258         } else if (type == BTRFS_BLOCK_GROUP_METADATA) {
259                 allocation->metadata += chunk_size;
260         } else if (type == BTRFS_BLOCK_GROUP_SYSTEM) {
261                 allocation->system += chunk_size;
262         } else if (type ==
263                         (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA)) {
264                 allocation->mixed += chunk_size;
265         } else {
266                 error("unrecognized profile type: 0x%llx",
267                                 (unsigned long long)type);
268                 ret = -EINVAL;
269         }
270
271         return ret;
272 }
273
274 static int create_raid_groups(struct btrfs_trans_handle *trans,
275                               struct btrfs_root *root, u64 data_profile,
276                               u64 metadata_profile, int mixed,
277                               struct mkfs_allocation *allocation)
278 {
279         int ret;
280
281         if (metadata_profile) {
282                 u64 meta_flags = BTRFS_BLOCK_GROUP_METADATA;
283
284                 ret = create_one_raid_group(trans, root,
285                                             BTRFS_BLOCK_GROUP_SYSTEM |
286                                             metadata_profile, allocation);
287                 if (ret)
288                         return ret;
289
290                 if (mixed)
291                         meta_flags |= BTRFS_BLOCK_GROUP_DATA;
292
293                 ret = create_one_raid_group(trans, root, meta_flags |
294                                             metadata_profile, allocation);
295                 if (ret)
296                         return ret;
297
298         }
299         if (!mixed && data_profile) {
300                 ret = create_one_raid_group(trans, root,
301                                             BTRFS_BLOCK_GROUP_DATA |
302                                             data_profile, allocation);
303                 if (ret)
304                         return ret;
305         }
306         ret = recow_roots(trans, root);
307
308         return ret;
309 }
310
311 static int create_tree(struct btrfs_trans_handle *trans,
312                         struct btrfs_root *root, u64 objectid)
313 {
314         struct btrfs_key location;
315         struct btrfs_root_item root_item;
316         struct extent_buffer *tmp;
317         int ret;
318
319         ret = btrfs_copy_root(trans, root, root->node, &tmp, objectid);
320         if (ret)
321                 return ret;
322
323         memcpy(&root_item, &root->root_item, sizeof(root_item));
324         btrfs_set_root_bytenr(&root_item, tmp->start);
325         btrfs_set_root_level(&root_item, btrfs_header_level(tmp));
326         btrfs_set_root_generation(&root_item, trans->transid);
327         free_extent_buffer(tmp);
328
329         location.objectid = objectid;
330         location.type = BTRFS_ROOT_ITEM_KEY;
331         location.offset = 0;
332         ret = btrfs_insert_root(trans, root->fs_info->tree_root,
333                                 &location, &root_item);
334
335         return ret;
336 }
337
338 static void print_usage(int ret)
339 {
340         printf("Usage: mkfs.btrfs [options] dev [ dev ... ]\n");
341         printf("Options:\n");
342         printf("  allocation profiles:\n");
343         printf("\t-d|--data PROFILE       data profile, raid0, raid1, raid5, raid6, raid10, dup or single\n");
344         printf("\t-m|--metadata PROFILE   metadata profile, values like for data profile\n");
345         printf("\t-M|--mixed              mix metadata and data together\n");
346         printf("  features:\n");
347         printf("\t-n|--nodesize SIZE      size of btree nodes\n");
348         printf("\t-s|--sectorsize SIZE    data block size (may not be mountable by current kernel)\n");
349         printf("\t-O|--features LIST      comma separated list of filesystem features (use '-O list-all' to list features)\n");
350         printf("\t-L|--label LABEL        set the filesystem label\n");
351         printf("\t-U|--uuid UUID          specify the filesystem UUID (must be unique)\n");
352         printf("  creation:\n");
353         printf("\t-b|--byte-count SIZE    set filesystem size to SIZE (on the first device)\n");
354         printf("\t-r|--rootdir DIR        copy files from DIR to the image root directory\n");
355         printf("\t-K|--nodiscard          do not perform whole device TRIM\n");
356         printf("\t-f|--force              force overwrite of existing filesystem\n");
357         printf("  general:\n");
358         printf("\t-q|--quiet              no messages except errors\n");
359         printf("\t-V|--version            print the mkfs.btrfs version and exit\n");
360         printf("\t--help                  print this help and exit\n");
361         printf("  deprecated:\n");
362         printf("\t-A|--alloc-start START  the offset to start the filesystem\n");
363         printf("\t-l|--leafsize SIZE      deprecated, alias for nodesize\n");
364         exit(ret);
365 }
366
367 static u64 parse_profile(const char *s)
368 {
369         if (strcasecmp(s, "raid0") == 0) {
370                 return BTRFS_BLOCK_GROUP_RAID0;
371         } else if (strcasecmp(s, "raid1") == 0) {
372                 return BTRFS_BLOCK_GROUP_RAID1;
373         } else if (strcasecmp(s, "raid5") == 0) {
374                 return BTRFS_BLOCK_GROUP_RAID5;
375         } else if (strcasecmp(s, "raid6") == 0) {
376                 return BTRFS_BLOCK_GROUP_RAID6;
377         } else if (strcasecmp(s, "raid10") == 0) {
378                 return BTRFS_BLOCK_GROUP_RAID10;
379         } else if (strcasecmp(s, "dup") == 0) {
380                 return BTRFS_BLOCK_GROUP_DUP;
381         } else if (strcasecmp(s, "single") == 0) {
382                 return 0;
383         } else {
384                 error("unknown profile %s", s);
385                 exit(1);
386         }
387         /* not reached */
388         return 0;
389 }
390
391 static char *parse_label(const char *input)
392 {
393         int len = strlen(input);
394
395         if (len >= BTRFS_LABEL_SIZE) {
396                 error("label %s is too long (max %d)", input,
397                         BTRFS_LABEL_SIZE - 1);
398                 exit(1);
399         }
400         return strdup(input);
401 }
402
403 static int create_chunks(struct btrfs_trans_handle *trans,
404                          struct btrfs_root *root, u64 num_of_meta_chunks,
405                          u64 size_of_data,
406                          struct mkfs_allocation *allocation)
407 {
408         struct btrfs_fs_info *fs_info = root->fs_info;
409         u64 chunk_start;
410         u64 chunk_size;
411         u64 meta_type = BTRFS_BLOCK_GROUP_METADATA;
412         u64 data_type = BTRFS_BLOCK_GROUP_DATA;
413         u64 minimum_data_chunk_size = SZ_8M;
414         u64 i;
415         int ret;
416
417         for (i = 0; i < num_of_meta_chunks; i++) {
418                 ret = btrfs_alloc_chunk(trans, fs_info,
419                                         &chunk_start, &chunk_size, meta_type);
420                 if (ret)
421                         return ret;
422                 ret = btrfs_make_block_group(trans, fs_info, 0,
423                                              meta_type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
424                                              chunk_start, chunk_size);
425                 allocation->metadata += chunk_size;
426                 if (ret)
427                         return ret;
428                 set_extent_dirty(&root->fs_info->free_space_cache,
429                                  chunk_start, chunk_start + chunk_size - 1);
430         }
431
432         if (size_of_data < minimum_data_chunk_size)
433                 size_of_data = minimum_data_chunk_size;
434
435         ret = btrfs_alloc_data_chunk(trans, fs_info,
436                                      &chunk_start, size_of_data, data_type, 0);
437         if (ret)
438                 return ret;
439         ret = btrfs_make_block_group(trans, fs_info, 0,
440                                      data_type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
441                                      chunk_start, size_of_data);
442         allocation->data += size_of_data;
443         if (ret)
444                 return ret;
445         set_extent_dirty(&root->fs_info->free_space_cache,
446                          chunk_start, chunk_start + size_of_data - 1);
447         return ret;
448 }
449
450 static int zero_output_file(int out_fd, u64 size)
451 {
452         int loop_num;
453         u64 location = 0;
454         char buf[SZ_4K];
455         int ret = 0, i;
456         ssize_t written;
457
458         memset(buf, 0, SZ_4K);
459
460         /* Only zero out the first 1M */
461         loop_num = SZ_1M / SZ_4K;
462         for (i = 0; i < loop_num; i++) {
463                 written = pwrite64(out_fd, buf, SZ_4K, location);
464                 if (written != SZ_4K)
465                         ret = -EIO;
466                 location += SZ_4K;
467         }
468
469         /* Then enlarge the file to size */
470         written = pwrite64(out_fd, buf, 1, size - 1);
471         if (written < 1)
472                 ret = -EIO;
473         return ret;
474 }
475
476 static int is_ssd(const char *file)
477 {
478         blkid_probe probe;
479         char wholedisk[PATH_MAX];
480         char sysfs_path[PATH_MAX];
481         dev_t devno;
482         int fd;
483         char rotational;
484         int ret;
485
486         probe = blkid_new_probe_from_filename(file);
487         if (!probe)
488                 return 0;
489
490         /* Device number of this disk (possibly a partition) */
491         devno = blkid_probe_get_devno(probe);
492         if (!devno) {
493                 blkid_free_probe(probe);
494                 return 0;
495         }
496
497         /* Get whole disk name (not full path) for this devno */
498         ret = blkid_devno_to_wholedisk(devno,
499                         wholedisk, sizeof(wholedisk), NULL);
500         if (ret) {
501                 blkid_free_probe(probe);
502                 return 0;
503         }
504
505         snprintf(sysfs_path, PATH_MAX, "/sys/block/%s/queue/rotational",
506                  wholedisk);
507
508         blkid_free_probe(probe);
509
510         fd = open(sysfs_path, O_RDONLY);
511         if (fd < 0) {
512                 return 0;
513         }
514
515         if (read(fd, &rotational, 1) < 1) {
516                 close(fd);
517                 return 0;
518         }
519         close(fd);
520
521         return rotational == '0';
522 }
523
524 static int _cmp_device_by_id(void *priv, struct list_head *a,
525                              struct list_head *b)
526 {
527         return list_entry(a, struct btrfs_device, dev_list)->devid -
528                list_entry(b, struct btrfs_device, dev_list)->devid;
529 }
530
531 static void list_all_devices(struct btrfs_root *root)
532 {
533         struct btrfs_fs_devices *fs_devices;
534         struct btrfs_device *device;
535         int number_of_devices = 0;
536         u64 total_block_count = 0;
537
538         fs_devices = root->fs_info->fs_devices;
539
540         list_for_each_entry(device, &fs_devices->devices, dev_list)
541                 number_of_devices++;
542
543         list_sort(NULL, &fs_devices->devices, _cmp_device_by_id);
544
545         printf("Number of devices:  %d\n", number_of_devices);
546         /* printf("Total devices size: %10s\n", */
547                 /* pretty_size(total_block_count)); */
548         printf("Devices:\n");
549         printf("   ID        SIZE  PATH\n");
550         list_for_each_entry(device, &fs_devices->devices, dev_list) {
551                 printf("  %3llu  %10s  %s\n",
552                         device->devid,
553                         pretty_size(device->total_bytes),
554                         device->name);
555                 total_block_count += device->total_bytes;
556         }
557
558         printf("\n");
559 }
560
561 static int is_temp_block_group(struct extent_buffer *node,
562                                struct btrfs_block_group_item *bgi,
563                                u64 data_profile, u64 meta_profile,
564                                u64 sys_profile)
565 {
566         u64 flag = btrfs_disk_block_group_flags(node, bgi);
567         u64 flag_type = flag & BTRFS_BLOCK_GROUP_TYPE_MASK;
568         u64 flag_profile = flag & BTRFS_BLOCK_GROUP_PROFILE_MASK;
569         u64 used = btrfs_disk_block_group_used(node, bgi);
570
571         /*
572          * Chunks meets all the following conditions is a temp chunk
573          * 1) Empty chunk
574          * Temp chunk is always empty.
575          *
576          * 2) profile mismatch with mkfs profile.
577          * Temp chunk is always in SINGLE
578          *
579          * 3) Size differs with mkfs_alloc
580          * Special case for SINGLE/SINGLE btrfs.
581          * In that case, temp data chunk and real data chunk are always empty.
582          * So we need to use mkfs_alloc to be sure which chunk is the newly
583          * allocated.
584          *
585          * Normally, new chunk size is equal to mkfs one (One chunk)
586          * If it has multiple chunks, we just refuse to delete any one.
587          * As they are all single, so no real problem will happen.
588          * So only use condition 1) and 2) to judge them.
589          */
590         if (used != 0)
591                 return 0;
592         switch (flag_type) {
593         case BTRFS_BLOCK_GROUP_DATA:
594         case BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA:
595                 data_profile &= BTRFS_BLOCK_GROUP_PROFILE_MASK;
596                 if (flag_profile != data_profile)
597                         return 1;
598                 break;
599         case BTRFS_BLOCK_GROUP_METADATA:
600                 meta_profile &= BTRFS_BLOCK_GROUP_PROFILE_MASK;
601                 if (flag_profile != meta_profile)
602                         return 1;
603                 break;
604         case BTRFS_BLOCK_GROUP_SYSTEM:
605                 sys_profile &= BTRFS_BLOCK_GROUP_PROFILE_MASK;
606                 if (flag_profile != sys_profile)
607                         return 1;
608                 break;
609         }
610         return 0;
611 }
612
613 /* Note: if current is a block group, it will skip it anyway */
614 static int next_block_group(struct btrfs_root *root,
615                             struct btrfs_path *path)
616 {
617         struct btrfs_key key;
618         int ret = 0;
619
620         while (1) {
621                 ret = btrfs_next_item(root, path);
622                 if (ret)
623                         goto out;
624
625                 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
626                 if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY)
627                         goto out;
628         }
629 out:
630         return ret;
631 }
632
633 /* This function will cleanup  */
634 static int cleanup_temp_chunks(struct btrfs_fs_info *fs_info,
635                                struct mkfs_allocation *alloc,
636                                u64 data_profile, u64 meta_profile,
637                                u64 sys_profile)
638 {
639         struct btrfs_trans_handle *trans = NULL;
640         struct btrfs_block_group_item *bgi;
641         struct btrfs_root *root = fs_info->extent_root;
642         struct btrfs_key key;
643         struct btrfs_key found_key;
644         struct btrfs_path path;
645         int ret = 0;
646
647         btrfs_init_path(&path);
648         trans = btrfs_start_transaction(root, 1);
649         BUG_ON(IS_ERR(trans));
650
651         key.objectid = 0;
652         key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
653         key.offset = 0;
654
655         while (1) {
656                 /*
657                  * as the rest of the loop may modify the tree, we need to
658                  * start a new search each time.
659                  */
660                 ret = btrfs_search_slot(trans, root, &key, &path, 0, 0);
661                 if (ret < 0)
662                         goto out;
663                 /* Don't pollute ret for >0 case */
664                 if (ret > 0)
665                         ret = 0;
666
667                 btrfs_item_key_to_cpu(path.nodes[0], &found_key,
668                                       path.slots[0]);
669                 if (found_key.objectid < key.objectid)
670                         goto out;
671                 if (found_key.type != BTRFS_BLOCK_GROUP_ITEM_KEY) {
672                         ret = next_block_group(root, &path);
673                         if (ret < 0)
674                                 goto out;
675                         if (ret > 0) {
676                                 ret = 0;
677                                 goto out;
678                         }
679                         btrfs_item_key_to_cpu(path.nodes[0], &found_key,
680                                               path.slots[0]);
681                 }
682
683                 bgi = btrfs_item_ptr(path.nodes[0], path.slots[0],
684                                      struct btrfs_block_group_item);
685                 if (is_temp_block_group(path.nodes[0], bgi,
686                                         data_profile, meta_profile,
687                                         sys_profile)) {
688                         u64 flags = btrfs_disk_block_group_flags(path.nodes[0],
689                                                              bgi);
690
691                         ret = btrfs_free_block_group(trans, fs_info,
692                                         found_key.objectid, found_key.offset);
693                         if (ret < 0)
694                                 goto out;
695
696                         if ((flags & BTRFS_BLOCK_GROUP_TYPE_MASK) ==
697                             BTRFS_BLOCK_GROUP_DATA)
698                                 alloc->data -= found_key.offset;
699                         else if ((flags & BTRFS_BLOCK_GROUP_TYPE_MASK) ==
700                                  BTRFS_BLOCK_GROUP_METADATA)
701                                 alloc->metadata -= found_key.offset;
702                         else if ((flags & BTRFS_BLOCK_GROUP_TYPE_MASK) ==
703                                  BTRFS_BLOCK_GROUP_SYSTEM)
704                                 alloc->system -= found_key.offset;
705                         else if ((flags & BTRFS_BLOCK_GROUP_TYPE_MASK) ==
706                                  (BTRFS_BLOCK_GROUP_METADATA |
707                                   BTRFS_BLOCK_GROUP_DATA))
708                                 alloc->mixed -= found_key.offset;
709                 }
710                 btrfs_release_path(&path);
711                 key.objectid = found_key.objectid + found_key.offset;
712         }
713 out:
714         if (trans)
715                 btrfs_commit_transaction(trans, root);
716         btrfs_release_path(&path);
717         return ret;
718 }
719
720 int main(int argc, char **argv)
721 {
722         char *file;
723         struct btrfs_root *root;
724         struct btrfs_fs_info *fs_info;
725         struct btrfs_trans_handle *trans;
726         char *label = NULL;
727         u64 block_count = 0;
728         u64 dev_block_count = 0;
729         u64 alloc_start = 0;
730         u64 metadata_profile = 0;
731         u64 data_profile = 0;
732         u32 nodesize = max_t(u32, sysconf(_SC_PAGESIZE),
733                         BTRFS_MKFS_DEFAULT_NODE_SIZE);
734         u32 sectorsize = 4096;
735         u32 stripesize = 4096;
736         int zero_end = 1;
737         int fd = -1;
738         int ret;
739         int close_ret;
740         int i;
741         int mixed = 0;
742         int nodesize_forced = 0;
743         int data_profile_opt = 0;
744         int metadata_profile_opt = 0;
745         int discard = 1;
746         int ssd = 0;
747         int force_overwrite = 0;
748         char *source_dir = NULL;
749         int source_dir_set = 0;
750         u64 num_of_meta_chunks = 0;
751         u64 size_of_data = 0;
752         u64 source_dir_size = 0;
753         u64 min_dev_size;
754         int dev_cnt = 0;
755         int saved_optind;
756         char fs_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 };
757         u64 features = BTRFS_MKFS_DEFAULT_FEATURES;
758         struct mkfs_allocation allocation = { 0 };
759         struct btrfs_mkfs_config mkfs_cfg;
760
761         while(1) {
762                 int c;
763                 static const struct option long_options[] = {
764                         { "alloc-start", required_argument, NULL, 'A'},
765                         { "byte-count", required_argument, NULL, 'b' },
766                         { "force", no_argument, NULL, 'f' },
767                         { "leafsize", required_argument, NULL, 'l' },
768                         { "label", required_argument, NULL, 'L'},
769                         { "metadata", required_argument, NULL, 'm' },
770                         { "mixed", no_argument, NULL, 'M' },
771                         { "nodesize", required_argument, NULL, 'n' },
772                         { "sectorsize", required_argument, NULL, 's' },
773                         { "data", required_argument, NULL, 'd' },
774                         { "version", no_argument, NULL, 'V' },
775                         { "rootdir", required_argument, NULL, 'r' },
776                         { "nodiscard", no_argument, NULL, 'K' },
777                         { "features", required_argument, NULL, 'O' },
778                         { "uuid", required_argument, NULL, 'U' },
779                         { "quiet", 0, NULL, 'q' },
780                         { "help", no_argument, NULL, GETOPT_VAL_HELP },
781                         { NULL, 0, NULL, 0}
782                 };
783
784                 c = getopt_long(argc, argv, "A:b:fl:n:s:m:d:L:O:r:U:VMKq",
785                                 long_options, NULL);
786                 if (c < 0)
787                         break;
788                 switch(c) {
789                         case 'A':
790                                 alloc_start = parse_size(optarg);
791                                 break;
792                         case 'f':
793                                 force_overwrite = 1;
794                                 break;
795                         case 'd':
796                                 data_profile = parse_profile(optarg);
797                                 data_profile_opt = 1;
798                                 break;
799                         case 'l':
800                                 warning("--leafsize is deprecated, use --nodesize");
801                                 /* fall through */
802                         case 'n':
803                                 nodesize = parse_size(optarg);
804                                 nodesize_forced = 1;
805                                 break;
806                         case 'L':
807                                 label = parse_label(optarg);
808                                 break;
809                         case 'm':
810                                 metadata_profile = parse_profile(optarg);
811                                 metadata_profile_opt = 1;
812                                 break;
813                         case 'M':
814                                 mixed = 1;
815                                 break;
816                         case 'O': {
817                                 char *orig = strdup(optarg);
818                                 char *tmp = orig;
819
820                                 tmp = btrfs_parse_fs_features(tmp, &features);
821                                 if (tmp) {
822                                         error("unrecognized filesystem feature '%s'",
823                                                         tmp);
824                                         free(orig);
825                                         goto error;
826                                 }
827                                 free(orig);
828                                 if (features & BTRFS_FEATURE_LIST_ALL) {
829                                         btrfs_list_all_fs_features(0);
830                                         goto success;
831                                 }
832                                 break;
833                                 }
834                         case 's':
835                                 sectorsize = parse_size(optarg);
836                                 break;
837                         case 'b':
838                                 block_count = parse_size(optarg);
839                                 zero_end = 0;
840                                 break;
841                         case 'V':
842                                 printf("mkfs.btrfs, part of %s\n",
843                                                 PACKAGE_STRING);
844                                 goto success;
845                         case 'r':
846                                 source_dir = optarg;
847                                 source_dir_set = 1;
848                                 break;
849                         case 'U':
850                                 strncpy(fs_uuid, optarg,
851                                         BTRFS_UUID_UNPARSED_SIZE - 1);
852                                 break;
853                         case 'K':
854                                 discard = 0;
855                                 break;
856                         case 'q':
857                                 verbose = 0;
858                                 break;
859                         case GETOPT_VAL_HELP:
860                         default:
861                                 print_usage(c != GETOPT_VAL_HELP);
862                 }
863         }
864
865         if (verbose) {
866                 printf("%s\n", PACKAGE_STRING);
867                 printf("See %s for more information.\n\n", PACKAGE_URL);
868         }
869
870         sectorsize = max(sectorsize, (u32)sysconf(_SC_PAGESIZE));
871         stripesize = sectorsize;
872         saved_optind = optind;
873         dev_cnt = argc - optind;
874         if (dev_cnt == 0)
875                 print_usage(1);
876
877         if (source_dir_set && dev_cnt > 1) {
878                 error("the option -r is limited to a single device");
879                 goto error;
880         }
881
882         if (*fs_uuid) {
883                 uuid_t dummy_uuid;
884
885                 if (uuid_parse(fs_uuid, dummy_uuid) != 0) {
886                         error("could not parse UUID: %s", fs_uuid);
887                         goto error;
888                 }
889                 if (!test_uuid_unique(fs_uuid)) {
890                         error("non-unique UUID: %s", fs_uuid);
891                         goto error;
892                 }
893         }
894
895         while (dev_cnt-- > 0) {
896                 file = argv[optind++];
897                 if (is_block_device(file) == 1)
898                         ret = test_dev_for_mkfs(file, force_overwrite);
899                 else
900                         ret = test_status_for_mkfs(file, force_overwrite);
901
902                 if (ret)
903                         goto error;
904         }
905
906         optind = saved_optind;
907         dev_cnt = argc - optind;
908
909         file = argv[optind++];
910         ssd = is_ssd(file);
911
912         /*
913         * Set default profiles according to number of added devices.
914         * For mixed groups defaults are single/single.
915         */
916         if (!mixed) {
917                 if (!metadata_profile_opt) {
918                         if (dev_cnt == 1 && ssd && verbose)
919                                 printf("Detected a SSD, turning off metadata "
920                                 "duplication.  Mkfs with -m dup if you want to "
921                                 "force metadata duplication.\n");
922
923                         metadata_profile = (dev_cnt > 1) ?
924                                         BTRFS_BLOCK_GROUP_RAID1 : (ssd) ?
925                                         0: BTRFS_BLOCK_GROUP_DUP;
926                 }
927                 if (!data_profile_opt) {
928                         data_profile = (dev_cnt > 1) ?
929                                 BTRFS_BLOCK_GROUP_RAID0 : 0; /* raid0 or single */
930                 }
931         } else {
932                 u32 best_nodesize = max_t(u32, sysconf(_SC_PAGESIZE), sectorsize);
933
934                 if (metadata_profile_opt || data_profile_opt) {
935                         if (metadata_profile != data_profile) {
936                                 error(
937         "with mixed block groups data and metadata profiles must be the same");
938                                 goto error;
939                         }
940                 }
941
942                 if (!nodesize_forced)
943                         nodesize = best_nodesize;
944         }
945
946         /*
947          * FS features that can be set by other means than -O
948          * just set the bit here
949          */
950         if (mixed)
951                 features |= BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS;
952
953         if ((data_profile | metadata_profile) &
954             (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)) {
955                 features |= BTRFS_FEATURE_INCOMPAT_RAID56;
956         }
957
958         if (btrfs_check_nodesize(nodesize, sectorsize,
959                                  features))
960                 goto error;
961
962         if (sectorsize < sizeof(struct btrfs_super_block)) {
963                 error("sectorsize smaller than superblock: %u < %zu",
964                                 sectorsize, sizeof(struct btrfs_super_block));
965                 goto error;
966         }
967
968         min_dev_size = btrfs_min_dev_size(nodesize, mixed, metadata_profile,
969                                           data_profile);
970         /* Check device/block_count after the nodesize is determined */
971         if (block_count && block_count < min_dev_size) {
972                 error("size %llu is too small to make a usable filesystem",
973                         block_count);
974                 error("minimum size for btrfs filesystem is %llu",
975                         min_dev_size);
976                 goto error;
977         }
978         for (i = saved_optind; i < saved_optind + dev_cnt; i++) {
979                 char *path;
980
981                 path = argv[i];
982                 ret = test_minimum_size(path, min_dev_size);
983                 if (ret < 0) {
984                         error("failed to check size for %s: %s",
985                                 path, strerror(-ret));
986                         goto error;
987                 }
988                 if (ret > 0) {
989                         error("'%s' is too small to make a usable filesystem",
990                                 path);
991                         error("minimum size for each btrfs device is %llu",
992                                 min_dev_size);
993                         goto error;
994                 }
995         }
996         ret = test_num_disk_vs_raid(metadata_profile, data_profile,
997                         dev_cnt, mixed, ssd);
998         if (ret)
999                 goto error;
1000
1001         dev_cnt--;
1002
1003         if (!source_dir_set) {
1004                 /*
1005                  * open without O_EXCL so that the problem should not
1006                  * occur by the following processing.
1007                  * (btrfs_register_one_device() fails if O_EXCL is on)
1008                  */
1009                 fd = open(file, O_RDWR);
1010                 if (fd < 0) {
1011                         error("unable to open %s: %s", file, strerror(errno));
1012                         goto error;
1013                 }
1014                 ret = btrfs_prepare_device(fd, file, &dev_block_count,
1015                                 block_count,
1016                                 (zero_end ? PREP_DEVICE_ZERO_END : 0) |
1017                                 (discard ? PREP_DEVICE_DISCARD : 0) |
1018                                 (verbose ? PREP_DEVICE_VERBOSE : 0));
1019                 if (ret) {
1020                         goto error;
1021                 }
1022                 if (block_count && block_count > dev_block_count) {
1023                         error("%s is smaller than requested size, expected %llu, found %llu",
1024                                         file,
1025                                         (unsigned long long)block_count,
1026                                         (unsigned long long)dev_block_count);
1027                         goto error;
1028                 }
1029         } else {
1030                 fd = open(file, O_CREAT | O_RDWR,
1031                                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
1032                 if (fd < 0) {
1033                         error("unable to open %s: %s", file, strerror(errno));
1034                         goto error;
1035                 }
1036
1037                 source_dir_size = btrfs_mkfs_size_dir(source_dir, sectorsize,
1038                                         &num_of_meta_chunks, &size_of_data);
1039                 if(block_count < source_dir_size)
1040                         block_count = source_dir_size;
1041                 ret = zero_output_file(fd, block_count);
1042                 if (ret) {
1043                         error("unable to zero the output file");
1044                         goto error;
1045                 }
1046                 /* our "device" is the new image file */
1047                 dev_block_count = block_count;
1048         }
1049
1050         /* To create the first block group and chunk 0 in make_btrfs */
1051         if (dev_block_count < BTRFS_MKFS_SYSTEM_GROUP_SIZE) {
1052                 error("device is too small to make filesystem, must be at least %llu",
1053                                 (unsigned long long)BTRFS_MKFS_SYSTEM_GROUP_SIZE);
1054                 goto error;
1055         }
1056
1057         if (group_profile_max_safe_loss(metadata_profile) <
1058                 group_profile_max_safe_loss(data_profile)){
1059                 warning("metadata has lower redundancy than data!\n");
1060         }
1061
1062         mkfs_cfg.label = label;
1063         memcpy(mkfs_cfg.fs_uuid, fs_uuid, sizeof(mkfs_cfg.fs_uuid));
1064         mkfs_cfg.num_bytes = dev_block_count;
1065         mkfs_cfg.nodesize = nodesize;
1066         mkfs_cfg.sectorsize = sectorsize;
1067         mkfs_cfg.stripesize = stripesize;
1068         mkfs_cfg.features = features;
1069
1070         ret = make_btrfs(fd, &mkfs_cfg);
1071         if (ret) {
1072                 error("error during mkfs: %s", strerror(-ret));
1073                 goto error;
1074         }
1075
1076         fs_info = open_ctree_fs_info(file, 0, 0, 0,
1077                         OPEN_CTREE_WRITES | OPEN_CTREE_FS_PARTIAL);
1078         if (!fs_info) {
1079                 error("open ctree failed");
1080                 goto error;
1081         }
1082         close(fd);
1083         fd = -1;
1084         root = fs_info->fs_root;
1085         fs_info->alloc_start = alloc_start;
1086
1087         ret = create_metadata_block_groups(root, mixed, &allocation);
1088         if (ret) {
1089                 error("failed to create default block groups: %d", ret);
1090                 goto error;
1091         }
1092
1093         trans = btrfs_start_transaction(root, 1);
1094         if (IS_ERR(trans)) {
1095                 error("failed to start transaction");
1096                 goto error;
1097         }
1098
1099         ret = create_data_block_groups(trans, root, mixed, &allocation);
1100         if (ret) {
1101                 error("failed to create default data block groups: %d", ret);
1102                 goto error;
1103         }
1104
1105         ret = make_root_dir(trans, root);
1106         if (ret) {
1107                 error("failed to setup the root directory: %d", ret);
1108                 goto error;
1109         }
1110
1111         ret = btrfs_commit_transaction(trans, root);
1112         if (ret) {
1113                 error("unable to commit transaction: %d", ret);
1114                 goto out;
1115         }
1116
1117         trans = btrfs_start_transaction(root, 1);
1118         if (IS_ERR(trans)) {
1119                 error("failed to start transaction");
1120                 goto error;
1121         }
1122
1123         if (dev_cnt == 0)
1124                 goto raid_groups;
1125
1126         while (dev_cnt-- > 0) {
1127                 file = argv[optind++];
1128
1129                 /*
1130                  * open without O_EXCL so that the problem should not
1131                  * occur by the following processing.
1132                  * (btrfs_register_one_device() fails if O_EXCL is on)
1133                  */
1134                 fd = open(file, O_RDWR);
1135                 if (fd < 0) {
1136                         error("unable to open %s: %s", file, strerror(errno));
1137                         goto error;
1138                 }
1139                 ret = btrfs_device_already_in_root(root, fd,
1140                                                    BTRFS_SUPER_INFO_OFFSET);
1141                 if (ret) {
1142                         error("skipping duplicate device %s in the filesystem",
1143                                 file);
1144                         close(fd);
1145                         continue;
1146                 }
1147                 ret = btrfs_prepare_device(fd, file, &dev_block_count,
1148                                 block_count,
1149                                 (verbose ? PREP_DEVICE_VERBOSE : 0) |
1150                                 (zero_end ? PREP_DEVICE_ZERO_END : 0) |
1151                                 (discard ? PREP_DEVICE_DISCARD : 0));
1152                 if (ret) {
1153                         goto error;
1154                 }
1155
1156                 ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count,
1157                                         sectorsize, sectorsize, sectorsize);
1158                 if (ret) {
1159                         error("unable to add %s to filesystem: %d", file, ret);
1160                         goto out;
1161                 }
1162                 if (verbose >= 2) {
1163                         struct btrfs_device *device;
1164
1165                         device = container_of(fs_info->fs_devices->devices.next,
1166                                         struct btrfs_device, dev_list);
1167                         printf("adding device %s id %llu\n", file,
1168                                 (unsigned long long)device->devid);
1169                 }
1170         }
1171
1172 raid_groups:
1173         if (!source_dir_set) {
1174                 ret = create_raid_groups(trans, root, data_profile,
1175                                  metadata_profile, mixed, &allocation);
1176                 if (ret) {
1177                         error("unable to create raid groups: %d", ret);
1178                         goto out;
1179                 }
1180         }
1181
1182         ret = create_tree(trans, root, BTRFS_DATA_RELOC_TREE_OBJECTID);
1183         if (ret) {
1184                 error("unable to create data reloc tree: %d", ret);
1185                 goto out;
1186         }
1187
1188         ret = btrfs_commit_transaction(trans, root);
1189         if (ret) {
1190                 error("unable to commit transaction: %d", ret);
1191                 goto out;
1192         }
1193
1194         if (source_dir_set) {
1195                 trans = btrfs_start_transaction(root, 1);
1196                 BUG_ON(IS_ERR(trans));
1197                 ret = create_chunks(trans, root,
1198                                     num_of_meta_chunks, size_of_data,
1199                                     &allocation);
1200                 if (ret) {
1201                         error("unable to create chunks: %d", ret);
1202                         goto out;
1203                 }
1204                 ret = btrfs_commit_transaction(trans, root);
1205                 if (ret) {
1206                         error("transaction commit failed: %d", ret);
1207                         goto out;
1208                 }
1209
1210                 ret = btrfs_mkfs_fill_dir(source_dir, root, verbose);
1211                 if (ret) {
1212                         error("error wihle filling filesystem: %d", ret);
1213                         goto out;
1214                 }
1215         }
1216         ret = cleanup_temp_chunks(fs_info, &allocation, data_profile,
1217                                   metadata_profile, metadata_profile);
1218         if (ret < 0) {
1219                 error("failed to cleanup temporary chunks: %d", ret);
1220                 goto out;
1221         }
1222
1223         if (verbose) {
1224                 char features_buf[64];
1225
1226                 printf("Label:              %s\n", label);
1227                 printf("UUID:               %s\n", mkfs_cfg.fs_uuid);
1228                 printf("Node size:          %u\n", nodesize);
1229                 printf("Sector size:        %u\n", sectorsize);
1230                 printf("Filesystem size:    %s\n",
1231                         pretty_size(btrfs_super_total_bytes(fs_info->super_copy)));
1232                 printf("Block group profiles:\n");
1233                 if (allocation.data)
1234                         printf("  Data:             %-8s %16s\n",
1235                                 btrfs_group_profile_str(data_profile),
1236                                 pretty_size(allocation.data));
1237                 if (allocation.metadata)
1238                         printf("  Metadata:         %-8s %16s\n",
1239                                 btrfs_group_profile_str(metadata_profile),
1240                                 pretty_size(allocation.metadata));
1241                 if (allocation.mixed)
1242                         printf("  Data+Metadata:    %-8s %16s\n",
1243                                 btrfs_group_profile_str(data_profile),
1244                                 pretty_size(allocation.mixed));
1245                 printf("  System:           %-8s %16s\n",
1246                         btrfs_group_profile_str(metadata_profile),
1247                         pretty_size(allocation.system));
1248                 printf("SSD detected:       %s\n", ssd ? "yes" : "no");
1249                 btrfs_parse_features_to_string(features_buf, features);
1250                 printf("Incompat features:  %s", features_buf);
1251                 printf("\n");
1252
1253                 list_all_devices(root);
1254         }
1255
1256         /*
1257          * The filesystem is now fully set up, commit the remaining changes and
1258          * fix the signature as the last step before closing the devices.
1259          */
1260         fs_info->finalize_on_close = 1;
1261 out:
1262         close_ret = close_ctree(root);
1263
1264         if (!close_ret) {
1265                 optind = saved_optind;
1266                 dev_cnt = argc - optind;
1267                 while (dev_cnt-- > 0) {
1268                         file = argv[optind++];
1269                         if (is_block_device(file) == 1)
1270                                 btrfs_register_one_device(file);
1271                 }
1272         }
1273
1274         btrfs_close_all_devices();
1275         free(label);
1276
1277         return !!ret;
1278 error:
1279         if (fd > 0)
1280                 close(fd);
1281
1282         free(label);
1283         exit(1);
1284 success:
1285         exit(0);
1286 }