btrfs-progs: mkfs: Update allocation info before verbose output
[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 /*
721  * Just update chunk allocation info, since --rootdir may allocate new
722  * chunks which is not updated in @allocation structure.
723  */
724 static void update_chunk_allocation(struct btrfs_fs_info *fs_info,
725                                     struct mkfs_allocation *allocation)
726 {
727         struct btrfs_block_group_cache *bg_cache;
728         const u64 mixed_flag = BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA;
729         u64 search_start = 0;
730
731         allocation->mixed = 0;
732         allocation->data = 0;
733         allocation->metadata = 0;
734         allocation->system = 0;
735         while (1) {
736                 bg_cache = btrfs_lookup_first_block_group(fs_info,
737                                                           search_start);
738                 if (!bg_cache)
739                         break;
740                 if ((bg_cache->flags & mixed_flag) == mixed_flag)
741                         allocation->mixed += bg_cache->key.offset;
742                 else if (bg_cache->flags & BTRFS_BLOCK_GROUP_DATA)
743                         allocation->data += bg_cache->key.offset;
744                 else if (bg_cache->flags & BTRFS_BLOCK_GROUP_METADATA)
745                         allocation->metadata += bg_cache->key.offset;
746                 else
747                         allocation->system += bg_cache->key.offset;
748                 search_start = bg_cache->key.objectid + bg_cache->key.offset;
749         }
750 }
751
752 int main(int argc, char **argv)
753 {
754         char *file;
755         struct btrfs_root *root;
756         struct btrfs_fs_info *fs_info;
757         struct btrfs_trans_handle *trans;
758         char *label = NULL;
759         u64 block_count = 0;
760         u64 dev_block_count = 0;
761         u64 alloc_start = 0;
762         u64 metadata_profile = 0;
763         u64 data_profile = 0;
764         u32 nodesize = max_t(u32, sysconf(_SC_PAGESIZE),
765                         BTRFS_MKFS_DEFAULT_NODE_SIZE);
766         u32 sectorsize = 4096;
767         u32 stripesize = 4096;
768         int zero_end = 1;
769         int fd = -1;
770         int ret;
771         int close_ret;
772         int i;
773         int mixed = 0;
774         int nodesize_forced = 0;
775         int data_profile_opt = 0;
776         int metadata_profile_opt = 0;
777         int discard = 1;
778         int ssd = 0;
779         int force_overwrite = 0;
780         char *source_dir = NULL;
781         int source_dir_set = 0;
782         u64 num_of_meta_chunks = 0;
783         u64 size_of_data = 0;
784         u64 source_dir_size = 0;
785         u64 min_dev_size;
786         int dev_cnt = 0;
787         int saved_optind;
788         char fs_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 };
789         u64 features = BTRFS_MKFS_DEFAULT_FEATURES;
790         struct mkfs_allocation allocation = { 0 };
791         struct btrfs_mkfs_config mkfs_cfg;
792
793         while(1) {
794                 int c;
795                 static const struct option long_options[] = {
796                         { "alloc-start", required_argument, NULL, 'A'},
797                         { "byte-count", required_argument, NULL, 'b' },
798                         { "force", no_argument, NULL, 'f' },
799                         { "leafsize", required_argument, NULL, 'l' },
800                         { "label", required_argument, NULL, 'L'},
801                         { "metadata", required_argument, NULL, 'm' },
802                         { "mixed", no_argument, NULL, 'M' },
803                         { "nodesize", required_argument, NULL, 'n' },
804                         { "sectorsize", required_argument, NULL, 's' },
805                         { "data", required_argument, NULL, 'd' },
806                         { "version", no_argument, NULL, 'V' },
807                         { "rootdir", required_argument, NULL, 'r' },
808                         { "nodiscard", no_argument, NULL, 'K' },
809                         { "features", required_argument, NULL, 'O' },
810                         { "uuid", required_argument, NULL, 'U' },
811                         { "quiet", 0, NULL, 'q' },
812                         { "help", no_argument, NULL, GETOPT_VAL_HELP },
813                         { NULL, 0, NULL, 0}
814                 };
815
816                 c = getopt_long(argc, argv, "A:b:fl:n:s:m:d:L:O:r:U:VMKq",
817                                 long_options, NULL);
818                 if (c < 0)
819                         break;
820                 switch(c) {
821                         case 'A':
822                                 alloc_start = parse_size(optarg);
823                                 break;
824                         case 'f':
825                                 force_overwrite = 1;
826                                 break;
827                         case 'd':
828                                 data_profile = parse_profile(optarg);
829                                 data_profile_opt = 1;
830                                 break;
831                         case 'l':
832                                 warning("--leafsize is deprecated, use --nodesize");
833                                 /* fall through */
834                         case 'n':
835                                 nodesize = parse_size(optarg);
836                                 nodesize_forced = 1;
837                                 break;
838                         case 'L':
839                                 label = parse_label(optarg);
840                                 break;
841                         case 'm':
842                                 metadata_profile = parse_profile(optarg);
843                                 metadata_profile_opt = 1;
844                                 break;
845                         case 'M':
846                                 mixed = 1;
847                                 break;
848                         case 'O': {
849                                 char *orig = strdup(optarg);
850                                 char *tmp = orig;
851
852                                 tmp = btrfs_parse_fs_features(tmp, &features);
853                                 if (tmp) {
854                                         error("unrecognized filesystem feature '%s'",
855                                                         tmp);
856                                         free(orig);
857                                         goto error;
858                                 }
859                                 free(orig);
860                                 if (features & BTRFS_FEATURE_LIST_ALL) {
861                                         btrfs_list_all_fs_features(0);
862                                         goto success;
863                                 }
864                                 break;
865                                 }
866                         case 's':
867                                 sectorsize = parse_size(optarg);
868                                 break;
869                         case 'b':
870                                 block_count = parse_size(optarg);
871                                 zero_end = 0;
872                                 break;
873                         case 'V':
874                                 printf("mkfs.btrfs, part of %s\n",
875                                                 PACKAGE_STRING);
876                                 goto success;
877                         case 'r':
878                                 source_dir = optarg;
879                                 source_dir_set = 1;
880                                 break;
881                         case 'U':
882                                 strncpy(fs_uuid, optarg,
883                                         BTRFS_UUID_UNPARSED_SIZE - 1);
884                                 break;
885                         case 'K':
886                                 discard = 0;
887                                 break;
888                         case 'q':
889                                 verbose = 0;
890                                 break;
891                         case GETOPT_VAL_HELP:
892                         default:
893                                 print_usage(c != GETOPT_VAL_HELP);
894                 }
895         }
896
897         if (verbose) {
898                 printf("%s\n", PACKAGE_STRING);
899                 printf("See %s for more information.\n\n", PACKAGE_URL);
900         }
901
902         sectorsize = max(sectorsize, (u32)sysconf(_SC_PAGESIZE));
903         stripesize = sectorsize;
904         saved_optind = optind;
905         dev_cnt = argc - optind;
906         if (dev_cnt == 0)
907                 print_usage(1);
908
909         if (source_dir_set && dev_cnt > 1) {
910                 error("the option -r is limited to a single device");
911                 goto error;
912         }
913
914         if (*fs_uuid) {
915                 uuid_t dummy_uuid;
916
917                 if (uuid_parse(fs_uuid, dummy_uuid) != 0) {
918                         error("could not parse UUID: %s", fs_uuid);
919                         goto error;
920                 }
921                 if (!test_uuid_unique(fs_uuid)) {
922                         error("non-unique UUID: %s", fs_uuid);
923                         goto error;
924                 }
925         }
926
927         while (dev_cnt-- > 0) {
928                 file = argv[optind++];
929                 if (is_block_device(file) == 1)
930                         ret = test_dev_for_mkfs(file, force_overwrite);
931                 else
932                         ret = test_status_for_mkfs(file, force_overwrite);
933
934                 if (ret)
935                         goto error;
936         }
937
938         optind = saved_optind;
939         dev_cnt = argc - optind;
940
941         file = argv[optind++];
942         ssd = is_ssd(file);
943
944         /*
945         * Set default profiles according to number of added devices.
946         * For mixed groups defaults are single/single.
947         */
948         if (!mixed) {
949                 if (!metadata_profile_opt) {
950                         if (dev_cnt == 1 && ssd && verbose)
951                                 printf("Detected a SSD, turning off metadata "
952                                 "duplication.  Mkfs with -m dup if you want to "
953                                 "force metadata duplication.\n");
954
955                         metadata_profile = (dev_cnt > 1) ?
956                                         BTRFS_BLOCK_GROUP_RAID1 : (ssd) ?
957                                         0: BTRFS_BLOCK_GROUP_DUP;
958                 }
959                 if (!data_profile_opt) {
960                         data_profile = (dev_cnt > 1) ?
961                                 BTRFS_BLOCK_GROUP_RAID0 : 0; /* raid0 or single */
962                 }
963         } else {
964                 u32 best_nodesize = max_t(u32, sysconf(_SC_PAGESIZE), sectorsize);
965
966                 if (metadata_profile_opt || data_profile_opt) {
967                         if (metadata_profile != data_profile) {
968                                 error(
969         "with mixed block groups data and metadata profiles must be the same");
970                                 goto error;
971                         }
972                 }
973
974                 if (!nodesize_forced)
975                         nodesize = best_nodesize;
976         }
977
978         /*
979          * FS features that can be set by other means than -O
980          * just set the bit here
981          */
982         if (mixed)
983                 features |= BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS;
984
985         if ((data_profile | metadata_profile) &
986             (BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6)) {
987                 features |= BTRFS_FEATURE_INCOMPAT_RAID56;
988         }
989
990         if (btrfs_check_nodesize(nodesize, sectorsize,
991                                  features))
992                 goto error;
993
994         if (sectorsize < sizeof(struct btrfs_super_block)) {
995                 error("sectorsize smaller than superblock: %u < %zu",
996                                 sectorsize, sizeof(struct btrfs_super_block));
997                 goto error;
998         }
999
1000         min_dev_size = btrfs_min_dev_size(nodesize, mixed, metadata_profile,
1001                                           data_profile);
1002         /* Check device/block_count after the nodesize is determined */
1003         if (block_count && block_count < min_dev_size) {
1004                 error("size %llu is too small to make a usable filesystem",
1005                         block_count);
1006                 error("minimum size for btrfs filesystem is %llu",
1007                         min_dev_size);
1008                 goto error;
1009         }
1010         for (i = saved_optind; i < saved_optind + dev_cnt; i++) {
1011                 char *path;
1012
1013                 path = argv[i];
1014                 ret = test_minimum_size(path, min_dev_size);
1015                 if (ret < 0) {
1016                         error("failed to check size for %s: %s",
1017                                 path, strerror(-ret));
1018                         goto error;
1019                 }
1020                 if (ret > 0) {
1021                         error("'%s' is too small to make a usable filesystem",
1022                                 path);
1023                         error("minimum size for each btrfs device is %llu",
1024                                 min_dev_size);
1025                         goto error;
1026                 }
1027         }
1028         ret = test_num_disk_vs_raid(metadata_profile, data_profile,
1029                         dev_cnt, mixed, ssd);
1030         if (ret)
1031                 goto error;
1032
1033         dev_cnt--;
1034
1035         if (!source_dir_set) {
1036                 /*
1037                  * open without O_EXCL so that the problem should not
1038                  * occur by the following processing.
1039                  * (btrfs_register_one_device() fails if O_EXCL is on)
1040                  */
1041                 fd = open(file, O_RDWR);
1042                 if (fd < 0) {
1043                         error("unable to open %s: %s", file, strerror(errno));
1044                         goto error;
1045                 }
1046                 ret = btrfs_prepare_device(fd, file, &dev_block_count,
1047                                 block_count,
1048                                 (zero_end ? PREP_DEVICE_ZERO_END : 0) |
1049                                 (discard ? PREP_DEVICE_DISCARD : 0) |
1050                                 (verbose ? PREP_DEVICE_VERBOSE : 0));
1051                 if (ret) {
1052                         goto error;
1053                 }
1054                 if (block_count && block_count > dev_block_count) {
1055                         error("%s is smaller than requested size, expected %llu, found %llu",
1056                                         file,
1057                                         (unsigned long long)block_count,
1058                                         (unsigned long long)dev_block_count);
1059                         goto error;
1060                 }
1061         } else {
1062                 fd = open(file, O_CREAT | O_RDWR,
1063                                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
1064                 if (fd < 0) {
1065                         error("unable to open %s: %s", file, strerror(errno));
1066                         goto error;
1067                 }
1068
1069                 source_dir_size = btrfs_mkfs_size_dir(source_dir, sectorsize,
1070                                         &num_of_meta_chunks, &size_of_data);
1071                 if(block_count < source_dir_size)
1072                         block_count = source_dir_size;
1073                 ret = zero_output_file(fd, block_count);
1074                 if (ret) {
1075                         error("unable to zero the output file");
1076                         goto error;
1077                 }
1078                 /* our "device" is the new image file */
1079                 dev_block_count = block_count;
1080         }
1081
1082         /* To create the first block group and chunk 0 in make_btrfs */
1083         if (dev_block_count < BTRFS_MKFS_SYSTEM_GROUP_SIZE) {
1084                 error("device is too small to make filesystem, must be at least %llu",
1085                                 (unsigned long long)BTRFS_MKFS_SYSTEM_GROUP_SIZE);
1086                 goto error;
1087         }
1088
1089         if (group_profile_max_safe_loss(metadata_profile) <
1090                 group_profile_max_safe_loss(data_profile)){
1091                 warning("metadata has lower redundancy than data!\n");
1092         }
1093
1094         mkfs_cfg.label = label;
1095         memcpy(mkfs_cfg.fs_uuid, fs_uuid, sizeof(mkfs_cfg.fs_uuid));
1096         mkfs_cfg.num_bytes = dev_block_count;
1097         mkfs_cfg.nodesize = nodesize;
1098         mkfs_cfg.sectorsize = sectorsize;
1099         mkfs_cfg.stripesize = stripesize;
1100         mkfs_cfg.features = features;
1101
1102         ret = make_btrfs(fd, &mkfs_cfg);
1103         if (ret) {
1104                 error("error during mkfs: %s", strerror(-ret));
1105                 goto error;
1106         }
1107
1108         fs_info = open_ctree_fs_info(file, 0, 0, 0,
1109                         OPEN_CTREE_WRITES | OPEN_CTREE_FS_PARTIAL);
1110         if (!fs_info) {
1111                 error("open ctree failed");
1112                 goto error;
1113         }
1114         close(fd);
1115         fd = -1;
1116         root = fs_info->fs_root;
1117         fs_info->alloc_start = alloc_start;
1118
1119         ret = create_metadata_block_groups(root, mixed, &allocation);
1120         if (ret) {
1121                 error("failed to create default block groups: %d", ret);
1122                 goto error;
1123         }
1124
1125         trans = btrfs_start_transaction(root, 1);
1126         if (IS_ERR(trans)) {
1127                 error("failed to start transaction");
1128                 goto error;
1129         }
1130
1131         ret = create_data_block_groups(trans, root, mixed, &allocation);
1132         if (ret) {
1133                 error("failed to create default data block groups: %d", ret);
1134                 goto error;
1135         }
1136
1137         ret = make_root_dir(trans, root);
1138         if (ret) {
1139                 error("failed to setup the root directory: %d", ret);
1140                 goto error;
1141         }
1142
1143         ret = btrfs_commit_transaction(trans, root);
1144         if (ret) {
1145                 error("unable to commit transaction: %d", ret);
1146                 goto out;
1147         }
1148
1149         trans = btrfs_start_transaction(root, 1);
1150         if (IS_ERR(trans)) {
1151                 error("failed to start transaction");
1152                 goto error;
1153         }
1154
1155         if (dev_cnt == 0)
1156                 goto raid_groups;
1157
1158         while (dev_cnt-- > 0) {
1159                 file = argv[optind++];
1160
1161                 /*
1162                  * open without O_EXCL so that the problem should not
1163                  * occur by the following processing.
1164                  * (btrfs_register_one_device() fails if O_EXCL is on)
1165                  */
1166                 fd = open(file, O_RDWR);
1167                 if (fd < 0) {
1168                         error("unable to open %s: %s", file, strerror(errno));
1169                         goto error;
1170                 }
1171                 ret = btrfs_device_already_in_root(root, fd,
1172                                                    BTRFS_SUPER_INFO_OFFSET);
1173                 if (ret) {
1174                         error("skipping duplicate device %s in the filesystem",
1175                                 file);
1176                         close(fd);
1177                         continue;
1178                 }
1179                 ret = btrfs_prepare_device(fd, file, &dev_block_count,
1180                                 block_count,
1181                                 (verbose ? PREP_DEVICE_VERBOSE : 0) |
1182                                 (zero_end ? PREP_DEVICE_ZERO_END : 0) |
1183                                 (discard ? PREP_DEVICE_DISCARD : 0));
1184                 if (ret) {
1185                         goto error;
1186                 }
1187
1188                 ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count,
1189                                         sectorsize, sectorsize, sectorsize);
1190                 if (ret) {
1191                         error("unable to add %s to filesystem: %d", file, ret);
1192                         goto out;
1193                 }
1194                 if (verbose >= 2) {
1195                         struct btrfs_device *device;
1196
1197                         device = container_of(fs_info->fs_devices->devices.next,
1198                                         struct btrfs_device, dev_list);
1199                         printf("adding device %s id %llu\n", file,
1200                                 (unsigned long long)device->devid);
1201                 }
1202         }
1203
1204 raid_groups:
1205         if (!source_dir_set) {
1206                 ret = create_raid_groups(trans, root, data_profile,
1207                                  metadata_profile, mixed, &allocation);
1208                 if (ret) {
1209                         error("unable to create raid groups: %d", ret);
1210                         goto out;
1211                 }
1212         }
1213
1214         ret = create_tree(trans, root, BTRFS_DATA_RELOC_TREE_OBJECTID);
1215         if (ret) {
1216                 error("unable to create data reloc tree: %d", ret);
1217                 goto out;
1218         }
1219
1220         ret = btrfs_commit_transaction(trans, root);
1221         if (ret) {
1222                 error("unable to commit transaction: %d", ret);
1223                 goto out;
1224         }
1225
1226         if (source_dir_set) {
1227                 trans = btrfs_start_transaction(root, 1);
1228                 BUG_ON(IS_ERR(trans));
1229                 ret = create_chunks(trans, root,
1230                                     num_of_meta_chunks, size_of_data,
1231                                     &allocation);
1232                 if (ret) {
1233                         error("unable to create chunks: %d", ret);
1234                         goto out;
1235                 }
1236                 ret = btrfs_commit_transaction(trans, root);
1237                 if (ret) {
1238                         error("transaction commit failed: %d", ret);
1239                         goto out;
1240                 }
1241
1242                 ret = btrfs_mkfs_fill_dir(source_dir, root, verbose);
1243                 if (ret) {
1244                         error("error wihle filling filesystem: %d", ret);
1245                         goto out;
1246                 }
1247         }
1248         ret = cleanup_temp_chunks(fs_info, &allocation, data_profile,
1249                                   metadata_profile, metadata_profile);
1250         if (ret < 0) {
1251                 error("failed to cleanup temporary chunks: %d", ret);
1252                 goto out;
1253         }
1254
1255         if (verbose) {
1256                 char features_buf[64];
1257
1258                 update_chunk_allocation(fs_info, &allocation);
1259                 printf("Label:              %s\n", label);
1260                 printf("UUID:               %s\n", mkfs_cfg.fs_uuid);
1261                 printf("Node size:          %u\n", nodesize);
1262                 printf("Sector size:        %u\n", sectorsize);
1263                 printf("Filesystem size:    %s\n",
1264                         pretty_size(btrfs_super_total_bytes(fs_info->super_copy)));
1265                 printf("Block group profiles:\n");
1266                 if (allocation.data)
1267                         printf("  Data:             %-8s %16s\n",
1268                                 btrfs_group_profile_str(data_profile),
1269                                 pretty_size(allocation.data));
1270                 if (allocation.metadata)
1271                         printf("  Metadata:         %-8s %16s\n",
1272                                 btrfs_group_profile_str(metadata_profile),
1273                                 pretty_size(allocation.metadata));
1274                 if (allocation.mixed)
1275                         printf("  Data+Metadata:    %-8s %16s\n",
1276                                 btrfs_group_profile_str(data_profile),
1277                                 pretty_size(allocation.mixed));
1278                 printf("  System:           %-8s %16s\n",
1279                         btrfs_group_profile_str(metadata_profile),
1280                         pretty_size(allocation.system));
1281                 printf("SSD detected:       %s\n", ssd ? "yes" : "no");
1282                 btrfs_parse_features_to_string(features_buf, features);
1283                 printf("Incompat features:  %s", features_buf);
1284                 printf("\n");
1285
1286                 list_all_devices(root);
1287         }
1288
1289         /*
1290          * The filesystem is now fully set up, commit the remaining changes and
1291          * fix the signature as the last step before closing the devices.
1292          */
1293         fs_info->finalize_on_close = 1;
1294 out:
1295         close_ret = close_ctree(root);
1296
1297         if (!close_ret) {
1298                 optind = saved_optind;
1299                 dev_cnt = argc - optind;
1300                 while (dev_cnt-- > 0) {
1301                         file = argv[optind++];
1302                         if (is_block_device(file) == 1)
1303                                 btrfs_register_one_device(file);
1304                 }
1305         }
1306
1307         btrfs_close_all_devices();
1308         free(label);
1309
1310         return !!ret;
1311 error:
1312         if (fd > 0)
1313                 close(fd);
1314
1315         free(label);
1316         exit(1);
1317 success:
1318         exit(0);
1319 }