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