]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfs/xfs_mkfs.c
mkfs: getbool is redundant
[thirdparty/xfsprogs-dev.git] / mkfs / xfs_mkfs.c
1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libxfs.h"
20 #include <ctype.h>
21 #ifdef ENABLE_BLKID
22 # include <blkid/blkid.h>
23 #endif /* ENABLE_BLKID */
24 #include "xfs_multidisk.h"
25
26 /*
27 * Device topology information.
28 */
29 struct fs_topology {
30 int dsunit; /* stripe unit - data subvolume */
31 int dswidth; /* stripe width - data subvolume */
32 int rtswidth; /* stripe width - rt subvolume */
33 int lsectorsize; /* logical sector size &*/
34 int psectorsize; /* physical sector size */
35 };
36
37 /*
38 * Prototypes for internal functions.
39 */
40 static void conflict(char opt, char *tab[], int oldidx, int newidx);
41 static void illegal(const char *value, const char *opt);
42 static __attribute__((noreturn)) void usage (void);
43 static __attribute__((noreturn)) void reqval(char opt, char *tab[], int idx);
44 static void respec(char opt, char *tab[], int idx);
45 static void unknown(char opt, char *s);
46 static int ispow2(unsigned int i);
47
48 static long long cvtnum(unsigned int blocksize,
49 unsigned int sectorsize, const char *s);
50
51 #define MAX_SUBOPTS 16
52 #define SUBOPT_NEEDS_VAL (-1LL)
53 /*
54 * Table for parsing mkfs parameters.
55 *
56 * Description of the structure members follows:
57 *
58 * name MANDATORY
59 * Name is a single char, e.g., for '-d file', name is 'd'.
60 *
61 * subopts MANDATORY
62 * Subopts is a list of strings naming suboptions. In the example above,
63 * it would contain "file". The last entry of this list has to be NULL.
64 *
65 * subopt_params MANDATORY
66 * This is a list of structs tied with subopts. For each entry in subopts,
67 * a corresponding entry has to be defined:
68 *
69 * subopt_params struct:
70 * index MANDATORY
71 * This number, starting from zero, denotes which item in subopt_params
72 * it is. The index has to be the same as is the order in subopts list,
73 * so we can access the right item both in subopt_param and subopts.
74 *
75 * minval, maxval OPTIONAL
76 * These options are used for automatic range check and they have to be
77 * always used together in pair. If you don't want to limit the max value,
78 * use something like UINT_MAX. If no value is given, then you must either
79 * supply your own validation, or refuse any value in the 'case
80 * X_SOMETHING' block. If you forget to define the min and max value, but
81 * call a standard function for validating user's value, it will cause an
82 * error message notifying you about this issue.
83 *
84 * (Said in another way, you can't have minval and maxval both equal
85 * to zero. But if one value is different: minval=0 and maxval=1,
86 * then it is OK.)
87 *
88 * defaultval MANDATORY
89 * The value used if user specifies the subopt, but no value.
90 * If the subopt accepts some values (-d file=[1|0]), then this
91 * sets what is used with simple specifying the subopt (-d file).
92 * A special SUBOPT_NEEDS_VAL can be used to require a user-given
93 * value in any case.
94 */
95 struct opt_params {
96 const char name;
97 const char *subopts[MAX_SUBOPTS];
98 struct subopt_param {
99 int index;
100 long long minval;
101 long long maxval;
102 long long defaultval;
103 } subopt_params[MAX_SUBOPTS];
104 };
105
106 struct opt_params bopts = {
107 .name = 'b',
108 .subopts = {
109 #define B_LOG 0
110 "log",
111 #define B_SIZE 1
112 "size",
113 NULL
114 },
115 .subopt_params = {
116 { .index = B_LOG,
117 .minval = XFS_MIN_BLOCKSIZE_LOG,
118 .maxval = XFS_MAX_BLOCKSIZE_LOG,
119 .defaultval = SUBOPT_NEEDS_VAL,
120 },
121 { .index = B_SIZE,
122 .minval = XFS_MIN_BLOCKSIZE,
123 .maxval = XFS_MAX_BLOCKSIZE,
124 .defaultval = SUBOPT_NEEDS_VAL,
125 },
126 },
127 };
128
129 struct opt_params dopts = {
130 .name = 'd',
131 .subopts = {
132 #define D_AGCOUNT 0
133 "agcount",
134 #define D_FILE 1
135 "file",
136 #define D_NAME 2
137 "name",
138 #define D_SIZE 3
139 "size",
140 #define D_SUNIT 4
141 "sunit",
142 #define D_SWIDTH 5
143 "swidth",
144 #define D_AGSIZE 6
145 "agsize",
146 #define D_SU 7
147 "su",
148 #define D_SW 8
149 "sw",
150 #define D_SECTLOG 9
151 "sectlog",
152 #define D_SECTSIZE 10
153 "sectsize",
154 #define D_NOALIGN 11
155 "noalign",
156 #define D_RTINHERIT 12
157 "rtinherit",
158 #define D_PROJINHERIT 13
159 "projinherit",
160 #define D_EXTSZINHERIT 14
161 "extszinherit",
162 NULL
163 },
164 .subopt_params = {
165 { .index = D_AGCOUNT,
166 .defaultval = SUBOPT_NEEDS_VAL,
167 },
168 { .index = D_FILE,
169 .minval = 0,
170 .maxval = 1,
171 .defaultval = 1,
172 },
173 { .index = D_NAME,
174 .defaultval = SUBOPT_NEEDS_VAL,
175 },
176 { .index = D_SIZE,
177 .defaultval = SUBOPT_NEEDS_VAL,
178 },
179 { .index = D_SUNIT,
180 .defaultval = SUBOPT_NEEDS_VAL,
181 },
182 { .index = D_SWIDTH,
183 .defaultval = SUBOPT_NEEDS_VAL,
184 },
185 { .index = D_AGSIZE,
186 .defaultval = SUBOPT_NEEDS_VAL,
187 },
188 { .index = D_SU,
189 .defaultval = SUBOPT_NEEDS_VAL,
190 },
191 { .index = D_SW,
192 .defaultval = SUBOPT_NEEDS_VAL,
193 },
194 { .index = D_SECTLOG,
195 .minval = XFS_MIN_SECTORSIZE_LOG,
196 .maxval = XFS_MAX_SECTORSIZE_LOG,
197 .defaultval = SUBOPT_NEEDS_VAL,
198 },
199 { .index = D_SECTSIZE,
200 .minval = XFS_MIN_SECTORSIZE,
201 .maxval = XFS_MAX_SECTORSIZE,
202 .defaultval = SUBOPT_NEEDS_VAL,
203 },
204 { .index = D_NOALIGN,
205 .minval = 0,
206 .maxval = 1,
207 .defaultval = 1,
208 },
209 { .index = D_RTINHERIT,
210 .defaultval = SUBOPT_NEEDS_VAL,
211 },
212 { .index = D_PROJINHERIT,
213 .defaultval = SUBOPT_NEEDS_VAL,
214 },
215 { .index = D_EXTSZINHERIT,
216 .defaultval = SUBOPT_NEEDS_VAL,
217 },
218 },
219 };
220
221
222 struct opt_params iopts = {
223 .name = 'i',
224 .subopts = {
225 #define I_ALIGN 0
226 "align",
227 #define I_LOG 1
228 "log",
229 #define I_MAXPCT 2
230 "maxpct",
231 #define I_PERBLOCK 3
232 "perblock",
233 #define I_SIZE 4
234 "size",
235 #define I_ATTR 5
236 "attr",
237 #define I_PROJID32BIT 6
238 "projid32bit",
239 #define I_SPINODES 7
240 "sparse",
241 NULL
242 },
243 .subopt_params = {
244 { .index = I_ALIGN,
245 .minval = 0,
246 .maxval = 1,
247 .defaultval = 1,
248 },
249 { .index = I_LOG,
250 .minval = XFS_DINODE_MIN_LOG,
251 .maxval = XFS_DINODE_MAX_LOG,
252 .defaultval = SUBOPT_NEEDS_VAL,
253 },
254 { .index = I_MAXPCT,
255 .defaultval = SUBOPT_NEEDS_VAL,
256 },
257 { .index = I_PERBLOCK,
258 .defaultval = SUBOPT_NEEDS_VAL,
259 },
260 { .index = I_SIZE,
261 .defaultval = SUBOPT_NEEDS_VAL,
262 },
263 { .index = I_ATTR,
264 .defaultval = SUBOPT_NEEDS_VAL,
265 },
266 { .index = I_PROJID32BIT,
267 .minval = 0,
268 .maxval = 1,
269 .defaultval = 1,
270 },
271 { .index = I_SPINODES,
272 .minval = 0,
273 .maxval = 1,
274 .defaultval = 1,
275 },
276 },
277 };
278
279 struct opt_params lopts = {
280 .name = 'l',
281 .subopts = {
282 #define L_AGNUM 0
283 "agnum",
284 #define L_INTERNAL 1
285 "internal",
286 #define L_SIZE 2
287 "size",
288 #define L_VERSION 3
289 "version",
290 #define L_SUNIT 4
291 "sunit",
292 #define L_SU 5
293 "su",
294 #define L_DEV 6
295 "logdev",
296 #define L_SECTLOG 7
297 "sectlog",
298 #define L_SECTSIZE 8
299 "sectsize",
300 #define L_FILE 9
301 "file",
302 #define L_NAME 10
303 "name",
304 #define L_LAZYSBCNTR 11
305 "lazy-count",
306 NULL
307 },
308 .subopt_params = {
309 { .index = L_AGNUM,
310 .defaultval = SUBOPT_NEEDS_VAL,
311 },
312 { .index = L_INTERNAL,
313 .minval = 0,
314 .maxval = 1,
315 .defaultval = 1,
316 },
317 { .index = L_SIZE,
318 .defaultval = SUBOPT_NEEDS_VAL,
319 },
320 { .index = L_VERSION,
321 .defaultval = SUBOPT_NEEDS_VAL,
322 },
323 { .index = L_SUNIT,
324 .defaultval = SUBOPT_NEEDS_VAL,
325 },
326 { .index = L_SU,
327 .defaultval = SUBOPT_NEEDS_VAL,
328 },
329 { .index = L_DEV,
330 .defaultval = SUBOPT_NEEDS_VAL,
331 },
332 { .index = L_SECTLOG,
333 .minval = XFS_MIN_SECTORSIZE_LOG,
334 .maxval = XFS_MAX_SECTORSIZE_LOG,
335 .defaultval = SUBOPT_NEEDS_VAL,
336 },
337 { .index = L_SECTSIZE,
338 .minval = XFS_MIN_SECTORSIZE,
339 .maxval = XFS_MAX_SECTORSIZE,
340 .defaultval = SUBOPT_NEEDS_VAL,
341 },
342 { .index = L_FILE,
343 .minval = 0,
344 .maxval = 1,
345 .defaultval = 1,
346 },
347 { .index = L_NAME,
348 .defaultval = SUBOPT_NEEDS_VAL,
349 },
350 { .index = L_LAZYSBCNTR,
351 .minval = 0,
352 .maxval = 1,
353 .defaultval = 1,
354 },
355 },
356 };
357
358 struct opt_params nopts = {
359 .name = 'n',
360 .subopts = {
361 #define N_LOG 0
362 "log",
363 #define N_SIZE 1
364 "size",
365 #define N_VERSION 2
366 "version",
367 #define N_FTYPE 3
368 "ftype",
369 NULL,
370 },
371 .subopt_params = {
372 { .index = N_LOG,
373 .minval = XFS_MIN_REC_DIRSIZE,
374 .maxval = XFS_MAX_BLOCKSIZE_LOG,
375 .defaultval = SUBOPT_NEEDS_VAL,
376 },
377 { .index = N_SIZE,
378 .minval = 1 << XFS_MIN_REC_DIRSIZE,
379 .maxval = XFS_MAX_BLOCKSIZE,
380 .defaultval = SUBOPT_NEEDS_VAL,
381 },
382 { .index = N_VERSION,
383 .defaultval = SUBOPT_NEEDS_VAL,
384 },
385 { .index = N_FTYPE,
386 .minval = 0,
387 .maxval = 1,
388 .defaultval = 1,
389 },
390 },
391 };
392
393 struct opt_params ropts = {
394 .name = 'r',
395 .subopts = {
396 #define R_EXTSIZE 0
397 "extsize",
398 #define R_SIZE 1
399 "size",
400 #define R_DEV 2
401 "rtdev",
402 #define R_FILE 3
403 "file",
404 #define R_NAME 4
405 "name",
406 #define R_NOALIGN 5
407 "noalign",
408 NULL
409 },
410 .subopt_params = {
411 { .index = R_EXTSIZE,
412 .defaultval = SUBOPT_NEEDS_VAL,
413 },
414 { .index = R_SIZE,
415 .defaultval = SUBOPT_NEEDS_VAL,
416 },
417 { .index = R_DEV,
418 .defaultval = SUBOPT_NEEDS_VAL,
419 },
420 { .index = R_FILE,
421 .minval = 0,
422 .maxval = 1,
423 .defaultval = 1,
424 },
425 { .index = R_NAME,
426 .defaultval = SUBOPT_NEEDS_VAL,
427 },
428 { .index = R_NOALIGN,
429 .minval = 0,
430 .maxval = 1,
431 .defaultval = 1,
432 },
433 },
434 };
435
436 struct opt_params sopts = {
437 .name = 's',
438 .subopts = {
439 #define S_LOG 0
440 "log",
441 #define S_SECTLOG 1
442 "sectlog",
443 #define S_SIZE 2
444 "size",
445 #define S_SECTSIZE 3
446 "sectsize",
447 NULL
448 },
449 .subopt_params = {
450 { .index = S_LOG,
451 .minval = XFS_MIN_SECTORSIZE_LOG,
452 .maxval = XFS_MAX_SECTORSIZE_LOG,
453 .defaultval = SUBOPT_NEEDS_VAL,
454 },
455 { .index = S_SECTLOG,
456 .minval = XFS_MIN_SECTORSIZE_LOG,
457 .maxval = XFS_MAX_SECTORSIZE_LOG,
458 .defaultval = SUBOPT_NEEDS_VAL,
459 },
460 { .index = S_SIZE,
461 .minval = XFS_MIN_SECTORSIZE,
462 .maxval = XFS_MAX_SECTORSIZE,
463 .defaultval = SUBOPT_NEEDS_VAL,
464 },
465 { .index = S_SECTSIZE,
466 .minval = XFS_MIN_SECTORSIZE,
467 .maxval = XFS_MAX_SECTORSIZE,
468 .defaultval = SUBOPT_NEEDS_VAL,
469 },
470 },
471 };
472
473 struct opt_params mopts = {
474 .name = 'm',
475 .subopts = {
476 #define M_CRC 0
477 "crc",
478 #define M_FINOBT 1
479 "finobt",
480 #define M_UUID 2
481 "uuid",
482 NULL
483 },
484 .subopt_params = {
485 { .index = M_CRC,
486 .minval = 0,
487 .maxval = 1,
488 .defaultval = 1,
489 },
490 { .index = M_FINOBT,
491 .minval = 0,
492 .maxval = 1,
493 .defaultval = 1,
494 },
495 { .index = M_UUID,
496 .defaultval = SUBOPT_NEEDS_VAL,
497 },
498 },
499 };
500
501 #define TERABYTES(count, blog) ((__uint64_t)(count) << (40 - (blog)))
502 #define GIGABYTES(count, blog) ((__uint64_t)(count) << (30 - (blog)))
503 #define MEGABYTES(count, blog) ((__uint64_t)(count) << (20 - (blog)))
504
505 /*
506 * Use this macro before we have superblock and mount structure
507 */
508 #define DTOBT(d) ((xfs_rfsblock_t)((d) >> (blocklog - BBSHIFT)))
509
510 /*
511 * Use this for block reservations needed for mkfs's conditions
512 * (basically no fragmentation).
513 */
514 #define MKFS_BLOCKRES_INODE \
515 ((uint)(mp->m_ialloc_blks + (mp->m_in_maxlevels - 1)))
516 #define MKFS_BLOCKRES(rb) \
517 ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \
518 (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
519
520 /* amount (in bytes) we zero at the beginning and end of the device to
521 * remove traces of other filesystems, raid superblocks, etc.
522 */
523 #define WHACK_SIZE (128 * 1024)
524
525 static void
526 calc_stripe_factors(
527 int dsu,
528 int dsw,
529 int dsectsz,
530 int lsu,
531 int lsectsz,
532 int *dsunit,
533 int *dswidth,
534 int *lsunit)
535 {
536 /* Handle data sunit/swidth options */
537 if (*dsunit || *dswidth) {
538 if (dsu || dsw) {
539 fprintf(stderr,
540 _("data su/sw must not be used in "
541 "conjunction with data sunit/swidth\n"));
542 usage();
543 }
544
545 if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) {
546 fprintf(stderr,
547 _("both data sunit and data swidth options "
548 "must be specified\n"));
549 usage();
550 }
551 }
552
553 if (dsu || dsw) {
554 if (*dsunit || *dswidth) {
555 fprintf(stderr,
556 _("data sunit/swidth must not be used in "
557 "conjunction with data su/sw\n"));
558 usage();
559 }
560
561 if ((dsu && !dsw) || (!dsu && dsw)) {
562 fprintf(stderr,
563 _("both data su and data sw options "
564 "must be specified\n"));
565 usage();
566 }
567
568 if (dsu % dsectsz) {
569 fprintf(stderr,
570 _("data su must be a multiple of the "
571 "sector size (%d)\n"), dsectsz);
572 usage();
573 }
574
575 *dsunit = (int)BTOBBT(dsu);
576 *dswidth = *dsunit * dsw;
577 }
578
579 if (*dsunit && (*dswidth % *dsunit != 0)) {
580 fprintf(stderr,
581 _("data stripe width (%d) must be a multiple of the "
582 "data stripe unit (%d)\n"), *dswidth, *dsunit);
583 usage();
584 }
585
586 /* Handle log sunit options */
587
588 if (*lsunit) {
589 if (lsu) {
590 fprintf(stderr,
591 _("log su should not be used in "
592 "conjunction with log sunit\n"));
593 usage();
594 }
595 }
596
597 if (lsu) {
598 if (*lsunit) {
599 fprintf(stderr,
600 _("log sunit should not be used in "
601 "conjunction with log su\n"));
602 usage();
603 }
604 *lsunit = (int)BTOBBT(lsu);
605 }
606 }
607
608 /*
609 * Check for existing filesystem or partition table on device.
610 * Returns:
611 * 1 for existing fs or partition
612 * 0 for nothing found
613 * -1 for internal error
614 */
615 #ifdef ENABLE_BLKID
616 static int
617 check_overwrite(
618 char *device)
619 {
620 const char *type;
621 blkid_probe pr = NULL;
622 int ret;
623 int fd;
624 long long size;
625 int bsz;
626
627 if (!device || !*device)
628 return 0;
629
630 ret = -1; /* will reset on success of all setup calls */
631
632 fd = open(device, O_RDONLY);
633 if (fd < 0)
634 goto out;
635 platform_findsizes(device, fd, &size, &bsz);
636 close(fd);
637
638 /* nothing to overwrite on a 0-length device */
639 if (size == 0) {
640 ret = 0;
641 goto out;
642 }
643
644 pr = blkid_new_probe_from_filename(device);
645 if (!pr)
646 goto out;
647
648 ret = blkid_probe_enable_partitions(pr, 1);
649 if (ret < 0)
650 goto out;
651
652 ret = blkid_do_fullprobe(pr);
653 if (ret < 0)
654 goto out;
655
656 /*
657 * Blkid returns 1 for nothing found and 0 when it finds a signature,
658 * but we want the exact opposite, so reverse the return value here.
659 *
660 * In addition print some useful diagnostics about what actually is
661 * on the device.
662 */
663 if (ret) {
664 ret = 0;
665 goto out;
666 }
667
668 if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
669 fprintf(stderr,
670 _("%s: %s appears to contain an existing "
671 "filesystem (%s).\n"), progname, device, type);
672 } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
673 fprintf(stderr,
674 _("%s: %s appears to contain a partition "
675 "table (%s).\n"), progname, device, type);
676 } else {
677 fprintf(stderr,
678 _("%s: %s appears to contain something weird "
679 "according to blkid\n"), progname, device);
680 }
681 ret = 1;
682
683 out:
684 if (pr)
685 blkid_free_probe(pr);
686 if (ret == -1)
687 fprintf(stderr,
688 _("%s: probe of %s failed, cannot detect "
689 "existing filesystem.\n"), progname, device);
690 return ret;
691 }
692
693 static void blkid_get_topology(
694 const char *device,
695 int *sunit,
696 int *swidth,
697 int *lsectorsize,
698 int *psectorsize,
699 int force_overwrite)
700 {
701
702 blkid_topology tp;
703 blkid_probe pr;
704 unsigned long val;
705 struct stat statbuf;
706
707 /* can't get topology info from a file */
708 if (!stat(device, &statbuf) && S_ISREG(statbuf.st_mode))
709 return;
710
711 pr = blkid_new_probe_from_filename(device);
712 if (!pr)
713 return;
714
715 tp = blkid_probe_get_topology(pr);
716 if (!tp)
717 goto out_free_probe;
718
719 val = blkid_topology_get_logical_sector_size(tp);
720 *lsectorsize = val;
721 val = blkid_topology_get_physical_sector_size(tp);
722 *psectorsize = val;
723 val = blkid_topology_get_minimum_io_size(tp);
724 *sunit = val;
725 val = blkid_topology_get_optimal_io_size(tp);
726 *swidth = val;
727
728 /*
729 * If the reported values are the same as the physical sector size
730 * do not bother to report anything. It will only cause warnings
731 * if people specify larger stripe units or widths manually.
732 */
733 if (*sunit == *psectorsize || *swidth == *psectorsize) {
734 *sunit = 0;
735 *swidth = 0;
736 }
737
738 /*
739 * Blkid reports the information in terms of bytes, but we want it in
740 * terms of 512 bytes blocks (only to convert it to bytes later..)
741 */
742 *sunit = *sunit >> 9;
743 *swidth = *swidth >> 9;
744
745 if (blkid_topology_get_alignment_offset(tp) != 0) {
746 fprintf(stderr,
747 _("warning: device is not properly aligned %s\n"),
748 device);
749
750 if (!force_overwrite) {
751 fprintf(stderr,
752 _("Use -f to force usage of a misaligned device\n"));
753
754 exit(EXIT_FAILURE);
755 }
756 /* Do not use physical sector size if the device is misaligned */
757 *psectorsize = *lsectorsize;
758 }
759
760 blkid_free_probe(pr);
761 return;
762
763 out_free_probe:
764 blkid_free_probe(pr);
765 fprintf(stderr,
766 _("warning: unable to probe device topology for device %s\n"),
767 device);
768 }
769 #else /* ifdef ENABLE_BLKID */
770 /*
771 * Without blkid, we can't do a good check for signatures.
772 * So instead of some messy attempts, just disable any checks
773 * and always return 'nothing found'.
774 */
775 # warning BLKID is disabled, so signature detection and block device\
776 access are not working!
777 static int
778 check_overwrite(
779 char *device)
780 {
781 return 1;
782 }
783
784 static void blkid_get_topology(
785 const char *device,
786 int *sunit,
787 int *swidth,
788 int *lsectorsize,
789 int *psectorsize,
790 int force_overwrite)
791 {
792 /*
793 * Shouldn't make any difference (no blkid = no block device access),
794 * but make sure this dummy replacement returns with at least some
795 * sanity.
796 */
797 *lsectorsize = *psectorsize = 512;
798 }
799
800 #endif /* ENABLE_BLKID */
801
802 static void get_topology(
803 libxfs_init_t *xi,
804 struct fs_topology *ft,
805 int force_overwrite)
806 {
807 struct stat statbuf;
808 char *dfile = xi->volname ? xi->volname : xi->dname;
809
810 /*
811 * If our target is a regular file, use platform_findsizes
812 * to try to obtain the underlying filesystem's requirements
813 * for direct IO; we'll set our sector size to that if possible.
814 */
815 if (xi->disfile ||
816 (!stat(dfile, &statbuf) && S_ISREG(statbuf.st_mode))) {
817 int fd;
818 int flags = O_RDONLY;
819 long long dummy;
820
821 /* with xi->disfile we may not have the file yet! */
822 if (xi->disfile)
823 flags |= O_CREAT;
824
825 fd = open(dfile, flags, 0666);
826 if (fd >= 0) {
827 platform_findsizes(dfile, fd, &dummy, &ft->lsectorsize);
828 close(fd);
829 ft->psectorsize = ft->lsectorsize;
830 } else
831 ft->psectorsize = ft->lsectorsize = BBSIZE;
832 } else {
833 blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth,
834 &ft->lsectorsize, &ft->psectorsize,
835 force_overwrite);
836 }
837
838 if (xi->rtname && !xi->risfile) {
839 int sunit, lsectorsize, psectorsize;
840
841 blkid_get_topology(xi->rtname, &sunit, &ft->rtswidth,
842 &lsectorsize, &psectorsize, force_overwrite);
843 }
844 }
845
846 static void
847 fixup_log_stripe_unit(
848 int lsflag,
849 int sunit,
850 xfs_rfsblock_t *logblocks,
851 int blocklog)
852 {
853 __uint64_t tmp_logblocks;
854
855 /*
856 * Make sure that the log size is a multiple of the stripe unit
857 */
858 if ((*logblocks % sunit) != 0) {
859 if (!lsflag) {
860 tmp_logblocks = ((*logblocks + (sunit - 1))
861 / sunit) * sunit;
862 /*
863 * If the log is too large, round down
864 * instead of round up
865 */
866 if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) ||
867 ((tmp_logblocks << blocklog) > XFS_MAX_LOG_BYTES)) {
868 tmp_logblocks = (*logblocks / sunit) * sunit;
869 }
870 *logblocks = tmp_logblocks;
871 } else {
872 fprintf(stderr, _("log size %lld is not a multiple "
873 "of the log stripe unit %d\n"),
874 (long long) *logblocks, sunit);
875 usage();
876 }
877 }
878 }
879
880 static xfs_fsblock_t
881 fixup_internal_log_stripe(
882 xfs_mount_t *mp,
883 int lsflag,
884 xfs_fsblock_t logstart,
885 __uint64_t agsize,
886 int sunit,
887 xfs_rfsblock_t *logblocks,
888 int blocklog,
889 int *lalign)
890 {
891 if ((logstart % sunit) != 0) {
892 logstart = ((logstart + (sunit - 1))/sunit) * sunit;
893 *lalign = 1;
894 }
895
896 fixup_log_stripe_unit(lsflag, sunit, logblocks, blocklog);
897
898 if (*logblocks > agsize - XFS_FSB_TO_AGBNO(mp, logstart)) {
899 fprintf(stderr,
900 _("Due to stripe alignment, the internal log size "
901 "(%lld) is too large.\n"), (long long) *logblocks);
902 fprintf(stderr, _("Must fit within an allocation group.\n"));
903 usage();
904 }
905 return logstart;
906 }
907
908 void
909 validate_log_size(__uint64_t logblocks, int blocklog, int min_logblocks)
910 {
911 if (logblocks < min_logblocks) {
912 fprintf(stderr,
913 _("log size %lld blocks too small, minimum size is %d blocks\n"),
914 (long long)logblocks, min_logblocks);
915 usage();
916 }
917 if (logblocks > XFS_MAX_LOG_BLOCKS) {
918 fprintf(stderr,
919 _("log size %lld blocks too large, maximum size is %lld blocks\n"),
920 (long long)logblocks, XFS_MAX_LOG_BLOCKS);
921 usage();
922 }
923 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
924 fprintf(stderr,
925 _("log size %lld bytes too large, maximum size is %lld bytes\n"),
926 (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES);
927 usage();
928 }
929 }
930
931 static int
932 calc_default_imaxpct(
933 int blocklog,
934 __uint64_t dblocks)
935 {
936 /*
937 * This returns the % of the disk space that is used for
938 * inodes, it changes relatively to the FS size:
939 * - over 50 TB, use 1%,
940 * - 1TB - 50 TB, use 5%,
941 * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%).
942 */
943
944 if (dblocks < TERABYTES(1, blocklog)) {
945 return XFS_DFL_IMAXIMUM_PCT;
946 } else if (dblocks < TERABYTES(50, blocklog)) {
947 return 5;
948 }
949
950 return 1;
951 }
952
953
954 void
955 calc_default_ag_geometry(
956 int blocklog,
957 __uint64_t dblocks,
958 int multidisk,
959 __uint64_t *agsize,
960 __uint64_t *agcount)
961 {
962 __uint64_t blocks = 0;
963 int shift = 0;
964
965 /*
966 * First handle the high extreme - the point at which we will
967 * always use the maximum AG size.
968 *
969 * This applies regardless of storage configuration.
970 */
971 if (dblocks >= TERABYTES(32, blocklog)) {
972 blocks = XFS_AG_MAX_BLOCKS(blocklog);
973 goto done;
974 }
975
976 /*
977 * For a single underlying storage device over 4TB in size
978 * use the maximum AG size. Between 128MB and 4TB, just use
979 * 4 AGs and scale up smoothly between min/max AG sizes.
980 */
981 if (!multidisk) {
982 if (dblocks >= TERABYTES(4, blocklog)) {
983 blocks = XFS_AG_MAX_BLOCKS(blocklog);
984 goto done;
985 } else if (dblocks >= MEGABYTES(128, blocklog)) {
986 shift = XFS_NOMULTIDISK_AGLOG;
987 goto calc_blocks;
988 }
989 }
990
991 /*
992 * For the multidisk configs we choose an AG count based on the number
993 * of data blocks available, trying to keep the number of AGs higher
994 * than the single disk configurations. This makes the assumption that
995 * larger filesystems have more parallelism available to them.
996 */
997 shift = XFS_MULTIDISK_AGLOG;
998 if (dblocks <= GIGABYTES(512, blocklog))
999 shift--;
1000 if (dblocks <= GIGABYTES(8, blocklog))
1001 shift--;
1002 if (dblocks < MEGABYTES(128, blocklog))
1003 shift--;
1004 if (dblocks < MEGABYTES(64, blocklog))
1005 shift--;
1006 if (dblocks < MEGABYTES(32, blocklog))
1007 shift--;
1008
1009 /*
1010 * If dblocks is not evenly divisible by the number of
1011 * desired AGs, round "blocks" up so we don't lose the
1012 * last bit of the filesystem. The same principle applies
1013 * to the AG count, so we don't lose the last AG!
1014 */
1015 calc_blocks:
1016 ASSERT(shift >= 0 && shift <= XFS_MULTIDISK_AGLOG);
1017 blocks = dblocks >> shift;
1018 if (dblocks & xfs_mask32lo(shift)) {
1019 if (blocks < XFS_AG_MAX_BLOCKS(blocklog))
1020 blocks++;
1021 }
1022 done:
1023 *agsize = blocks;
1024 *agcount = dblocks / blocks + (dblocks % blocks != 0);
1025 }
1026
1027 static void
1028 validate_ag_geometry(
1029 int blocklog,
1030 __uint64_t dblocks,
1031 __uint64_t agsize,
1032 __uint64_t agcount)
1033 {
1034 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
1035 fprintf(stderr,
1036 _("agsize (%lld blocks) too small, need at least %lld blocks\n"),
1037 (long long)agsize,
1038 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1039 usage();
1040 }
1041
1042 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
1043 fprintf(stderr,
1044 _("agsize (%lld blocks) too big, maximum is %lld blocks\n"),
1045 (long long)agsize,
1046 (long long)XFS_AG_MAX_BLOCKS(blocklog));
1047 usage();
1048 }
1049
1050 if (agsize > dblocks) {
1051 fprintf(stderr,
1052 _("agsize (%lld blocks) too big, data area is %lld blocks\n"),
1053 (long long)agsize, (long long)dblocks);
1054 usage();
1055 }
1056
1057 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
1058 fprintf(stderr,
1059 _("too many allocation groups for size = %lld\n"),
1060 (long long)agsize);
1061 fprintf(stderr, _("need at most %lld allocation groups\n"),
1062 (long long)(dblocks / XFS_AG_MIN_BLOCKS(blocklog) +
1063 (dblocks % XFS_AG_MIN_BLOCKS(blocklog) != 0)));
1064 usage();
1065 }
1066
1067 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
1068 fprintf(stderr,
1069 _("too few allocation groups for size = %lld\n"), (long long)agsize);
1070 fprintf(stderr,
1071 _("need at least %lld allocation groups\n"),
1072 (long long)(dblocks / XFS_AG_MAX_BLOCKS(blocklog) +
1073 (dblocks % XFS_AG_MAX_BLOCKS(blocklog) != 0)));
1074 usage();
1075 }
1076
1077 /*
1078 * If the last AG is too small, reduce the filesystem size
1079 * and drop the blocks.
1080 */
1081 if ( dblocks % agsize != 0 &&
1082 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
1083 fprintf(stderr,
1084 _("last AG size %lld blocks too small, minimum size is %lld blocks\n"),
1085 (long long)(dblocks % agsize),
1086 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1087 usage();
1088 }
1089
1090 /*
1091 * If agcount is too large, make it smaller.
1092 */
1093 if (agcount > XFS_MAX_AGNUMBER + 1) {
1094 fprintf(stderr,
1095 _("%lld allocation groups is too many, maximum is %lld\n"),
1096 (long long)agcount, (long long)XFS_MAX_AGNUMBER + 1);
1097 usage();
1098 }
1099 }
1100
1101 static void
1102 zero_old_xfs_structures(
1103 libxfs_init_t *xi,
1104 xfs_sb_t *new_sb)
1105 {
1106 void *buf;
1107 xfs_sb_t sb;
1108 __uint32_t bsize;
1109 int i;
1110 xfs_off_t off;
1111 int tmp;
1112
1113 /*
1114 * We open regular files with O_TRUNC|O_CREAT. Nothing to do here...
1115 */
1116 if (xi->disfile && xi->dcreat)
1117 return;
1118
1119 /*
1120 * read in existing filesystem superblock, use its geometry
1121 * settings and zero the existing secondary superblocks.
1122 */
1123 buf = memalign(libxfs_device_alignment(), new_sb->sb_sectsize);
1124 if (!buf) {
1125 fprintf(stderr,
1126 _("error reading existing superblock -- failed to memalign buffer\n"));
1127 return;
1128 }
1129 memset(buf, 0, new_sb->sb_sectsize);
1130
1131 tmp = pread(xi->dfd, buf, new_sb->sb_sectsize, 0);
1132 if (tmp < 0) {
1133 fprintf(stderr, _("existing superblock read failed: %s\n"),
1134 strerror(errno));
1135 goto done;
1136 }
1137 if (tmp != new_sb->sb_sectsize) {
1138 fprintf(stderr,
1139 _("warning: could not read existing superblock, skip zeroing\n"));
1140 goto done;
1141 }
1142 libxfs_sb_from_disk(&sb, buf);
1143
1144 /*
1145 * perform same basic superblock validation to make sure we
1146 * actually zero secondary blocks
1147 */
1148 if (sb.sb_magicnum != XFS_SB_MAGIC || sb.sb_blocksize == 0)
1149 goto done;
1150
1151 for (bsize = 1, i = 0; bsize < sb.sb_blocksize &&
1152 i < sizeof(sb.sb_blocksize) * NBBY; i++)
1153 bsize <<= 1;
1154
1155 if (i < XFS_MIN_BLOCKSIZE_LOG || i > XFS_MAX_BLOCKSIZE_LOG ||
1156 i != sb.sb_blocklog)
1157 goto done;
1158
1159 if (sb.sb_dblocks > ((__uint64_t)sb.sb_agcount * sb.sb_agblocks) ||
1160 sb.sb_dblocks < ((__uint64_t)(sb.sb_agcount - 1) *
1161 sb.sb_agblocks + XFS_MIN_AG_BLOCKS))
1162 goto done;
1163
1164 /*
1165 * block size and basic geometry seems alright, zero the secondaries.
1166 */
1167 memset(buf, 0, new_sb->sb_sectsize);
1168 off = 0;
1169 for (i = 1; i < sb.sb_agcount; i++) {
1170 off += sb.sb_agblocks;
1171 if (pwrite64(xi->dfd, buf, new_sb->sb_sectsize,
1172 off << sb.sb_blocklog) == -1)
1173 break;
1174 }
1175 done:
1176 free(buf);
1177 }
1178
1179 static void
1180 discard_blocks(dev_t dev, __uint64_t nsectors)
1181 {
1182 int fd;
1183
1184 /*
1185 * We intentionally ignore errors from the discard ioctl. It is
1186 * not necessary for the mkfs functionality but just an optimization.
1187 */
1188 fd = libxfs_device_to_fd(dev);
1189 if (fd > 0)
1190 platform_discard_blocks(fd, 0, nsectors << 9);
1191 }
1192
1193 struct sb_feat_args {
1194 int log_version;
1195 int attr_version;
1196 int dir_version;
1197 int spinodes;
1198 int finobt;
1199 bool finobtflag;
1200 bool inode_align;
1201 bool nci;
1202 bool lazy_sb_counters;
1203 bool projid16bit;
1204 bool crcs_enabled;
1205 bool dirftype;
1206 bool parent_pointers;
1207 };
1208
1209 static void
1210 sb_set_features(
1211 struct xfs_sb *sbp,
1212 struct sb_feat_args *fp,
1213 int sectsize,
1214 int lsectsize,
1215 int dsunit)
1216 {
1217
1218 sbp->sb_versionnum = XFS_DFL_SB_VERSION_BITS;
1219 if (fp->crcs_enabled)
1220 sbp->sb_versionnum |= XFS_SB_VERSION_5;
1221 else
1222 sbp->sb_versionnum |= XFS_SB_VERSION_4;
1223
1224 if (fp->inode_align)
1225 sbp->sb_versionnum |= XFS_SB_VERSION_ALIGNBIT;
1226 if (dsunit)
1227 sbp->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT;
1228 if (fp->log_version == 2)
1229 sbp->sb_versionnum |= XFS_SB_VERSION_LOGV2BIT;
1230 if (fp->attr_version == 1)
1231 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
1232 if (sectsize > BBSIZE || lsectsize > BBSIZE)
1233 sbp->sb_versionnum |= XFS_SB_VERSION_SECTORBIT;
1234 if (fp->nci)
1235 sbp->sb_versionnum |= XFS_SB_VERSION_BORGBIT;
1236
1237
1238 sbp->sb_features2 = 0;
1239 if (fp->lazy_sb_counters)
1240 sbp->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
1241 if (!fp->projid16bit)
1242 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
1243 if (fp->parent_pointers)
1244 sbp->sb_features2 |= XFS_SB_VERSION2_PARENTBIT;
1245 if (fp->crcs_enabled)
1246 sbp->sb_features2 |= XFS_SB_VERSION2_CRCBIT;
1247 if (fp->attr_version == 2)
1248 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
1249
1250 /* v5 superblocks have their own feature bit for dirftype */
1251 if (fp->dirftype && !fp->crcs_enabled)
1252 sbp->sb_features2 |= XFS_SB_VERSION2_FTYPE;
1253
1254 /* update whether extended features are in use */
1255 if (sbp->sb_features2 != 0)
1256 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
1257
1258 /*
1259 * Due to a structure alignment issue, sb_features2 ended up in one
1260 * of two locations, the second "incorrect" location represented by
1261 * the sb_bad_features2 field. To avoid older kernels mounting
1262 * filesystems they shouldn't, set both field to the same value.
1263 */
1264 sbp->sb_bad_features2 = sbp->sb_features2;
1265
1266 if (!fp->crcs_enabled)
1267 return;
1268
1269 /* default features for v5 filesystems */
1270 sbp->sb_features_compat = 0;
1271 sbp->sb_features_ro_compat = 0;
1272 sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE;
1273 sbp->sb_features_log_incompat = 0;
1274
1275 if (fp->finobt)
1276 sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT;
1277
1278 /*
1279 * Sparse inode chunk support has two main inode alignment requirements.
1280 * First, sparse chunk alignment must match the cluster size. Second,
1281 * full chunk alignment must match the inode chunk size.
1282 *
1283 * Copy the already calculated/scaled inoalignmt to spino_align and
1284 * update the former to the full inode chunk size.
1285 */
1286 if (fp->spinodes) {
1287 sbp->sb_spino_align = sbp->sb_inoalignmt;
1288 sbp->sb_inoalignmt = XFS_INODES_PER_CHUNK *
1289 sbp->sb_inodesize >> sbp->sb_blocklog;
1290 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
1291 }
1292
1293 }
1294
1295 long long
1296 getnum(
1297 const char *str,
1298 unsigned int blocksize,
1299 unsigned int sectorsize,
1300 bool convert)
1301 {
1302 long long i;
1303 char *sp;
1304
1305 if (convert)
1306 return cvtnum(blocksize, sectorsize, str);
1307
1308 i = strtoll(str, &sp, 0);
1309 if (i == 0 && sp == str)
1310 return -1LL;
1311 if (*sp != '\0')
1312 return -1LL; /* trailing garbage */
1313 return i;
1314 }
1315
1316 static __attribute__((noreturn)) void
1317 illegal_option(
1318 const char *value,
1319 struct opt_params *opts,
1320 int index)
1321 {
1322 fprintf(stderr,
1323 _("Illegal value %s for -%c %s option\n"),
1324 value, opts->name, opts->subopts[index]);
1325 usage();
1326 }
1327
1328 static int
1329 getnum_checked(
1330 const char *str,
1331 struct opt_params *opts,
1332 int index)
1333 {
1334 const struct subopt_param *sp = &opts->subopt_params[index];
1335 long long c;
1336
1337 if (sp->index != index) {
1338 fprintf(stderr,
1339 ("Developer screwed up option parsing (%d/%d)! Please report!\n"),
1340 sp->index, index);
1341 reqval(opts->name, (char **)opts->subopts, index);
1342 }
1343
1344 if (!str || *str == '\0') {
1345 if (sp->defaultval == SUBOPT_NEEDS_VAL)
1346 reqval(opts->name, (char **)opts->subopts, index);
1347 return sp->defaultval;
1348 }
1349
1350 if (sp->minval == 0 && sp->maxval == 0) {
1351 fprintf(stderr,
1352 _("Option -%c %s has undefined minval/maxval."
1353 "Can't verify value range. This is a bug.\n"),
1354 opts->name, opts->subopts[index]);
1355 exit(1);
1356 }
1357
1358 c = getnum(str, 0, 0, false);
1359 if (c < sp->minval || c > sp->maxval)
1360 illegal_option(str, opts, index);
1361 return c;
1362 }
1363
1364 int
1365 main(
1366 int argc,
1367 char **argv)
1368 {
1369 __uint64_t agcount;
1370 xfs_agf_t *agf;
1371 xfs_agi_t *agi;
1372 xfs_agnumber_t agno;
1373 __uint64_t agsize;
1374 xfs_alloc_rec_t *arec;
1375 struct xfs_btree_block *block;
1376 int blflag;
1377 int blocklog;
1378 unsigned int blocksize;
1379 int bsflag;
1380 int bsize;
1381 xfs_buf_t *buf;
1382 int c;
1383 int daflag;
1384 int dasize;
1385 xfs_rfsblock_t dblocks;
1386 char *dfile;
1387 int dirblocklog;
1388 int dirblocksize;
1389 char *dsize;
1390 int dsu;
1391 int dsw;
1392 int dsunit;
1393 int dswidth;
1394 int force_overwrite;
1395 struct fsxattr fsx;
1396 int ilflag;
1397 int imaxpct;
1398 int imflag;
1399 int inodelog;
1400 int inopblock;
1401 int ipflag;
1402 int isflag;
1403 int isize;
1404 char *label = NULL;
1405 int laflag;
1406 int lalign;
1407 int ldflag;
1408 int liflag;
1409 xfs_agnumber_t logagno;
1410 xfs_rfsblock_t logblocks;
1411 char *logfile;
1412 int loginternal;
1413 char *logsize;
1414 xfs_fsblock_t logstart;
1415 int lvflag;
1416 int lsflag;
1417 int lsuflag;
1418 int lsunitflag;
1419 int lsectorlog;
1420 int lsectorsize;
1421 int lslflag;
1422 int lssflag;
1423 int lsu;
1424 int lsunit;
1425 int min_logblocks;
1426 xfs_mount_t *mp;
1427 xfs_mount_t mbuf;
1428 xfs_extlen_t nbmblocks;
1429 int nlflag;
1430 int nodsflag;
1431 int norsflag;
1432 xfs_alloc_rec_t *nrec;
1433 int nftype;
1434 int nsflag;
1435 int nvflag;
1436 int Nflag;
1437 int discard = 1;
1438 char *p;
1439 char *protofile;
1440 char *protostring;
1441 int qflag;
1442 xfs_rfsblock_t rtblocks;
1443 xfs_extlen_t rtextblocks;
1444 xfs_rtblock_t rtextents;
1445 char *rtextsize;
1446 char *rtfile;
1447 char *rtsize;
1448 xfs_sb_t *sbp;
1449 int sectorlog;
1450 unsigned int sectorsize;
1451 __uint64_t sector_mask;
1452 int slflag;
1453 int ssflag;
1454 __uint64_t tmp_agsize;
1455 uuid_t uuid;
1456 int worst_freelist;
1457 libxfs_init_t xi;
1458 struct fs_topology ft;
1459 struct sb_feat_args sb_feat = {
1460 .finobt = 1,
1461 .finobtflag = false,
1462 .spinodes = 0,
1463 .log_version = 2,
1464 .attr_version = 2,
1465 .dir_version = XFS_DFL_DIR_VERSION,
1466 .inode_align = XFS_IFLAG_ALIGN,
1467 .nci = false,
1468 .lazy_sb_counters = true,
1469 .projid16bit = false,
1470 .crcs_enabled = true,
1471 .dirftype = true,
1472 .parent_pointers = false,
1473 };
1474
1475 platform_uuid_generate(&uuid);
1476 progname = basename(argv[0]);
1477 setlocale(LC_ALL, "");
1478 bindtextdomain(PACKAGE, LOCALEDIR);
1479 textdomain(PACKAGE);
1480
1481 blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
1482 blocklog = blocksize = 0;
1483 sectorlog = lsectorlog = 0;
1484 sectorsize = lsectorsize = 0;
1485 agsize = daflag = dasize = dblocks = 0;
1486 ilflag = imflag = ipflag = isflag = 0;
1487 liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = 0;
1488 loginternal = 1;
1489 logagno = logblocks = rtblocks = rtextblocks = 0;
1490 Nflag = nlflag = nsflag = nvflag = 0;
1491 nftype = 0;
1492 dirblocklog = dirblocksize = 0;
1493 qflag = 0;
1494 imaxpct = inodelog = inopblock = isize = 0;
1495 dfile = logfile = rtfile = NULL;
1496 dsize = logsize = rtsize = rtextsize = protofile = NULL;
1497 dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
1498 nodsflag = norsflag = 0;
1499 force_overwrite = 0;
1500 worst_freelist = 0;
1501 memset(&fsx, 0, sizeof(fsx));
1502
1503 memset(&xi, 0, sizeof(xi));
1504 xi.isdirect = LIBXFS_DIRECT;
1505 xi.isreadonly = LIBXFS_EXCLUSIVELY;
1506
1507 while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
1508 switch (c) {
1509 case 'C':
1510 case 'f':
1511 force_overwrite = 1;
1512 break;
1513 case 'b':
1514 p = optarg;
1515 while (*p != '\0') {
1516 char **subopts = (char **)bopts.subopts;
1517 char *value;
1518
1519 switch (getsubopt(&p, (constpp)subopts,
1520 &value)) {
1521 case B_LOG:
1522 if (blflag)
1523 respec('b', subopts, B_LOG);
1524 if (bsflag)
1525 conflict('b', subopts, B_SIZE,
1526 B_LOG);
1527 blocklog = getnum_checked(value, &bopts,
1528 B_LOG);
1529 blocksize = 1 << blocklog;
1530 blflag = 1;
1531 break;
1532 case B_SIZE:
1533 if (!value || *value == '\0')
1534 reqval('b', subopts, B_SIZE);
1535 if (bsflag)
1536 respec('b', subopts, B_SIZE);
1537 if (blflag)
1538 conflict('b', subopts, B_LOG,
1539 B_SIZE);
1540 blocksize = getnum(value, blocksize,
1541 sectorsize, true);
1542 if (blocksize <= 0 ||
1543 !ispow2(blocksize))
1544 illegal(value, "b size");
1545 blocklog = libxfs_highbit32(blocksize);
1546 bsflag = 1;
1547 break;
1548 default:
1549 unknown('b', value);
1550 }
1551 }
1552 break;
1553 case 'd':
1554 p = optarg;
1555 while (*p != '\0') {
1556 char **subopts = (char **)dopts.subopts;
1557 char *value;
1558
1559 switch (getsubopt(&p, (constpp)subopts,
1560 &value)) {
1561 case D_AGCOUNT:
1562 if (!value || *value == '\0')
1563 reqval('d', subopts, D_AGCOUNT);
1564 if (daflag)
1565 respec('d', subopts, D_AGCOUNT);
1566 agcount = getnum(value, 0, 0, false);
1567 if ((__int64_t)agcount <= 0)
1568 illegal(value, "d agcount");
1569 daflag = 1;
1570 break;
1571 case D_AGSIZE:
1572 if (!value || *value == '\0')
1573 reqval('d', subopts, D_AGSIZE);
1574 if (dasize)
1575 respec('d', subopts, D_AGSIZE);
1576 agsize = getnum(value, blocksize,
1577 sectorsize, true);
1578 if ((__int64_t)agsize <= 0)
1579 illegal(value, "d agsize");
1580 dasize = 1;
1581 break;
1582 case D_FILE:
1583 xi.disfile = getnum_checked(value,
1584 &dopts, D_FILE);
1585 if (xi.disfile && !Nflag)
1586 xi.dcreat = 1;
1587 break;
1588 case D_NAME:
1589 if (!value || *value == '\0')
1590 reqval('d', subopts, D_NAME);
1591 if (xi.dname)
1592 respec('d', subopts, D_NAME);
1593 xi.dname = value;
1594 break;
1595 case D_SIZE:
1596 if (!value || *value == '\0')
1597 reqval('d', subopts, D_SIZE);
1598 if (dsize)
1599 respec('d', subopts, D_SIZE);
1600 dsize = value;
1601 break;
1602 case D_SUNIT:
1603 if (!value || *value == '\0')
1604 reqval('d', subopts, D_SUNIT);
1605 if (dsunit)
1606 respec('d', subopts, D_SUNIT);
1607 if (nodsflag)
1608 conflict('d', subopts, D_NOALIGN,
1609 D_SUNIT);
1610 dsunit = getnum(value, 0, 0, false);
1611 if (dsunit < 0)
1612 illegal(value, "d sunit");
1613 break;
1614 case D_SWIDTH:
1615 if (!value || *value == '\0')
1616 reqval('d', subopts, D_SWIDTH);
1617 if (dswidth)
1618 respec('d', subopts, D_SWIDTH);
1619 if (nodsflag)
1620 conflict('d', subopts, D_NOALIGN,
1621 D_SWIDTH);
1622 dswidth = getnum(value, 0, 0, false);
1623 if (dswidth < 0)
1624 illegal(value, "d swidth");
1625 break;
1626 case D_SU:
1627 if (!value || *value == '\0')
1628 reqval('d', subopts, D_SU);
1629 if (dsu)
1630 respec('d', subopts, D_SU);
1631 if (nodsflag)
1632 conflict('d', subopts, D_NOALIGN,
1633 D_SU);
1634 dsu = getnum(value, blocksize,
1635 sectorsize, true);
1636 if (dsu < 0)
1637 illegal(value, "d su");
1638 break;
1639 case D_SW:
1640 if (!value || *value == '\0')
1641 reqval('d', subopts, D_SW);
1642 if (dsw)
1643 respec('d', subopts, D_SW);
1644 if (nodsflag)
1645 conflict('d', subopts, D_NOALIGN,
1646 D_SW);
1647 dsw = getnum(value, 0, 0, false);
1648 if (dsw < 0)
1649 illegal(value, "d sw");
1650 break;
1651 case D_NOALIGN:
1652 nodsflag = getnum_checked(value,
1653 &dopts, D_NOALIGN);
1654 if (nodsflag) {
1655 if (dsu)
1656 conflict('d', subopts, D_SU,
1657 D_NOALIGN);
1658 if (dsunit)
1659 conflict('d', subopts, D_SUNIT,
1660 D_NOALIGN);
1661 if (dsw)
1662 conflict('d', subopts, D_SW,
1663 D_NOALIGN);
1664 if (dswidth)
1665 conflict('d', subopts, D_SWIDTH,
1666 D_NOALIGN);
1667 }
1668 break;
1669 case D_SECTLOG:
1670 if (slflag)
1671 respec('d', subopts, D_SECTLOG);
1672 if (ssflag)
1673 conflict('d', subopts, D_SECTSIZE,
1674 D_SECTLOG);
1675 sectorlog = getnum_checked(value, &dopts,
1676 D_SECTLOG);
1677 sectorsize = 1 << sectorlog;
1678 slflag = 1;
1679 break;
1680 case D_SECTSIZE:
1681 if (!value || *value == '\0')
1682 reqval('d', subopts, D_SECTSIZE);
1683 if (ssflag)
1684 respec('d', subopts, D_SECTSIZE);
1685 if (slflag)
1686 conflict('d', subopts, D_SECTLOG,
1687 D_SECTSIZE);
1688 sectorsize = getnum(value, blocksize,
1689 sectorsize, true);
1690 if (sectorsize <= 0 ||
1691 !ispow2(sectorsize))
1692 illegal(value, "d sectsize");
1693 sectorlog =
1694 libxfs_highbit32(sectorsize);
1695 ssflag = 1;
1696 break;
1697 case D_RTINHERIT:
1698 fsx.fsx_xflags |= \
1699 XFS_DIFLAG_RTINHERIT;
1700 break;
1701 case D_PROJINHERIT:
1702 if (!value || *value == '\0')
1703 reqval('d', subopts, D_PROJINHERIT);
1704 fsx.fsx_projid = atoi(value);
1705 fsx.fsx_xflags |= \
1706 XFS_DIFLAG_PROJINHERIT;
1707 break;
1708 case D_EXTSZINHERIT:
1709 if (!value || *value == '\0')
1710 reqval('d', subopts, D_EXTSZINHERIT);
1711 fsx.fsx_extsize = atoi(value);
1712 fsx.fsx_xflags |= \
1713 XFS_DIFLAG_EXTSZINHERIT;
1714 break;
1715 default:
1716 unknown('d', value);
1717 }
1718 }
1719 break;
1720 case 'i':
1721 p = optarg;
1722 while (*p != '\0') {
1723 char **subopts = (char **)iopts.subopts;
1724 char *value;
1725
1726 switch (getsubopt(&p, (constpp)subopts,
1727 &value)) {
1728 case I_ALIGN:
1729 sb_feat.inode_align = getnum_checked(
1730 value, &iopts, I_ALIGN);
1731 break;
1732 case I_LOG:
1733 if (ilflag)
1734 respec('i', subopts, I_LOG);
1735 if (ipflag)
1736 conflict('i', subopts, I_PERBLOCK,
1737 I_LOG);
1738 if (isflag)
1739 conflict('i', subopts, I_SIZE,
1740 I_LOG);
1741 inodelog = getnum_checked(value, &iopts,
1742 I_LOG);
1743 isize = 1 << inodelog;
1744 ilflag = 1;
1745 break;
1746 case I_MAXPCT:
1747 if (!value || *value == '\0')
1748 reqval('i', subopts, I_MAXPCT);
1749 if (imflag)
1750 respec('i', subopts, I_MAXPCT);
1751 imaxpct = getnum(value, 0, 0, false);
1752 if (imaxpct < 0 || imaxpct > 100)
1753 illegal(value, "i maxpct");
1754 imflag = 1;
1755 break;
1756 case I_PERBLOCK:
1757 if (!value || *value == '\0')
1758 reqval('i', subopts, I_PERBLOCK);
1759 if (ilflag)
1760 conflict('i', subopts, I_LOG,
1761 I_PERBLOCK);
1762 if (ipflag)
1763 respec('i', subopts, I_PERBLOCK);
1764 if (isflag)
1765 conflict('i', subopts, I_SIZE,
1766 I_PERBLOCK);
1767 inopblock = getnum(value, 0, 0, false);
1768 if (inopblock <
1769 XFS_MIN_INODE_PERBLOCK ||
1770 !ispow2(inopblock))
1771 illegal(value, "i perblock");
1772 ipflag = 1;
1773 break;
1774 case I_SIZE:
1775 if (!value || *value == '\0')
1776 reqval('i', subopts, I_SIZE);
1777 if (ilflag)
1778 conflict('i', subopts, I_LOG,
1779 I_SIZE);
1780 if (ipflag)
1781 conflict('i', subopts, I_PERBLOCK,
1782 I_SIZE);
1783 if (isflag)
1784 respec('i', subopts, I_SIZE);
1785 isize = getnum(value, 0, 0, true);
1786 if (isize <= 0 || !ispow2(isize))
1787 illegal(value, "i size");
1788 inodelog = libxfs_highbit32(isize);
1789 isflag = 1;
1790 break;
1791 case I_ATTR:
1792 if (!value || *value == '\0')
1793 reqval('i', subopts, I_ATTR);
1794 c = getnum(value, 0, 0, false);
1795 if (c < 0 || c > 2)
1796 illegal(value, "i attr");
1797 sb_feat.attr_version = c;
1798 break;
1799 case I_PROJID32BIT:
1800 sb_feat.projid16bit =
1801 !getnum_checked(value, &iopts,
1802 I_PROJID32BIT);
1803 break;
1804 case I_SPINODES:
1805 sb_feat.spinodes =
1806 getnum_checked(value, &iopts,
1807 I_SPINODES);
1808 break;
1809 default:
1810 unknown('i', value);
1811 }
1812 }
1813 break;
1814 case 'l':
1815 p = optarg;
1816 while (*p != '\0') {
1817 char **subopts = (char **)lopts.subopts;
1818 char *value;
1819
1820 switch (getsubopt(&p, (constpp)subopts,
1821 &value)) {
1822 case L_AGNUM:
1823 if (!value || *value == '\0')
1824 reqval('l', subopts, L_AGNUM);
1825 if (laflag)
1826 respec('l', subopts, L_AGNUM);
1827 if (ldflag)
1828 conflict('l', subopts, L_AGNUM, L_DEV);
1829 logagno = getnum(value, 0, 0, false);
1830 if ((__int64_t)logagno < 0)
1831 illegal(value, "l agno");
1832 laflag = 1;
1833 break;
1834 case L_FILE:
1835 xi.lisfile = getnum_checked(value,
1836 &lopts, L_FILE);
1837 if (xi.lisfile && loginternal)
1838 conflict('l', subopts, L_INTERNAL,
1839 L_FILE);
1840 if (xi.lisfile)
1841 xi.lcreat = 1;
1842 break;
1843 case L_INTERNAL:
1844 if (ldflag)
1845 conflict('l', subopts, L_INTERNAL, L_DEV);
1846 if (xi.lisfile)
1847 conflict('l', subopts, L_FILE,
1848 L_INTERNAL);
1849 if (liflag)
1850 respec('l', subopts, L_INTERNAL);
1851
1852 loginternal = getnum_checked(value,
1853 &lopts, L_INTERNAL);
1854 liflag = 1;
1855 break;
1856 case L_SU:
1857 if (!value || *value == '\0')
1858 reqval('l', subopts, L_SU);
1859 if (lsu)
1860 respec('l', subopts, L_SU);
1861 lsu = getnum(value, blocksize,
1862 sectorsize, true);
1863 if (lsu < 0)
1864 illegal(value, "l su");
1865 lsuflag = 1;
1866 break;
1867 case L_SUNIT:
1868 if (!value || *value == '\0')
1869 reqval('l', subopts, L_SUNIT);
1870 if (lsunit)
1871 respec('l', subopts, L_SUNIT);
1872 lsunit = getnum(value, 0, 0, false);
1873 if (lsunit < 0)
1874 illegal(value, "l sunit");
1875 lsunitflag = 1;
1876 break;
1877 case L_NAME:
1878 case L_DEV:
1879 if (laflag)
1880 conflict('l', subopts, L_AGNUM, L_DEV);
1881 if (liflag)
1882 conflict('l', subopts, L_INTERNAL, L_DEV);
1883 if (!value || *value == '\0')
1884 reqval('l', subopts, L_NAME);
1885 if (xi.logname)
1886 respec('l', subopts, L_NAME);
1887 ldflag = 1;
1888 loginternal = 0;
1889 logfile = value;
1890 xi.logname = value;
1891 break;
1892 case L_VERSION:
1893 if (!value || *value == '\0')
1894 reqval('l', subopts, L_VERSION);
1895 if (lvflag)
1896 respec('l', subopts, L_VERSION);
1897 c = getnum(value, 0, 0, false);
1898 if (c < 1 || c > 2)
1899 illegal(value, "l version");
1900 sb_feat.log_version = c;
1901 lvflag = 1;
1902 break;
1903 case L_SIZE:
1904 if (!value || *value == '\0')
1905 reqval('l', subopts, L_SIZE);
1906 if (logsize)
1907 respec('l', subopts, L_SIZE);
1908 logsize = value;
1909 lsflag = 1;
1910 break;
1911 case L_SECTLOG:
1912 if (lslflag)
1913 respec('l', subopts, L_SECTLOG);
1914 if (lssflag)
1915 conflict('l', subopts, L_SECTSIZE,
1916 L_SECTLOG);
1917 lsectorlog = getnum_checked(value,
1918 &lopts, L_SECTLOG);
1919 lsectorsize = 1 << lsectorlog;
1920 lslflag = 1;
1921 break;
1922 case L_SECTSIZE:
1923 if (!value || *value == '\0')
1924 reqval('l', subopts, L_SECTSIZE);
1925 if (lssflag)
1926 respec('l', subopts, L_SECTSIZE);
1927 if (lslflag)
1928 conflict('l', subopts, L_SECTLOG,
1929 L_SECTSIZE);
1930 lsectorsize = getnum(value, blocksize,
1931 sectorsize, true);
1932 if (lsectorsize <= 0 ||
1933 !ispow2(lsectorsize))
1934 illegal(value, "l sectsize");
1935 lsectorlog =
1936 libxfs_highbit32(lsectorsize);
1937 lssflag = 1;
1938 break;
1939 case L_LAZYSBCNTR:
1940 sb_feat.lazy_sb_counters =
1941 getnum_checked(value, &lopts,
1942 L_LAZYSBCNTR);
1943 break;
1944 default:
1945 unknown('l', value);
1946 }
1947 }
1948 break;
1949 case 'L':
1950 if (strlen(optarg) > sizeof(sbp->sb_fname))
1951 illegal(optarg, "L");
1952 label = optarg;
1953 break;
1954 case 'm':
1955 p = optarg;
1956 while (*p != '\0') {
1957 char **subopts = (char **)mopts.subopts;
1958 char *value;
1959
1960 switch (getsubopt(&p, (constpp)subopts,
1961 &value)) {
1962 case M_CRC:
1963 sb_feat.crcs_enabled =
1964 getnum_checked(value, &mopts,
1965 M_CRC);
1966 if (sb_feat.crcs_enabled)
1967 sb_feat.dirftype = true;
1968 break;
1969 case M_FINOBT:
1970 sb_feat.finobtflag = true;
1971 sb_feat.finobt = getnum_checked(
1972 value, &mopts, M_FINOBT);
1973 break;
1974 case M_UUID:
1975 if (!value || *value == '\0')
1976 reqval('m', subopts, M_UUID);
1977 if (platform_uuid_parse(value, &uuid))
1978 illegal(optarg, "m uuid");
1979 break;
1980 default:
1981 unknown('m', value);
1982 }
1983 }
1984 break;
1985 case 'n':
1986 p = optarg;
1987 while (*p != '\0') {
1988 char **subopts = (char **)nopts.subopts;
1989 char *value;
1990
1991 switch (getsubopt(&p, (constpp)subopts,
1992 &value)) {
1993 case N_LOG:
1994 if (nlflag)
1995 respec('n', subopts, N_LOG);
1996 if (nsflag)
1997 conflict('n', subopts, N_SIZE,
1998 N_LOG);
1999 dirblocklog = getnum_checked(value,
2000 &nopts, N_LOG);
2001 dirblocksize = 1 << dirblocklog;
2002 nlflag = 1;
2003 break;
2004 case N_SIZE:
2005 if (!value || *value == '\0')
2006 reqval('n', subopts, N_SIZE);
2007 if (nsflag)
2008 respec('n', subopts, N_SIZE);
2009 if (nlflag)
2010 conflict('n', subopts, N_LOG,
2011 N_SIZE);
2012 dirblocksize = getnum(value, blocksize,
2013 sectorsize, true);
2014 if (dirblocksize <= 0 ||
2015 !ispow2(dirblocksize))
2016 illegal(value, "n size");
2017 dirblocklog =
2018 libxfs_highbit32(dirblocksize);
2019 nsflag = 1;
2020 break;
2021 case N_VERSION:
2022 if (!value || *value == '\0')
2023 reqval('n', subopts, N_VERSION);
2024 if (nvflag)
2025 respec('n', subopts, N_VERSION);
2026 if (!strcasecmp(value, "ci")) {
2027 /* ASCII CI mode */
2028 sb_feat.nci = true;
2029 } else {
2030 c = getnum(value, 0, 0, false);
2031 if (c != 2)
2032 illegal(value,
2033 "n version");
2034 sb_feat.dir_version = c;
2035 }
2036 nvflag = 1;
2037 break;
2038 case N_FTYPE:
2039 if (nftype)
2040 respec('n', subopts, N_FTYPE);
2041 sb_feat.dirftype = getnum_checked(value,
2042 &nopts, N_FTYPE);
2043 nftype = 1;
2044 break;
2045 default:
2046 unknown('n', value);
2047 }
2048 }
2049 break;
2050 case 'N':
2051 Nflag = 1;
2052 break;
2053 case 'K':
2054 discard = 0;
2055 break;
2056 case 'p':
2057 if (protofile)
2058 respec('p', NULL, 0);
2059 protofile = optarg;
2060 break;
2061 case 'q':
2062 qflag = 1;
2063 break;
2064 case 'r':
2065 p = optarg;
2066 while (*p != '\0') {
2067 char **subopts = (char **)ropts.subopts;
2068 char *value;
2069
2070 switch (getsubopt(&p, (constpp)subopts,
2071 &value)) {
2072 case R_EXTSIZE:
2073 if (!value || *value == '\0')
2074 reqval('r', subopts, R_EXTSIZE);
2075 if (rtextsize)
2076 respec('r', subopts, R_EXTSIZE);
2077 rtextsize = value;
2078 break;
2079 case R_FILE:
2080 xi.risfile = getnum_checked(value,
2081 &ropts, R_FILE);
2082 if (xi.risfile)
2083 xi.rcreat = 1;
2084 break;
2085 case R_NAME:
2086 case R_DEV:
2087 if (!value || *value == '\0')
2088 reqval('r', subopts, R_NAME);
2089 if (xi.rtname)
2090 respec('r', subopts, R_NAME);
2091 xi.rtname = value;
2092 break;
2093 case R_SIZE:
2094 if (!value || *value == '\0')
2095 reqval('r', subopts, R_SIZE);
2096 if (rtsize)
2097 respec('r', subopts, R_SIZE);
2098 rtsize = value;
2099 break;
2100 case R_NOALIGN:
2101 norsflag = getnum_checked(value,
2102 &ropts, R_NOALIGN);
2103 break;
2104 default:
2105 unknown('r', value);
2106 }
2107 }
2108 break;
2109 case 's':
2110 p = optarg;
2111 while (*p != '\0') {
2112 char **subopts = (char **)sopts.subopts;
2113 char *value;
2114
2115 switch (getsubopt(&p, (constpp)subopts,
2116 &value)) {
2117 case S_LOG:
2118 case S_SECTLOG:
2119 if (slflag || lslflag)
2120 respec('s', subopts, S_SECTLOG);
2121 if (ssflag || lssflag)
2122 conflict('s', subopts,
2123 S_SECTSIZE, S_SECTLOG);
2124 sectorlog = getnum_checked(value, &sopts,
2125 S_SECTLOG);
2126 lsectorlog = sectorlog;
2127 sectorsize = 1 << sectorlog;
2128 lsectorsize = sectorsize;
2129 lslflag = slflag = 1;
2130 break;
2131 case S_SIZE:
2132 case S_SECTSIZE:
2133 if (!value || *value == '\0')
2134 reqval('s', subopts, S_SECTSIZE);
2135 if (ssflag || lssflag)
2136 respec('s', subopts, S_SECTSIZE);
2137 if (slflag || lslflag)
2138 conflict('s', subopts, S_SECTLOG,
2139 S_SECTSIZE);
2140 sectorsize = getnum(value, blocksize,
2141 sectorsize, true);
2142 if (sectorsize <= 0 ||
2143 !ispow2(sectorsize))
2144 illegal(value, "s sectsize");
2145 lsectorsize = sectorsize;
2146 sectorlog =
2147 libxfs_highbit32(sectorsize);
2148 lsectorlog = sectorlog;
2149 lssflag = ssflag = 1;
2150 break;
2151 default:
2152 unknown('s', value);
2153 }
2154 }
2155 break;
2156 case 'V':
2157 printf(_("%s version %s\n"), progname, VERSION);
2158 exit(0);
2159 case '?':
2160 unknown(optopt, "");
2161 }
2162 }
2163 if (argc - optind > 1) {
2164 fprintf(stderr, _("extra arguments\n"));
2165 usage();
2166 } else if (argc - optind == 1) {
2167 dfile = xi.volname = argv[optind];
2168 if (xi.dname) {
2169 fprintf(stderr,
2170 _("cannot specify both %s and -d name=%s\n"),
2171 xi.volname, xi.dname);
2172 usage();
2173 }
2174 } else
2175 dfile = xi.dname;
2176
2177 /*
2178 * Blocksize and sectorsize first, other things depend on them
2179 * For RAID4/5/6 we want to align sector size and block size,
2180 * so we need to start with the device geometry extraction too.
2181 */
2182 if (!blflag && !bsflag) {
2183 blocklog = XFS_DFL_BLOCKSIZE_LOG;
2184 blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
2185 }
2186 if (blocksize < XFS_MIN_BLOCKSIZE || blocksize > XFS_MAX_BLOCKSIZE) {
2187 fprintf(stderr, _("illegal block size %d\n"), blocksize);
2188 usage();
2189 }
2190 if (sb_feat.crcs_enabled && blocksize < XFS_MIN_CRC_BLOCKSIZE) {
2191 fprintf(stderr,
2192 _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
2193 XFS_MIN_CRC_BLOCKSIZE);
2194 usage();
2195 }
2196 if (sb_feat.crcs_enabled && !sb_feat.dirftype) {
2197 fprintf(stderr, _("cannot disable ftype with crcs enabled\n"));
2198 usage();
2199 }
2200
2201 if (!slflag && !ssflag) {
2202 sectorlog = XFS_MIN_SECTORSIZE_LOG;
2203 sectorsize = XFS_MIN_SECTORSIZE;
2204 }
2205 if (!lslflag && !lssflag) {
2206 lsectorlog = sectorlog;
2207 lsectorsize = sectorsize;
2208 }
2209
2210 memset(&ft, 0, sizeof(ft));
2211 get_topology(&xi, &ft, force_overwrite);
2212
2213 if (!ssflag) {
2214 /*
2215 * Unless specified manually on the command line use the
2216 * advertised sector size of the device. We use the physical
2217 * sector size unless the requested block size is smaller
2218 * than that, then we can use logical, but warn about the
2219 * inefficiency.
2220 */
2221
2222 /* Older kernels may not have physical/logical distinction */
2223 if (!ft.psectorsize)
2224 ft.psectorsize = ft.lsectorsize;
2225
2226 sectorsize = ft.psectorsize ? ft.psectorsize :
2227 XFS_MIN_SECTORSIZE;
2228
2229 if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) {
2230 fprintf(stderr,
2231 _("specified blocksize %d is less than device physical sector size %d\n"),
2232 blocksize, ft.psectorsize);
2233 fprintf(stderr,
2234 _("switching to logical sector size %d\n"),
2235 ft.lsectorsize);
2236 sectorsize = ft.lsectorsize ? ft.lsectorsize :
2237 XFS_MIN_SECTORSIZE;
2238 }
2239 }
2240
2241 if (!ssflag) {
2242 sectorlog = libxfs_highbit32(sectorsize);
2243 if (loginternal) {
2244 lsectorsize = sectorsize;
2245 lsectorlog = sectorlog;
2246 }
2247 }
2248
2249 if (sectorsize < XFS_MIN_SECTORSIZE ||
2250 sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) {
2251 if (ssflag)
2252 fprintf(stderr, _("illegal sector size %d\n"), sectorsize);
2253 else
2254 fprintf(stderr,
2255 _("block size %d cannot be smaller than logical sector size %d\n"),
2256 blocksize, ft.lsectorsize);
2257 usage();
2258 }
2259 if (sectorsize < ft.lsectorsize) {
2260 fprintf(stderr, _("illegal sector size %d; hw sector is %d\n"),
2261 sectorsize, ft.lsectorsize);
2262 usage();
2263 }
2264 if (lsectorsize < XFS_MIN_SECTORSIZE ||
2265 lsectorsize > XFS_MAX_SECTORSIZE || lsectorsize > blocksize) {
2266 fprintf(stderr, _("illegal log sector size %d\n"), lsectorsize);
2267 usage();
2268 } else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) {
2269 lsu = blocksize;
2270 sb_feat.log_version = 2;
2271 }
2272
2273 /*
2274 * Now we have blocks and sector sizes set up, check parameters that are
2275 * no longer optional for CRC enabled filesystems. Catch them up front
2276 * here before doing anything else.
2277 */
2278 if (sb_feat.crcs_enabled) {
2279 /* minimum inode size is 512 bytes, ipflag checked later */
2280 if ((isflag || ilflag) && inodelog < XFS_DINODE_DFL_CRC_LOG) {
2281 fprintf(stderr,
2282 _("Minimum inode size for CRCs is %d bytes\n"),
2283 1 << XFS_DINODE_DFL_CRC_LOG);
2284 usage();
2285 }
2286
2287 /* inodes always aligned */
2288 if (!sb_feat.inode_align) {
2289 fprintf(stderr,
2290 _("Inodes always aligned for CRC enabled filesytems\n"));
2291 usage();
2292 }
2293
2294 /* lazy sb counters always on */
2295 if (!sb_feat.lazy_sb_counters) {
2296 fprintf(stderr,
2297 _("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
2298 usage();
2299 }
2300
2301 /* version 2 logs always on */
2302 if (sb_feat.log_version != 2) {
2303 fprintf(stderr,
2304 _("V2 logs always enabled for CRC enabled filesytems\n"));
2305 usage();
2306 }
2307
2308 /* attr2 always on */
2309 if (sb_feat.attr_version != 2) {
2310 fprintf(stderr,
2311 _("V2 attribute format always enabled on CRC enabled filesytems\n"));
2312 usage();
2313 }
2314
2315 /* 32 bit project quota always on */
2316 /* attr2 always on */
2317 if (sb_feat.projid16bit) {
2318 fprintf(stderr,
2319 _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
2320 usage();
2321 }
2322 } else {
2323 /*
2324 * The kernel doesn't currently support crc=0,finobt=1
2325 * filesystems. If crcs are not enabled and the user has
2326 * explicitly turned them off then silently turn them off
2327 * to avoid an unnecessary warning. If the user explicitly
2328 * tried to use crc=0,finobt=1, then issue a warning before
2329 * turning them off.
2330 */
2331 if (sb_feat.finobt && sb_feat.finobtflag) {
2332 fprintf(stderr,
2333 _("warning: finobt not supported without CRC support, disabled.\n"));
2334 }
2335 sb_feat.finobt = 0;
2336 }
2337
2338 if (sb_feat.spinodes && !sb_feat.crcs_enabled) {
2339 fprintf(stderr,
2340 _("warning: sparse inodes not supported without CRC support, disabled.\n"));
2341 sb_feat.spinodes = 0;
2342 }
2343
2344 if (nsflag || nlflag) {
2345 if (dirblocksize < blocksize ||
2346 dirblocksize > XFS_MAX_BLOCKSIZE) {
2347 fprintf(stderr, _("illegal directory block size %d\n"),
2348 dirblocksize);
2349 usage();
2350 }
2351 } else {
2352 if (blocksize < (1 << XFS_MIN_REC_DIRSIZE))
2353 dirblocklog = XFS_MIN_REC_DIRSIZE;
2354 else
2355 dirblocklog = blocklog;
2356 dirblocksize = 1 << dirblocklog;
2357 }
2358
2359 if (daflag && dasize) {
2360 fprintf(stderr,
2361 _("both -d agcount= and agsize= specified, use one or the other\n"));
2362 usage();
2363 }
2364
2365 if (xi.disfile && (!dsize || !xi.dname)) {
2366 fprintf(stderr,
2367 _("if -d file then -d name and -d size are required\n"));
2368 usage();
2369 }
2370 if (dsize) {
2371 __uint64_t dbytes;
2372
2373 dbytes = getnum(dsize, blocksize, sectorsize, true);
2374 if ((__int64_t)dbytes < 0)
2375 illegal(dsize, "d size");
2376 if (dbytes % XFS_MIN_BLOCKSIZE) {
2377 fprintf(stderr,
2378 _("illegal data length %lld, not a multiple of %d\n"),
2379 (long long)dbytes, XFS_MIN_BLOCKSIZE);
2380 usage();
2381 }
2382 dblocks = (xfs_rfsblock_t)(dbytes >> blocklog);
2383 if (dbytes % blocksize)
2384 fprintf(stderr, _("warning: "
2385 "data length %lld not a multiple of %d, truncated to %lld\n"),
2386 (long long)dbytes, blocksize,
2387 (long long)(dblocks << blocklog));
2388 }
2389 if (ipflag) {
2390 inodelog = blocklog - libxfs_highbit32(inopblock);
2391 isize = 1 << inodelog;
2392 } else if (!ilflag && !isflag) {
2393 inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
2394 : XFS_DINODE_DFL_LOG;
2395 isize = 1 << inodelog;
2396 }
2397 if (sb_feat.crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
2398 fprintf(stderr,
2399 _("Minimum inode size for CRCs is %d bytes\n"),
2400 1 << XFS_DINODE_DFL_CRC_LOG);
2401 usage();
2402 }
2403
2404 if (xi.lisfile && (!logsize || !xi.logname)) {
2405 fprintf(stderr,
2406 _("if -l file then -l name and -l size are required\n"));
2407 usage();
2408 }
2409 if (logsize) {
2410 __uint64_t logbytes;
2411
2412 logbytes = getnum(logsize, blocksize, sectorsize, true);
2413 if ((__int64_t)logbytes < 0)
2414 illegal(logsize, "l size");
2415 if (logbytes % XFS_MIN_BLOCKSIZE) {
2416 fprintf(stderr,
2417 _("illegal log length %lld, not a multiple of %d\n"),
2418 (long long)logbytes, XFS_MIN_BLOCKSIZE);
2419 usage();
2420 }
2421 logblocks = (xfs_rfsblock_t)(logbytes >> blocklog);
2422 if (logbytes % blocksize)
2423 fprintf(stderr,
2424 _("warning: log length %lld not a multiple of %d, truncated to %lld\n"),
2425 (long long)logbytes, blocksize,
2426 (long long)(logblocks << blocklog));
2427 }
2428 if (xi.risfile && (!rtsize || !xi.rtname)) {
2429 fprintf(stderr,
2430 _("if -r file then -r name and -r size are required\n"));
2431 usage();
2432 }
2433 if (rtsize) {
2434 __uint64_t rtbytes;
2435
2436 rtbytes = getnum(rtsize, blocksize, sectorsize, true);
2437 if ((__int64_t)rtbytes < 0)
2438 illegal(rtsize, "r size");
2439 if (rtbytes % XFS_MIN_BLOCKSIZE) {
2440 fprintf(stderr,
2441 _("illegal rt length %lld, not a multiple of %d\n"),
2442 (long long)rtbytes, XFS_MIN_BLOCKSIZE);
2443 usage();
2444 }
2445 rtblocks = (xfs_rfsblock_t)(rtbytes >> blocklog);
2446 if (rtbytes % blocksize)
2447 fprintf(stderr,
2448 _("warning: rt length %lld not a multiple of %d, truncated to %lld\n"),
2449 (long long)rtbytes, blocksize,
2450 (long long)(rtblocks << blocklog));
2451 }
2452 /*
2453 * If specified, check rt extent size against its constraints.
2454 */
2455 if (rtextsize) {
2456 __uint64_t rtextbytes;
2457
2458 rtextbytes = getnum(rtextsize, blocksize, sectorsize, true);
2459 if ((__int64_t)rtextbytes < 0)
2460 illegal(rtsize, "r extsize");
2461 if (rtextbytes % blocksize) {
2462 fprintf(stderr,
2463 _("illegal rt extent size %lld, not a multiple of %d\n"),
2464 (long long)rtextbytes, blocksize);
2465 usage();
2466 }
2467 if (rtextbytes > XFS_MAX_RTEXTSIZE) {
2468 fprintf(stderr,
2469 _("rt extent size %s too large, maximum %d\n"),
2470 rtextsize, XFS_MAX_RTEXTSIZE);
2471 usage();
2472 }
2473 if (rtextbytes < XFS_MIN_RTEXTSIZE) {
2474 fprintf(stderr,
2475 _("rt extent size %s too small, minimum %d\n"),
2476 rtextsize, XFS_MIN_RTEXTSIZE);
2477 usage();
2478 }
2479 rtextblocks = (xfs_extlen_t)(rtextbytes >> blocklog);
2480 } else {
2481 /*
2482 * If realtime extsize has not been specified by the user,
2483 * and the underlying volume is striped, then set rtextblocks
2484 * to the stripe width.
2485 */
2486 __uint64_t rswidth;
2487 __uint64_t rtextbytes;
2488
2489 if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile))
2490 rswidth = ft.rtswidth;
2491 else
2492 rswidth = 0;
2493
2494 /* check that rswidth is a multiple of fs blocksize */
2495 if (!norsflag && rswidth && !(BBTOB(rswidth) % blocksize)) {
2496 rswidth = DTOBT(rswidth);
2497 rtextbytes = rswidth << blocklog;
2498 if (XFS_MIN_RTEXTSIZE <= rtextbytes &&
2499 (rtextbytes <= XFS_MAX_RTEXTSIZE)) {
2500 rtextblocks = rswidth;
2501 }
2502 }
2503 if (!rtextblocks) {
2504 rtextblocks = (blocksize < XFS_MIN_RTEXTSIZE) ?
2505 XFS_MIN_RTEXTSIZE >> blocklog : 1;
2506 }
2507 }
2508 ASSERT(rtextblocks);
2509
2510 /*
2511 * Check some argument sizes against mins, maxes.
2512 */
2513 if (isize > blocksize / XFS_MIN_INODE_PERBLOCK ||
2514 isize < XFS_DINODE_MIN_SIZE ||
2515 isize > XFS_DINODE_MAX_SIZE) {
2516 int maxsz;
2517
2518 fprintf(stderr, _("illegal inode size %d\n"), isize);
2519 maxsz = MIN(blocksize / XFS_MIN_INODE_PERBLOCK,
2520 XFS_DINODE_MAX_SIZE);
2521 if (XFS_DINODE_MIN_SIZE == maxsz)
2522 fprintf(stderr,
2523 _("allowable inode size with %d byte blocks is %d\n"),
2524 blocksize, XFS_DINODE_MIN_SIZE);
2525 else
2526 fprintf(stderr,
2527 _("allowable inode size with %d byte blocks is between %d and %d\n"),
2528 blocksize, XFS_DINODE_MIN_SIZE, maxsz);
2529 exit(1);
2530 }
2531
2532 /* if lsu or lsunit was specified, automatically use v2 logs */
2533 if ((lsu || lsunit) && sb_feat.log_version == 1) {
2534 fprintf(stderr,
2535 _("log stripe unit specified, using v2 logs\n"));
2536 sb_feat.log_version = 2;
2537 }
2538
2539 calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize,
2540 &dsunit, &dswidth, &lsunit);
2541
2542 xi.setblksize = sectorsize;
2543
2544 /*
2545 * Initialize. This will open the log and rt devices as well.
2546 */
2547 if (!libxfs_init(&xi))
2548 usage();
2549 if (!xi.ddev) {
2550 fprintf(stderr, _("no device name given in argument list\n"));
2551 usage();
2552 }
2553
2554 /*
2555 * Ok, Linux only has a 1024-byte resolution on device _size_,
2556 * and the sizes below are in basic 512-byte blocks,
2557 * so if we have (size % 2), on any partition, we can't get
2558 * to the last 512 bytes. The same issue exists for larger
2559 * sector sizes - we cannot write past the last sector.
2560 *
2561 * So, we reduce the size (in basic blocks) to a perfect
2562 * multiple of the sector size, or 1024, whichever is larger.
2563 */
2564
2565 sector_mask = (__uint64_t)-1 << (MAX(sectorlog, 10) - BBSHIFT);
2566 xi.dsize &= sector_mask;
2567 xi.rtsize &= sector_mask;
2568 xi.logBBsize &= (__uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
2569
2570 if (!force_overwrite) {
2571 if (check_overwrite(dfile) ||
2572 check_overwrite(logfile) ||
2573 check_overwrite(xi.rtname)) {
2574 fprintf(stderr,
2575 _("%s: Use the -f option to force overwrite.\n"),
2576 progname);
2577 exit(1);
2578 }
2579 }
2580
2581 if (discard && !Nflag) {
2582 discard_blocks(xi.ddev, xi.dsize);
2583 if (xi.rtdev)
2584 discard_blocks(xi.rtdev, xi.rtsize);
2585 if (xi.logdev && xi.logdev != xi.ddev)
2586 discard_blocks(xi.logdev, xi.logBBsize);
2587 }
2588
2589 if (!liflag && !ldflag)
2590 loginternal = xi.logdev == 0;
2591 if (xi.logname)
2592 logfile = xi.logname;
2593 else if (loginternal)
2594 logfile = _("internal log");
2595 else if (xi.volname && xi.logdev)
2596 logfile = _("volume log");
2597 else if (!ldflag) {
2598 fprintf(stderr, _("no log subvolume or internal log\n"));
2599 usage();
2600 }
2601 if (xi.rtname)
2602 rtfile = xi.rtname;
2603 else
2604 if (xi.volname && xi.rtdev)
2605 rtfile = _("volume rt");
2606 else if (!xi.rtdev)
2607 rtfile = _("none");
2608 if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
2609 fprintf(stderr,
2610 _("size %s specified for data subvolume is too large, "
2611 "maximum is %lld blocks\n"),
2612 dsize, (long long)DTOBT(xi.dsize));
2613 usage();
2614 } else if (!dsize && xi.dsize > 0)
2615 dblocks = DTOBT(xi.dsize);
2616 else if (!dsize) {
2617 fprintf(stderr, _("can't get size of data subvolume\n"));
2618 usage();
2619 }
2620 if (dblocks < XFS_MIN_DATA_BLOCKS) {
2621 fprintf(stderr,
2622 _("size %lld of data subvolume is too small, minimum %d blocks\n"),
2623 (long long)dblocks, XFS_MIN_DATA_BLOCKS);
2624 usage();
2625 }
2626
2627 if (loginternal && xi.logdev) {
2628 fprintf(stderr,
2629 _("can't have both external and internal logs\n"));
2630 usage();
2631 } else if (loginternal && sectorsize != lsectorsize) {
2632 fprintf(stderr,
2633 _("data and log sector sizes must be equal for internal logs\n"));
2634 usage();
2635 }
2636
2637 if (xi.dbsize > sectorsize) {
2638 fprintf(stderr, _(
2639 "Warning: the data subvolume sector size %u is less than the sector size \n\
2640 reported by the device (%u).\n"),
2641 sectorsize, xi.dbsize);
2642 }
2643 if (!loginternal && xi.lbsize > lsectorsize) {
2644 fprintf(stderr, _(
2645 "Warning: the log subvolume sector size %u is less than the sector size\n\
2646 reported by the device (%u).\n"),
2647 lsectorsize, xi.lbsize);
2648 }
2649 if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
2650 fprintf(stderr, _(
2651 "Warning: the realtime subvolume sector size %u is less than the sector size\n\
2652 reported by the device (%u).\n"),
2653 sectorsize, xi.rtbsize);
2654 }
2655
2656 if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
2657 fprintf(stderr,
2658 _("size %s specified for rt subvolume is too large, "
2659 "maximum is %lld blocks\n"),
2660 rtsize, (long long)DTOBT(xi.rtsize));
2661 usage();
2662 } else if (!rtsize && xi.rtsize > 0)
2663 rtblocks = DTOBT(xi.rtsize);
2664 else if (rtsize && !xi.rtdev) {
2665 fprintf(stderr,
2666 _("size specified for non-existent rt subvolume\n"));
2667 usage();
2668 }
2669 if (xi.rtdev) {
2670 rtextents = rtblocks / rtextblocks;
2671 nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize);
2672 } else {
2673 rtextents = rtblocks = 0;
2674 nbmblocks = 0;
2675 }
2676
2677 if (!nodsflag) {
2678 if (dsunit) {
2679 if (ft.dsunit && ft.dsunit != dsunit) {
2680 fprintf(stderr,
2681 _("%s: Specified data stripe unit %d "
2682 "is not the same as the volume stripe "
2683 "unit %d\n"),
2684 progname, dsunit, ft.dsunit);
2685 }
2686 if (ft.dswidth && ft.dswidth != dswidth) {
2687 fprintf(stderr,
2688 _("%s: Specified data stripe width %d "
2689 "is not the same as the volume stripe "
2690 "width %d\n"),
2691 progname, dswidth, ft.dswidth);
2692 }
2693 } else {
2694 dsunit = ft.dsunit;
2695 dswidth = ft.dswidth;
2696 nodsflag = 1;
2697 }
2698 } /* else dsunit & dswidth can't be set if nodsflag is set */
2699
2700 if (dasize) { /* User-specified AG size */
2701 /*
2702 * Check specified agsize is a multiple of blocksize.
2703 */
2704 if (agsize % blocksize) {
2705 fprintf(stderr,
2706 _("agsize (%lld) not a multiple of fs blk size (%d)\n"),
2707 (long long)agsize, blocksize);
2708 usage();
2709 }
2710 agsize /= blocksize;
2711 agcount = dblocks / agsize + (dblocks % agsize != 0);
2712
2713 } else if (daflag) { /* User-specified AG count */
2714 agsize = dblocks / agcount + (dblocks % agcount != 0);
2715 } else {
2716 calc_default_ag_geometry(blocklog, dblocks,
2717 dsunit | dswidth, &agsize, &agcount);
2718 }
2719
2720 /*
2721 * If dsunit is a multiple of fs blocksize, then check that is a
2722 * multiple of the agsize too
2723 */
2724 if (dsunit && !(BBTOB(dsunit) % blocksize) &&
2725 dswidth && !(BBTOB(dswidth) % blocksize)) {
2726
2727 /* convert from 512 byte blocks to fs blocksize */
2728 dsunit = DTOBT(dsunit);
2729 dswidth = DTOBT(dswidth);
2730
2731 /*
2732 * agsize is not a multiple of dsunit
2733 */
2734 if ((agsize % dsunit) != 0) {
2735 /*
2736 * Round up to stripe unit boundary. Also make sure
2737 * that agsize is still larger than
2738 * XFS_AG_MIN_BLOCKS(blocklog)
2739 */
2740 tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit;
2741 /*
2742 * Round down to stripe unit boundary if rounding up
2743 * created an AG size that is larger than the AG max.
2744 */
2745 if (tmp_agsize > XFS_AG_MAX_BLOCKS(blocklog))
2746 tmp_agsize = ((agsize) / dsunit) * dsunit;
2747
2748 if ((tmp_agsize >= XFS_AG_MIN_BLOCKS(blocklog)) &&
2749 (tmp_agsize <= XFS_AG_MAX_BLOCKS(blocklog))) {
2750 agsize = tmp_agsize;
2751 if (!daflag)
2752 agcount = dblocks/agsize +
2753 (dblocks % agsize != 0);
2754 if (dasize)
2755 fprintf(stderr,
2756 _("agsize rounded to %lld, swidth = %d\n"),
2757 (long long)agsize, dswidth);
2758 } else {
2759 if (nodsflag) {
2760 dsunit = dswidth = 0;
2761 } else {
2762 /*
2763 * agsize is out of bounds, this will
2764 * print nice details & exit.
2765 */
2766 validate_ag_geometry(blocklog, dblocks,
2767 agsize, agcount);
2768 exit(1);
2769 }
2770 }
2771 }
2772 if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) {
2773 /* This is a non-optimal configuration because all AGs
2774 * start on the same disk in the stripe. Changing
2775 * the AG size by one sunit will guarantee that this
2776 * does not happen.
2777 */
2778 tmp_agsize = agsize - dsunit;
2779 if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
2780 tmp_agsize = agsize + dsunit;
2781 if (dblocks < agsize) {
2782 /* oh well, nothing to do */
2783 tmp_agsize = agsize;
2784 }
2785 }
2786 if (daflag || dasize) {
2787 fprintf(stderr, _(
2788 "Warning: AG size is a multiple of stripe width. This can cause performance\n\
2789 problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
2790 an AG size that is one stripe unit smaller, for example %llu.\n"),
2791 (unsigned long long)tmp_agsize);
2792 } else {
2793 agsize = tmp_agsize;
2794 agcount = dblocks/agsize + (dblocks % agsize != 0);
2795 /*
2796 * If the last AG is too small, reduce the
2797 * filesystem size and drop the blocks.
2798 */
2799 if ( dblocks % agsize != 0 &&
2800 (dblocks % agsize <
2801 XFS_AG_MIN_BLOCKS(blocklog))) {
2802 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
2803 agcount--;
2804 ASSERT(agcount != 0);
2805 }
2806 }
2807 }
2808 } else {
2809 if (nodsflag)
2810 dsunit = dswidth = 0;
2811 else {
2812 fprintf(stderr,
2813 _("%s: Stripe unit(%d) or stripe width(%d) is "
2814 "not a multiple of the block size(%d)\n"),
2815 progname, BBTOB(dsunit), BBTOB(dswidth),
2816 blocksize);
2817 exit(1);
2818 }
2819 }
2820
2821 /*
2822 * If the last AG is too small, reduce the filesystem size
2823 * and drop the blocks.
2824 */
2825 if ( dblocks % agsize != 0 &&
2826 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
2827 ASSERT(!daflag);
2828 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
2829 agcount--;
2830 ASSERT(agcount != 0);
2831 }
2832
2833 validate_ag_geometry(blocklog, dblocks, agsize, agcount);
2834
2835 if (!imflag)
2836 imaxpct = calc_default_imaxpct(blocklog, dblocks);
2837
2838 /*
2839 * check that log sunit is modulo fsblksize or default it to dsunit.
2840 */
2841
2842 if (lsunit) {
2843 if ((BBTOB(lsunit) % blocksize != 0)) {
2844 fprintf(stderr,
2845 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
2846 BBTOB(lsunit), blocksize);
2847 exit(1);
2848 }
2849 /* convert from 512 byte blocks to fs blocks */
2850 lsunit = DTOBT(lsunit);
2851 } else if (sb_feat.log_version == 2 && loginternal && dsunit) {
2852 /* lsunit and dsunit now in fs blocks */
2853 lsunit = dsunit;
2854 }
2855
2856 if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
2857 /* Warn only if specified on commandline */
2858 if (lsuflag || lsunitflag) {
2859 fprintf(stderr,
2860 _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
2861 (lsunit * blocksize));
2862 fprintf(stderr,
2863 _("log stripe unit adjusted to 32KiB\n"));
2864 }
2865 lsunit = (32 * 1024) >> blocklog;
2866 }
2867
2868 min_logblocks = max_trans_res(sb_feat.crcs_enabled, sb_feat.dir_version,
2869 sectorlog, blocklog, inodelog, dirblocklog,
2870 sb_feat.log_version, lsunit, sb_feat.finobt);
2871 ASSERT(min_logblocks);
2872 min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
2873 if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
2874 min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
2875 if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
2876 fprintf(stderr,
2877 _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
2878 logsize, (long long)DTOBT(xi.logBBsize));
2879 usage();
2880 } else if (!logsize && xi.logBBsize > 0) {
2881 logblocks = DTOBT(xi.logBBsize);
2882 } else if (logsize && !xi.logdev && !loginternal) {
2883 fprintf(stderr,
2884 _("size specified for non-existent log subvolume\n"));
2885 usage();
2886 } else if (loginternal && logsize && logblocks >= dblocks) {
2887 fprintf(stderr, _("size %lld too large for internal log\n"),
2888 (long long)logblocks);
2889 usage();
2890 } else if (!loginternal && !xi.logdev) {
2891 logblocks = 0;
2892 } else if (loginternal && !logsize) {
2893
2894 if (dblocks < GIGABYTES(1, blocklog)) {
2895 /* tiny filesystems get minimum sized logs. */
2896 logblocks = min_logblocks;
2897 } else if (dblocks < GIGABYTES(16, blocklog)) {
2898
2899 /*
2900 * For small filesystems, we want to use the
2901 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
2902 * at all possible, ramping up to 128MB at 256GB.
2903 */
2904 logblocks = MIN(XFS_MIN_LOG_BYTES >> blocklog,
2905 min_logblocks * XFS_DFL_LOG_FACTOR);
2906 } else {
2907 /*
2908 * With a 2GB max log size, default to maximum size
2909 * at 4TB. This keeps the same ratio from the older
2910 * max log size of 128M at 256GB fs size. IOWs,
2911 * the ratio of fs size to log size is 2048:1.
2912 */
2913 logblocks = (dblocks << blocklog) / 2048;
2914 logblocks = logblocks >> blocklog;
2915 }
2916
2917 /* Ensure the chosen size meets minimum log size requirements */
2918 logblocks = MAX(min_logblocks, logblocks);
2919
2920 /* make sure the log fits wholly within an AG */
2921 if (logblocks >= agsize)
2922 logblocks = min_logblocks;
2923
2924 /* and now clamp the size to the maximum supported size */
2925 logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
2926 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES)
2927 logblocks = XFS_MAX_LOG_BYTES >> blocklog;
2928
2929 }
2930 validate_log_size(logblocks, blocklog, min_logblocks);
2931
2932 protostring = setup_proto(protofile);
2933 bsize = 1 << (blocklog - BBSHIFT);
2934 mp = &mbuf;
2935 sbp = &mp->m_sb;
2936 memset(mp, 0, sizeof(xfs_mount_t));
2937 sbp->sb_blocklog = (__uint8_t)blocklog;
2938 sbp->sb_sectlog = (__uint8_t)sectorlog;
2939 sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize);
2940 sbp->sb_agblocks = (xfs_agblock_t)agsize;
2941 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
2942 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
2943
2944 /*
2945 * sb_versionnum and finobt flags must be set before we use
2946 * XFS_PREALLOC_BLOCKS().
2947 */
2948 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
2949
2950
2951 if (loginternal) {
2952 /*
2953 * Readjust the log size to fit within an AG if it was sized
2954 * automatically.
2955 */
2956 if (!logsize) {
2957 logblocks = MIN(logblocks,
2958 XFS_ALLOC_AG_MAX_USABLE(mp));
2959
2960 /* revalidate the log size is valid if we changed it */
2961 validate_log_size(logblocks, blocklog, min_logblocks);
2962 }
2963 if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) {
2964 fprintf(stderr,
2965 _("internal log size %lld too large, must fit in allocation group\n"),
2966 (long long)logblocks);
2967 usage();
2968 }
2969
2970 if (laflag) {
2971 if (logagno >= agcount) {
2972 fprintf(stderr,
2973 _("log ag number %d too large, must be less than %lld\n"),
2974 logagno, (long long)agcount);
2975 usage();
2976 }
2977 } else
2978 logagno = (xfs_agnumber_t)(agcount / 2);
2979
2980 logstart = XFS_AGB_TO_FSB(mp, logagno, XFS_PREALLOC_BLOCKS(mp));
2981 /*
2982 * Align the logstart at stripe unit boundary.
2983 */
2984 if (lsunit) {
2985 logstart = fixup_internal_log_stripe(mp,
2986 lsflag, logstart, agsize, lsunit,
2987 &logblocks, blocklog, &lalign);
2988 } else if (dsunit) {
2989 logstart = fixup_internal_log_stripe(mp,
2990 lsflag, logstart, agsize, dsunit,
2991 &logblocks, blocklog, &lalign);
2992 }
2993 } else {
2994 logstart = 0;
2995 if (lsunit)
2996 fixup_log_stripe_unit(lsflag, lsunit,
2997 &logblocks, blocklog);
2998 }
2999 validate_log_size(logblocks, blocklog, min_logblocks);
3000
3001 if (!qflag || Nflag) {
3002 printf(_(
3003 "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
3004 " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
3005 " =%-22s crc=%-8u finobt=%u, sparse=%u\n"
3006 "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
3007 " =%-22s sunit=%-6u swidth=%u blks\n"
3008 "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n"
3009 "log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
3010 " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
3011 "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
3012 dfile, isize, (long long)agcount, (long long)agsize,
3013 "", sectorsize, sb_feat.attr_version,
3014 !sb_feat.projid16bit,
3015 "", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
3016 "", blocksize, (long long)dblocks, imaxpct,
3017 "", dsunit, dswidth,
3018 sb_feat.dir_version, dirblocksize, sb_feat.nci,
3019 sb_feat.dirftype,
3020 logfile, 1 << blocklog, (long long)logblocks,
3021 sb_feat.log_version, "", lsectorsize, lsunit,
3022 sb_feat.lazy_sb_counters,
3023 rtfile, rtextblocks << blocklog,
3024 (long long)rtblocks, (long long)rtextents);
3025 if (Nflag)
3026 exit(0);
3027 }
3028
3029 if (label)
3030 strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname));
3031 sbp->sb_magicnum = XFS_SB_MAGIC;
3032 sbp->sb_blocksize = blocksize;
3033 sbp->sb_dblocks = dblocks;
3034 sbp->sb_rblocks = rtblocks;
3035 sbp->sb_rextents = rtextents;
3036 platform_uuid_copy(&sbp->sb_uuid, &uuid);
3037 /* Only in memory; libxfs expects this as if read from disk */
3038 platform_uuid_copy(&sbp->sb_meta_uuid, &uuid);
3039 sbp->sb_logstart = logstart;
3040 sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
3041 sbp->sb_rextsize = rtextblocks;
3042 sbp->sb_agcount = (xfs_agnumber_t)agcount;
3043 sbp->sb_rbmblocks = nbmblocks;
3044 sbp->sb_logblocks = (xfs_extlen_t)logblocks;
3045 sbp->sb_sectsize = (__uint16_t)sectorsize;
3046 sbp->sb_inodesize = (__uint16_t)isize;
3047 sbp->sb_inopblock = (__uint16_t)(blocksize / isize);
3048 sbp->sb_sectlog = (__uint8_t)sectorlog;
3049 sbp->sb_inodelog = (__uint8_t)inodelog;
3050 sbp->sb_inopblog = (__uint8_t)(blocklog - inodelog);
3051 sbp->sb_rextslog =
3052 (__uint8_t)(rtextents ?
3053 libxfs_highbit32((unsigned int)rtextents) : 0);
3054 sbp->sb_inprogress = 1; /* mkfs is in progress */
3055 sbp->sb_imax_pct = imaxpct;
3056 sbp->sb_icount = 0;
3057 sbp->sb_ifree = 0;
3058 sbp->sb_fdblocks = dblocks - agcount * XFS_PREALLOC_BLOCKS(mp) -
3059 (loginternal ? logblocks : 0);
3060 sbp->sb_frextents = 0; /* will do a free later */
3061 sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
3062 sbp->sb_qflags = 0;
3063 sbp->sb_unit = dsunit;
3064 sbp->sb_width = dswidth;
3065 sbp->sb_dirblklog = dirblocklog - blocklog;
3066 if (sb_feat.log_version == 2) { /* This is stored in bytes */
3067 lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit);
3068 sbp->sb_logsunit = lsunit;
3069 } else
3070 sbp->sb_logsunit = 0;
3071 if (sb_feat.inode_align) {
3072 int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
3073 if (sb_feat.crcs_enabled)
3074 cluster_size *= isize / XFS_DINODE_MIN_SIZE;
3075 sbp->sb_inoalignmt = cluster_size >> blocklog;
3076 sb_feat.inode_align = sbp->sb_inoalignmt != 0;
3077 } else
3078 sbp->sb_inoalignmt = 0;
3079 if (lsectorsize != BBSIZE || sectorsize != BBSIZE) {
3080 sbp->sb_logsectlog = (__uint8_t)lsectorlog;
3081 sbp->sb_logsectsize = (__uint16_t)lsectorsize;
3082 } else {
3083 sbp->sb_logsectlog = 0;
3084 sbp->sb_logsectsize = 0;
3085 }
3086
3087 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
3088
3089 if (force_overwrite)
3090 zero_old_xfs_structures(&xi, sbp);
3091
3092 /*
3093 * Zero out the beginning of the device, to obliterate any old
3094 * filesystem signatures out there. This should take care of
3095 * swap (somewhere around the page size), jfs (32k),
3096 * ext[2,3] and reiserfs (64k) - and hopefully all else.
3097 */
3098 libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
3099 buf = libxfs_getbuf(mp->m_ddev_targp, 0, BTOBB(WHACK_SIZE));
3100 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
3101 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3102 libxfs_purgebuf(buf);
3103
3104 /* OK, now write the superblock */
3105 buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
3106 buf->b_ops = &xfs_sb_buf_ops;
3107 memset(XFS_BUF_PTR(buf), 0, sectorsize);
3108 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
3109 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3110 libxfs_purgebuf(buf);
3111
3112 /*
3113 * If the data area is a file, then grow it out to its final size
3114 * so that the reads for the end of the device in the mount code
3115 * will succeed.
3116 */
3117 if (xi.disfile && ftruncate64(xi.dfd, dblocks * blocksize) < 0) {
3118 fprintf(stderr, _("%s: Growing the data section failed\n"),
3119 progname);
3120 exit(1);
3121 }
3122
3123 /*
3124 * Zero out the end of the device, to obliterate any
3125 * old MD RAID (or other) metadata at the end of the device.
3126 * (MD sb is ~64k from the end, take out a wider swath to be sure)
3127 */
3128 if (!xi.disfile) {
3129 buf = libxfs_getbuf(mp->m_ddev_targp,
3130 (xi.dsize - BTOBB(WHACK_SIZE)),
3131 BTOBB(WHACK_SIZE));
3132 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
3133 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3134 libxfs_purgebuf(buf);
3135 }
3136
3137 /*
3138 * Zero the log....
3139 */
3140 libxfs_log_clear(mp->m_logdev_targp, NULL,
3141 XFS_FSB_TO_DADDR(mp, logstart),
3142 (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
3143 &sbp->sb_uuid, sb_feat.log_version, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
3144
3145 mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
3146 if (mp == NULL) {
3147 fprintf(stderr, _("%s: filesystem failed to initialize\n"),
3148 progname);
3149 exit(1);
3150 }
3151
3152 /*
3153 * XXX: this code is effectively shared with the kernel growfs code.
3154 * These initialisations should be pulled into libxfs to keep the
3155 * kernel/userspace header initialisation code the same.
3156 */
3157 for (agno = 0; agno < agcount; agno++) {
3158 struct xfs_agfl *agfl;
3159 int bucket;
3160 struct xfs_perag *pag = xfs_perag_get(mp, agno);
3161
3162 /*
3163 * Superblock.
3164 */
3165 buf = libxfs_getbuf(mp->m_ddev_targp,
3166 XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
3167 XFS_FSS_TO_BB(mp, 1));
3168 buf->b_ops = &xfs_sb_buf_ops;
3169 memset(XFS_BUF_PTR(buf), 0, sectorsize);
3170 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
3171 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3172
3173 /*
3174 * AG header block: freespace
3175 */
3176 buf = libxfs_getbuf(mp->m_ddev_targp,
3177 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
3178 XFS_FSS_TO_BB(mp, 1));
3179 buf->b_ops = &xfs_agf_buf_ops;
3180 agf = XFS_BUF_TO_AGF(buf);
3181 memset(agf, 0, sectorsize);
3182 if (agno == agcount - 1)
3183 agsize = dblocks - (xfs_rfsblock_t)(agno * agsize);
3184 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
3185 agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
3186 agf->agf_seqno = cpu_to_be32(agno);
3187 agf->agf_length = cpu_to_be32(agsize);
3188 agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
3189 agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
3190 agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
3191 agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
3192 pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
3193 pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
3194 agf->agf_flfirst = 0;
3195 agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
3196 agf->agf_flcount = 0;
3197 nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp));
3198 agf->agf_freeblks = cpu_to_be32(nbmblocks);
3199 agf->agf_longest = cpu_to_be32(nbmblocks);
3200 if (xfs_sb_version_hascrc(&mp->m_sb))
3201 platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
3202
3203 if (loginternal && agno == logagno) {
3204 be32_add_cpu(&agf->agf_freeblks, -logblocks);
3205 agf->agf_longest = cpu_to_be32(agsize -
3206 XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
3207 }
3208 if (xfs_alloc_min_freelist(mp, pag) > worst_freelist)
3209 worst_freelist = xfs_alloc_min_freelist(mp, pag);
3210 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3211
3212 /*
3213 * AG freelist header block
3214 */
3215 buf = libxfs_getbuf(mp->m_ddev_targp,
3216 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
3217 XFS_FSS_TO_BB(mp, 1));
3218 buf->b_ops = &xfs_agfl_buf_ops;
3219 agfl = XFS_BUF_TO_AGFL(buf);
3220 /* setting to 0xff results in initialisation to NULLAGBLOCK */
3221 memset(agfl, 0xff, sectorsize);
3222 if (xfs_sb_version_hascrc(&mp->m_sb)) {
3223 agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
3224 agfl->agfl_seqno = cpu_to_be32(agno);
3225 platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
3226 for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
3227 agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
3228 }
3229
3230 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3231
3232 /*
3233 * AG header block: inodes
3234 */
3235 buf = libxfs_getbuf(mp->m_ddev_targp,
3236 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
3237 XFS_FSS_TO_BB(mp, 1));
3238 agi = XFS_BUF_TO_AGI(buf);
3239 buf->b_ops = &xfs_agi_buf_ops;
3240 memset(agi, 0, sectorsize);
3241 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
3242 agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
3243 agi->agi_seqno = cpu_to_be32(agno);
3244 agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize);
3245 agi->agi_count = 0;
3246 agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
3247 agi->agi_level = cpu_to_be32(1);
3248 if (sb_feat.finobt) {
3249 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
3250 agi->agi_free_level = cpu_to_be32(1);
3251 }
3252 agi->agi_freecount = 0;
3253 agi->agi_newino = cpu_to_be32(NULLAGINO);
3254 agi->agi_dirino = cpu_to_be32(NULLAGINO);
3255 if (xfs_sb_version_hascrc(&mp->m_sb))
3256 platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
3257 for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
3258 agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
3259 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3260
3261 /*
3262 * BNO btree root block
3263 */
3264 buf = libxfs_getbuf(mp->m_ddev_targp,
3265 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
3266 bsize);
3267 buf->b_ops = &xfs_allocbt_buf_ops;
3268 block = XFS_BUF_TO_BLOCK(buf);
3269 memset(block, 0, blocksize);
3270 if (xfs_sb_version_hascrc(&mp->m_sb))
3271 xfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1,
3272 agno, XFS_BTREE_CRC_BLOCKS);
3273 else
3274 xfs_btree_init_block(mp, buf, XFS_ABTB_MAGIC, 0, 1,
3275 agno, 0);
3276
3277 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3278 arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
3279 if (loginternal && agno == logagno) {
3280 if (lalign) {
3281 /*
3282 * Have to insert two records
3283 * Insert pad record for stripe align of log
3284 */
3285 arec->ar_blockcount = cpu_to_be32(
3286 XFS_FSB_TO_AGBNO(mp, logstart) -
3287 be32_to_cpu(arec->ar_startblock));
3288 nrec = arec + 1;
3289 /*
3290 * Insert record at start of internal log
3291 */
3292 nrec->ar_startblock = cpu_to_be32(
3293 be32_to_cpu(arec->ar_startblock) +
3294 be32_to_cpu(arec->ar_blockcount));
3295 arec = nrec;
3296 be16_add_cpu(&block->bb_numrecs, 1);
3297 }
3298 /*
3299 * Change record start to after the internal log
3300 */
3301 be32_add_cpu(&arec->ar_startblock, logblocks);
3302 }
3303 /*
3304 * Calculate the record block count and check for the case where
3305 * the log might have consumed all available space in the AG. If
3306 * so, reset the record count to 0 to avoid exposure of an invalid
3307 * record start block.
3308 */
3309 arec->ar_blockcount = cpu_to_be32(agsize -
3310 be32_to_cpu(arec->ar_startblock));
3311 if (!arec->ar_blockcount)
3312 block->bb_numrecs = 0;
3313
3314 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3315
3316 /*
3317 * CNT btree root block
3318 */
3319 buf = libxfs_getbuf(mp->m_ddev_targp,
3320 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
3321 bsize);
3322 buf->b_ops = &xfs_allocbt_buf_ops;
3323 block = XFS_BUF_TO_BLOCK(buf);
3324 memset(block, 0, blocksize);
3325 if (xfs_sb_version_hascrc(&mp->m_sb))
3326 xfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1,
3327 agno, XFS_BTREE_CRC_BLOCKS);
3328 else
3329 xfs_btree_init_block(mp, buf, XFS_ABTC_MAGIC, 0, 1,
3330 agno, 0);
3331
3332 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3333 arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
3334 if (loginternal && agno == logagno) {
3335 if (lalign) {
3336 arec->ar_blockcount = cpu_to_be32(
3337 XFS_FSB_TO_AGBNO(mp, logstart) -
3338 be32_to_cpu(arec->ar_startblock));
3339 nrec = arec + 1;
3340 nrec->ar_startblock = cpu_to_be32(
3341 be32_to_cpu(arec->ar_startblock) +
3342 be32_to_cpu(arec->ar_blockcount));
3343 arec = nrec;
3344 be16_add_cpu(&block->bb_numrecs, 1);
3345 }
3346 be32_add_cpu(&arec->ar_startblock, logblocks);
3347 }
3348 /*
3349 * Calculate the record block count and check for the case where
3350 * the log might have consumed all available space in the AG. If
3351 * so, reset the record count to 0 to avoid exposure of an invalid
3352 * record start block.
3353 */
3354 arec->ar_blockcount = cpu_to_be32(agsize -
3355 be32_to_cpu(arec->ar_startblock));
3356 if (!arec->ar_blockcount)
3357 block->bb_numrecs = 0;
3358
3359 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3360
3361 /*
3362 * INO btree root block
3363 */
3364 buf = libxfs_getbuf(mp->m_ddev_targp,
3365 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
3366 bsize);
3367 buf->b_ops = &xfs_inobt_buf_ops;
3368 block = XFS_BUF_TO_BLOCK(buf);
3369 memset(block, 0, blocksize);
3370 if (xfs_sb_version_hascrc(&mp->m_sb))
3371 xfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0,
3372 agno, XFS_BTREE_CRC_BLOCKS);
3373 else
3374 xfs_btree_init_block(mp, buf, XFS_IBT_MAGIC, 0, 0,
3375 agno, 0);
3376 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3377
3378 /*
3379 * Free INO btree root block
3380 */
3381 if (!sb_feat.finobt) {
3382 xfs_perag_put(pag);
3383 continue;
3384 }
3385
3386 buf = libxfs_getbuf(mp->m_ddev_targp,
3387 XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
3388 bsize);
3389 buf->b_ops = &xfs_inobt_buf_ops;
3390 block = XFS_BUF_TO_BLOCK(buf);
3391 memset(block, 0, blocksize);
3392 if (xfs_sb_version_hascrc(&mp->m_sb))
3393 xfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0,
3394 agno, XFS_BTREE_CRC_BLOCKS);
3395 else
3396 xfs_btree_init_block(mp, buf, XFS_FIBT_MAGIC, 0, 0,
3397 agno, 0);
3398 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3399 xfs_perag_put(pag);
3400 }
3401
3402 /*
3403 * Touch last block, make fs the right size if it's a file.
3404 */
3405 buf = libxfs_getbuf(mp->m_ddev_targp,
3406 (xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize);
3407 memset(XFS_BUF_PTR(buf), 0, blocksize);
3408 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3409
3410 /*
3411 * Make sure we can write the last block in the realtime area.
3412 */
3413 if (mp->m_rtdev_targp->dev && rtblocks > 0) {
3414 buf = libxfs_getbuf(mp->m_rtdev_targp,
3415 XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
3416 memset(XFS_BUF_PTR(buf), 0, blocksize);
3417 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3418 }
3419
3420 /*
3421 * BNO, CNT free block list
3422 */
3423 for (agno = 0; agno < agcount; agno++) {
3424 xfs_alloc_arg_t args;
3425 xfs_trans_t *tp;
3426 struct xfs_trans_res tres = {0};
3427
3428 memset(&args, 0, sizeof(args));
3429 args.tp = tp = libxfs_trans_alloc(mp, 0);
3430 args.mp = mp;
3431 args.agno = agno;
3432 args.alignment = 1;
3433 args.pag = xfs_perag_get(mp,agno);
3434 c = -libxfs_trans_reserve(tp, &tres, worst_freelist, 0);
3435 if (c)
3436 res_failed(c);
3437
3438 libxfs_alloc_fix_freelist(&args, 0);
3439 xfs_perag_put(args.pag);
3440 libxfs_trans_commit(tp);
3441 }
3442
3443 /*
3444 * Allocate the root inode and anything else in the proto file.
3445 */
3446 parse_proto(mp, &fsx, &protostring);
3447
3448 /*
3449 * Protect ourselves against possible stupidity
3450 */
3451 if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
3452 fprintf(stderr,
3453 _("%s: root inode created in AG %u, not AG 0\n"),
3454 progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
3455 exit(1);
3456 }
3457
3458 /*
3459 * Write out multiple secondary superblocks with rootinode field set
3460 */
3461 if (mp->m_sb.sb_agcount > 1) {
3462 /*
3463 * the last superblock
3464 */
3465 buf = libxfs_readbuf(mp->m_dev,
3466 XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1,
3467 XFS_SB_DADDR),
3468 XFS_FSS_TO_BB(mp, 1),
3469 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3470 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
3471 mp->m_sb.sb_rootino);
3472 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3473 /*
3474 * and one in the middle for luck
3475 */
3476 if (mp->m_sb.sb_agcount > 2) {
3477 buf = libxfs_readbuf(mp->m_dev,
3478 XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2,
3479 XFS_SB_DADDR),
3480 XFS_FSS_TO_BB(mp, 1),
3481 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3482 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
3483 mp->m_sb.sb_rootino);
3484 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3485 }
3486 }
3487
3488 /*
3489 * Dump all inodes and buffers before marking us all done.
3490 * Need to drop references to inodes we still hold, first.
3491 */
3492 libxfs_rtmount_destroy(mp);
3493 libxfs_bcache_purge();
3494
3495 /*
3496 * Mark the filesystem ok.
3497 */
3498 buf = libxfs_getsb(mp, LIBXFS_EXIT_ON_FAILURE);
3499 (XFS_BUF_TO_SBP(buf))->sb_inprogress = 0;
3500 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3501
3502 libxfs_umount(mp);
3503 if (xi.rtdev)
3504 libxfs_device_close(xi.rtdev);
3505 if (xi.logdev && xi.logdev != xi.ddev)
3506 libxfs_device_close(xi.logdev);
3507 libxfs_device_close(xi.ddev);
3508
3509 return 0;
3510 }
3511
3512 static void
3513 conflict(
3514 char opt,
3515 char *tab[],
3516 int oldidx,
3517 int newidx)
3518 {
3519 fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
3520 opt, tab[oldidx], opt, tab[newidx]);
3521 usage();
3522 }
3523
3524
3525 static void
3526 illegal(
3527 const char *value,
3528 const char *opt)
3529 {
3530 fprintf(stderr, _("Illegal value %s for -%s option\n"), value, opt);
3531 usage();
3532 }
3533
3534 static int
3535 ispow2(
3536 unsigned int i)
3537 {
3538 return (i & (i - 1)) == 0;
3539 }
3540
3541 static void __attribute__((noreturn))
3542 reqval(
3543 char opt,
3544 char *tab[],
3545 int idx)
3546 {
3547 fprintf(stderr, _("-%c %s option requires a value\n"), opt, tab[idx]);
3548 usage();
3549 }
3550
3551 static void
3552 respec(
3553 char opt,
3554 char *tab[],
3555 int idx)
3556 {
3557 fprintf(stderr, "-%c ", opt);
3558 if (tab)
3559 fprintf(stderr, "%s ", tab[idx]);
3560 fprintf(stderr, _("option respecified\n"));
3561 usage();
3562 }
3563
3564 static void
3565 unknown(
3566 char opt,
3567 char *s)
3568 {
3569 fprintf(stderr, _("unknown option -%c %s\n"), opt, s);
3570 usage();
3571 }
3572
3573 long long
3574 cvtnum(
3575 unsigned int blocksize,
3576 unsigned int sectorsize,
3577 const char *s)
3578 {
3579 long long i;
3580 char *sp;
3581
3582 i = strtoll(s, &sp, 0);
3583 if (i == 0 && sp == s)
3584 return -1LL;
3585 if (*sp == '\0')
3586 return i;
3587
3588 if (*sp == 'b' && sp[1] == '\0')
3589 return i * blocksize;
3590 if (*sp == 's' && sp[1] == '\0')
3591 return i * sectorsize;
3592
3593 if (*sp == 'k' && sp[1] == '\0')
3594 return 1024LL * i;
3595 if (*sp == 'm' && sp[1] == '\0')
3596 return 1024LL * 1024LL * i;
3597 if (*sp == 'g' && sp[1] == '\0')
3598 return 1024LL * 1024LL * 1024LL * i;
3599 if (*sp == 't' && sp[1] == '\0')
3600 return 1024LL * 1024LL * 1024LL * 1024LL * i;
3601 if (*sp == 'p' && sp[1] == '\0')
3602 return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
3603 if (*sp == 'e' && sp[1] == '\0')
3604 return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
3605 return -1LL;
3606 }
3607
3608 static void __attribute__((noreturn))
3609 usage( void )
3610 {
3611 fprintf(stderr, _("Usage: %s\n\
3612 /* blocksize */ [-b log=n|size=num]\n\
3613 /* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx]\n\
3614 /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
3615 (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
3616 sectlog=n|sectsize=num\n\
3617 /* force overwrite */ [-f]\n\
3618 /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
3619 projid32bit=0|1,sparse=0|1]\n\
3620 /* no discard */ [-K]\n\
3621 /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
3622 sunit=value|su=num,sectlog=n|sectsize=num,\n\
3623 lazy-count=0|1]\n\
3624 /* label */ [-L label (maximum 12 characters)]\n\
3625 /* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\
3626 /* no-op info only */ [-N]\n\
3627 /* prototype file */ [-p fname]\n\
3628 /* quiet */ [-q]\n\
3629 /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\
3630 /* sectorsize */ [-s log=n|size=num]\n\
3631 /* version */ [-V]\n\
3632 devicename\n\
3633 <devicename> is required unless -d name=xxx is given.\n\
3634 <num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\
3635 xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\
3636 <value> is xxx (512 byte blocks).\n"),
3637 progname);
3638 exit(1);
3639 }