]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfs/xfs_mkfs.c
mkfs: factor rtdev extent size validation
[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 /*
866 * Default filesystem features and configuration values
867 *
868 * This structure contains the default mkfs values that are to be used when
869 * a user does not specify the option on the command line. We do not use these
870 * values directly - they are inputs to the mkfs geometry validation and
871 * calculations.
872 */
873 struct mkfs_default_params {
874 char *source; /* where the defaults came from */
875
876 int sectorsize;
877 int blocksize;
878
879 /* feature flags that are set */
880 struct sb_feat_args sb_feat;
881
882 /* root inode characteristics */
883 struct fsxattr fsx;
884 };
885
886 #define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
887 #define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
888 #define MEGABYTES(count, blog) ((uint64_t)(count) << (20 - (blog)))
889
890 /*
891 * Use this macro before we have superblock and mount structure
892 */
893 #define DTOBT(d, bl) ((xfs_rfsblock_t)((d) >> ((bl) - BBSHIFT)))
894
895 /*
896 * Use this for block reservations needed for mkfs's conditions
897 * (basically no fragmentation).
898 */
899 #define MKFS_BLOCKRES_INODE \
900 ((uint)(mp->m_ialloc_blks + (mp->m_in_maxlevels - 1)))
901 #define MKFS_BLOCKRES(rb) \
902 ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \
903 (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
904
905 /* amount (in bytes) we zero at the beginning and end of the device to
906 * remove traces of other filesystems, raid superblocks, etc.
907 */
908 #define WHACK_SIZE (128 * 1024)
909
910 /*
911 * Convert lsu to lsunit for 512 bytes blocks and check validity of the values.
912 */
913 static void
914 calc_stripe_factors(
915 int dsu,
916 int dsw,
917 int dsectsz,
918 int lsu,
919 int lsectsz,
920 int *dsunit,
921 int *dswidth,
922 int *lsunit)
923 {
924 /* Handle data sunit/swidth options */
925 if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) {
926 fprintf(stderr,
927 _("both data sunit and data swidth options "
928 "must be specified\n"));
929 usage();
930 }
931
932 if (dsu || dsw) {
933 if ((dsu && !dsw) || (!dsu && dsw)) {
934 fprintf(stderr,
935 _("both data su and data sw options "
936 "must be specified\n"));
937 usage();
938 }
939
940 if (dsu % dsectsz) {
941 fprintf(stderr,
942 _("data su must be a multiple of the "
943 "sector size (%d)\n"), dsectsz);
944 usage();
945 }
946
947 *dsunit = (int)BTOBBT(dsu);
948 *dswidth = *dsunit * dsw;
949 }
950
951 if (*dsunit && (*dswidth % *dsunit != 0)) {
952 fprintf(stderr,
953 _("data stripe width (%d) must be a multiple of the "
954 "data stripe unit (%d)\n"), *dswidth, *dsunit);
955 usage();
956 }
957
958 /* Handle log sunit options */
959
960 if (lsu)
961 *lsunit = (int)BTOBBT(lsu);
962
963 /* verify if lsu/lsunit is a multiple block size */
964 if (lsu % blocksize != 0) {
965 fprintf(stderr,
966 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
967 lsu, blocksize);
968 exit(1);
969 }
970 if ((BBTOB(*lsunit) % blocksize != 0)) {
971 fprintf(stderr,
972 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
973 BBTOB(*lsunit), blocksize);
974 exit(1);
975 }
976 }
977
978 static void
979 check_device_type(
980 const char *name,
981 int *isfile,
982 bool no_size,
983 bool no_name,
984 int *create,
985 bool force_overwrite,
986 const char *optname)
987 {
988 struct stat statbuf;
989
990 if (*isfile && (no_size || no_name)) {
991 fprintf(stderr,
992 _("if -%s file then -%s name and -%s size are required\n"),
993 optname, optname, optname);
994 usage();
995 }
996
997 if (!name) {
998 fprintf(stderr, _("No device name specified\n"));
999 usage();
1000 }
1001
1002 if (stat(name, &statbuf)) {
1003 if (errno == ENOENT && *isfile) {
1004 if (create)
1005 *create = 1;
1006 return;
1007 }
1008
1009 fprintf(stderr,
1010 _("Error accessing specified device %s: %s\n"),
1011 name, strerror(errno));
1012 usage();
1013 return;
1014 }
1015
1016 if (!force_overwrite && check_overwrite(name)) {
1017 fprintf(stderr,
1018 _("%s: Use the -f option to force overwrite.\n"),
1019 progname);
1020 exit(1);
1021 }
1022
1023 /*
1024 * We only want to completely truncate and recreate an existing file if
1025 * we were specifically told it was a file. Set the create flag only in
1026 * this case to trigger that behaviour.
1027 */
1028 if (S_ISREG(statbuf.st_mode)) {
1029 if (!*isfile)
1030 *isfile = 1;
1031 else if (create)
1032 *create = 1;
1033 return;
1034 }
1035
1036 if (S_ISBLK(statbuf.st_mode)) {
1037 if (*isfile) {
1038 fprintf(stderr,
1039 _("specified \"-%s file\" on a block device %s\n"),
1040 optname, name);
1041 usage();
1042 }
1043 return;
1044 }
1045
1046 fprintf(stderr,
1047 _("specified device %s not a file or block device\n"),
1048 name);
1049 usage();
1050 }
1051
1052 static void
1053 fixup_log_stripe_unit(
1054 int lsflag,
1055 int sunit,
1056 xfs_rfsblock_t *logblocks,
1057 int blocklog)
1058 {
1059 uint64_t tmp_logblocks;
1060
1061 /*
1062 * Make sure that the log size is a multiple of the stripe unit
1063 */
1064 if ((*logblocks % sunit) != 0) {
1065 if (!lsflag) {
1066 tmp_logblocks = ((*logblocks + (sunit - 1))
1067 / sunit) * sunit;
1068 /*
1069 * If the log is too large, round down
1070 * instead of round up
1071 */
1072 if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) ||
1073 ((tmp_logblocks << blocklog) > XFS_MAX_LOG_BYTES)) {
1074 tmp_logblocks = (*logblocks / sunit) * sunit;
1075 }
1076 *logblocks = tmp_logblocks;
1077 } else {
1078 fprintf(stderr, _("log size %lld is not a multiple "
1079 "of the log stripe unit %d\n"),
1080 (long long) *logblocks, sunit);
1081 usage();
1082 }
1083 }
1084 }
1085
1086 static xfs_fsblock_t
1087 fixup_internal_log_stripe(
1088 xfs_mount_t *mp,
1089 int lsflag,
1090 xfs_fsblock_t logstart,
1091 uint64_t agsize,
1092 int sunit,
1093 xfs_rfsblock_t *logblocks,
1094 int blocklog,
1095 int *lalign)
1096 {
1097 if ((logstart % sunit) != 0) {
1098 logstart = ((logstart + (sunit - 1))/sunit) * sunit;
1099 *lalign = 1;
1100 }
1101
1102 fixup_log_stripe_unit(lsflag, sunit, logblocks, blocklog);
1103
1104 if (*logblocks > agsize - XFS_FSB_TO_AGBNO(mp, logstart)) {
1105 fprintf(stderr,
1106 _("Due to stripe alignment, the internal log size "
1107 "(%lld) is too large.\n"), (long long) *logblocks);
1108 fprintf(stderr, _("Must fit within an allocation group.\n"));
1109 usage();
1110 }
1111 return logstart;
1112 }
1113
1114 void
1115 validate_log_size(uint64_t logblocks, int blocklog, int min_logblocks)
1116 {
1117 if (logblocks < min_logblocks) {
1118 fprintf(stderr,
1119 _("log size %lld blocks too small, minimum size is %d blocks\n"),
1120 (long long)logblocks, min_logblocks);
1121 usage();
1122 }
1123 if (logblocks > XFS_MAX_LOG_BLOCKS) {
1124 fprintf(stderr,
1125 _("log size %lld blocks too large, maximum size is %lld blocks\n"),
1126 (long long)logblocks, XFS_MAX_LOG_BLOCKS);
1127 usage();
1128 }
1129 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
1130 fprintf(stderr,
1131 _("log size %lld bytes too large, maximum size is %lld bytes\n"),
1132 (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES);
1133 usage();
1134 }
1135 }
1136
1137 static int
1138 calc_default_imaxpct(
1139 int blocklog,
1140 uint64_t dblocks)
1141 {
1142 /*
1143 * This returns the % of the disk space that is used for
1144 * inodes, it changes relatively to the FS size:
1145 * - over 50 TB, use 1%,
1146 * - 1TB - 50 TB, use 5%,
1147 * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%).
1148 */
1149
1150 if (dblocks < TERABYTES(1, blocklog)) {
1151 return XFS_DFL_IMAXIMUM_PCT;
1152 } else if (dblocks < TERABYTES(50, blocklog)) {
1153 return 5;
1154 }
1155
1156 return 1;
1157 }
1158
1159 static void
1160 validate_ag_geometry(
1161 int blocklog,
1162 uint64_t dblocks,
1163 uint64_t agsize,
1164 uint64_t agcount)
1165 {
1166 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
1167 fprintf(stderr,
1168 _("agsize (%lld blocks) too small, need at least %lld blocks\n"),
1169 (long long)agsize,
1170 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1171 usage();
1172 }
1173
1174 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
1175 fprintf(stderr,
1176 _("agsize (%lld blocks) too big, maximum is %lld blocks\n"),
1177 (long long)agsize,
1178 (long long)XFS_AG_MAX_BLOCKS(blocklog));
1179 usage();
1180 }
1181
1182 if (agsize > dblocks) {
1183 fprintf(stderr,
1184 _("agsize (%lld blocks) too big, data area is %lld blocks\n"),
1185 (long long)agsize, (long long)dblocks);
1186 usage();
1187 }
1188
1189 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
1190 fprintf(stderr,
1191 _("too many allocation groups for size = %lld\n"),
1192 (long long)agsize);
1193 fprintf(stderr, _("need at most %lld allocation groups\n"),
1194 (long long)(dblocks / XFS_AG_MIN_BLOCKS(blocklog) +
1195 (dblocks % XFS_AG_MIN_BLOCKS(blocklog) != 0)));
1196 usage();
1197 }
1198
1199 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
1200 fprintf(stderr,
1201 _("too few allocation groups for size = %lld\n"), (long long)agsize);
1202 fprintf(stderr,
1203 _("need at least %lld allocation groups\n"),
1204 (long long)(dblocks / XFS_AG_MAX_BLOCKS(blocklog) +
1205 (dblocks % XFS_AG_MAX_BLOCKS(blocklog) != 0)));
1206 usage();
1207 }
1208
1209 /*
1210 * If the last AG is too small, reduce the filesystem size
1211 * and drop the blocks.
1212 */
1213 if ( dblocks % agsize != 0 &&
1214 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
1215 fprintf(stderr,
1216 _("last AG size %lld blocks too small, minimum size is %lld blocks\n"),
1217 (long long)(dblocks % agsize),
1218 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1219 usage();
1220 }
1221
1222 /*
1223 * If agcount is too large, make it smaller.
1224 */
1225 if (agcount > XFS_MAX_AGNUMBER + 1) {
1226 fprintf(stderr,
1227 _("%lld allocation groups is too many, maximum is %lld\n"),
1228 (long long)agcount, (long long)XFS_MAX_AGNUMBER + 1);
1229 usage();
1230 }
1231 }
1232
1233 static void
1234 zero_old_xfs_structures(
1235 libxfs_init_t *xi,
1236 xfs_sb_t *new_sb)
1237 {
1238 void *buf;
1239 xfs_sb_t sb;
1240 uint32_t bsize;
1241 int i;
1242 xfs_off_t off;
1243
1244 /*
1245 * We open regular files with O_TRUNC|O_CREAT. Nothing to do here...
1246 */
1247 if (xi->disfile && xi->dcreat)
1248 return;
1249
1250 /*
1251 * read in existing filesystem superblock, use its geometry
1252 * settings and zero the existing secondary superblocks.
1253 */
1254 buf = memalign(libxfs_device_alignment(), new_sb->sb_sectsize);
1255 if (!buf) {
1256 fprintf(stderr,
1257 _("error reading existing superblock -- failed to memalign buffer\n"));
1258 return;
1259 }
1260 memset(buf, 0, new_sb->sb_sectsize);
1261
1262 /*
1263 * If we are creating an image file, it might be of zero length at this
1264 * point in time. Hence reading the existing superblock is going to
1265 * return zero bytes. It's not a failure we need to warn about in this
1266 * case.
1267 */
1268 off = pread(xi->dfd, buf, new_sb->sb_sectsize, 0);
1269 if (off != new_sb->sb_sectsize) {
1270 if (!xi->disfile)
1271 fprintf(stderr,
1272 _("error reading existing superblock: %s\n"),
1273 strerror(errno));
1274 goto done;
1275 }
1276 libxfs_sb_from_disk(&sb, buf);
1277
1278 /*
1279 * perform same basic superblock validation to make sure we
1280 * actually zero secondary blocks
1281 */
1282 if (sb.sb_magicnum != XFS_SB_MAGIC || sb.sb_blocksize == 0)
1283 goto done;
1284
1285 for (bsize = 1, i = 0; bsize < sb.sb_blocksize &&
1286 i < sizeof(sb.sb_blocksize) * NBBY; i++)
1287 bsize <<= 1;
1288
1289 if (i < XFS_MIN_BLOCKSIZE_LOG || i > XFS_MAX_BLOCKSIZE_LOG ||
1290 i != sb.sb_blocklog)
1291 goto done;
1292
1293 if (sb.sb_dblocks > ((uint64_t)sb.sb_agcount * sb.sb_agblocks) ||
1294 sb.sb_dblocks < ((uint64_t)(sb.sb_agcount - 1) *
1295 sb.sb_agblocks + XFS_MIN_AG_BLOCKS))
1296 goto done;
1297
1298 /*
1299 * block size and basic geometry seems alright, zero the secondaries.
1300 */
1301 memset(buf, 0, new_sb->sb_sectsize);
1302 off = 0;
1303 for (i = 1; i < sb.sb_agcount; i++) {
1304 off += sb.sb_agblocks;
1305 if (pwrite(xi->dfd, buf, new_sb->sb_sectsize,
1306 off << sb.sb_blocklog) == -1)
1307 break;
1308 }
1309 done:
1310 free(buf);
1311 }
1312
1313 static void
1314 discard_blocks(dev_t dev, uint64_t nsectors)
1315 {
1316 int fd;
1317
1318 /*
1319 * We intentionally ignore errors from the discard ioctl. It is
1320 * not necessary for the mkfs functionality but just an optimization.
1321 */
1322 fd = libxfs_device_to_fd(dev);
1323 if (fd > 0)
1324 platform_discard_blocks(fd, 0, nsectors << 9);
1325 }
1326
1327 static void
1328 sb_set_features(
1329 struct xfs_sb *sbp,
1330 struct sb_feat_args *fp,
1331 int sectsize,
1332 int lsectsize,
1333 int dsunit)
1334 {
1335
1336 sbp->sb_versionnum = XFS_DFL_SB_VERSION_BITS;
1337 if (fp->crcs_enabled)
1338 sbp->sb_versionnum |= XFS_SB_VERSION_5;
1339 else
1340 sbp->sb_versionnum |= XFS_SB_VERSION_4;
1341
1342 if (fp->inode_align)
1343 sbp->sb_versionnum |= XFS_SB_VERSION_ALIGNBIT;
1344 if (dsunit)
1345 sbp->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT;
1346 if (fp->log_version == 2)
1347 sbp->sb_versionnum |= XFS_SB_VERSION_LOGV2BIT;
1348 if (fp->attr_version == 1)
1349 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
1350 if (sectsize > BBSIZE || lsectsize > BBSIZE)
1351 sbp->sb_versionnum |= XFS_SB_VERSION_SECTORBIT;
1352 if (fp->nci)
1353 sbp->sb_versionnum |= XFS_SB_VERSION_BORGBIT;
1354
1355
1356 sbp->sb_features2 = 0;
1357 if (fp->lazy_sb_counters)
1358 sbp->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
1359 if (!fp->projid16bit)
1360 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
1361 if (fp->parent_pointers)
1362 sbp->sb_features2 |= XFS_SB_VERSION2_PARENTBIT;
1363 if (fp->crcs_enabled)
1364 sbp->sb_features2 |= XFS_SB_VERSION2_CRCBIT;
1365 if (fp->attr_version == 2)
1366 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
1367
1368 /* v5 superblocks have their own feature bit for dirftype */
1369 if (fp->dirftype && !fp->crcs_enabled)
1370 sbp->sb_features2 |= XFS_SB_VERSION2_FTYPE;
1371
1372 /* update whether extended features are in use */
1373 if (sbp->sb_features2 != 0)
1374 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
1375
1376 /*
1377 * Due to a structure alignment issue, sb_features2 ended up in one
1378 * of two locations, the second "incorrect" location represented by
1379 * the sb_bad_features2 field. To avoid older kernels mounting
1380 * filesystems they shouldn't, set both field to the same value.
1381 */
1382 sbp->sb_bad_features2 = sbp->sb_features2;
1383
1384 if (!fp->crcs_enabled)
1385 return;
1386
1387 /* default features for v5 filesystems */
1388 sbp->sb_features_compat = 0;
1389 sbp->sb_features_ro_compat = 0;
1390 sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE;
1391 sbp->sb_features_log_incompat = 0;
1392
1393 if (fp->finobt)
1394 sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT;
1395 if (fp->rmapbt)
1396 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT;
1397 if (fp->reflink)
1398 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
1399
1400 /*
1401 * Sparse inode chunk support has two main inode alignment requirements.
1402 * First, sparse chunk alignment must match the cluster size. Second,
1403 * full chunk alignment must match the inode chunk size.
1404 *
1405 * Copy the already calculated/scaled inoalignmt to spino_align and
1406 * update the former to the full inode chunk size.
1407 */
1408 if (fp->spinodes) {
1409 sbp->sb_spino_align = sbp->sb_inoalignmt;
1410 sbp->sb_inoalignmt = XFS_INODES_PER_CHUNK *
1411 sbp->sb_inodesize >> sbp->sb_blocklog;
1412 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
1413 }
1414
1415 }
1416
1417 static __attribute__((noreturn)) void
1418 illegal_option(
1419 const char *value,
1420 struct opt_params *opts,
1421 int index,
1422 const char *reason)
1423 {
1424 fprintf(stderr,
1425 _("Illegal value %s for -%c %s option. %s\n"),
1426 value, opts->name, opts->subopts[index],
1427 reason ? reason : "");
1428 usage();
1429 }
1430
1431 /*
1432 * Check for conflicts and option respecification.
1433 */
1434 static void
1435 check_opt(
1436 struct opt_params *opts,
1437 int index,
1438 bool str_seen)
1439 {
1440 struct subopt_param *sp = &opts->subopt_params[index];
1441 int i;
1442
1443 if (sp->index != index) {
1444 fprintf(stderr,
1445 _("Developer screwed up option parsing (%d/%d)! Please report!\n"),
1446 sp->index, index);
1447 reqval(opts->name, opts->subopts, index);
1448 }
1449
1450 /*
1451 * Check for respecification of the option. This is more complex than it
1452 * seems because some options are parsed twice - once as a string during
1453 * input parsing, then later the string is passed to getnum for
1454 * conversion into a number and bounds checking. Hence the two variables
1455 * used to track the different uses based on the @str parameter passed
1456 * to us.
1457 */
1458 if (!str_seen) {
1459 if (sp->seen)
1460 respec(opts->name, opts->subopts, index);
1461 sp->seen = true;
1462 } else {
1463 if (sp->str_seen)
1464 respec(opts->name, opts->subopts, index);
1465 sp->str_seen = true;
1466 }
1467
1468 /* check for conflicts with the option */
1469 for (i = 0; i < MAX_CONFLICTS; i++) {
1470 int conflict_opt = sp->conflicts[i];
1471
1472 if (conflict_opt == LAST_CONFLICT)
1473 break;
1474 if (opts->subopt_params[conflict_opt].seen ||
1475 opts->subopt_params[conflict_opt].str_seen)
1476 conflict(opts->name, opts->subopts,
1477 conflict_opt, index);
1478 }
1479 }
1480
1481 static long long
1482 getnum(
1483 const char *str,
1484 struct opt_params *opts,
1485 int index)
1486 {
1487 struct subopt_param *sp = &opts->subopt_params[index];
1488 long long c;
1489
1490 check_opt(opts, index, false);
1491 /* empty strings might just return a default value */
1492 if (!str || *str == '\0') {
1493 if (sp->defaultval == SUBOPT_NEEDS_VAL)
1494 reqval(opts->name, opts->subopts, index);
1495 return sp->defaultval;
1496 }
1497
1498 if (sp->minval == 0 && sp->maxval == 0) {
1499 fprintf(stderr,
1500 _("Option -%c %s has undefined minval/maxval."
1501 "Can't verify value range. This is a bug.\n"),
1502 opts->name, opts->subopts[index]);
1503 exit(1);
1504 }
1505
1506 /*
1507 * Some values are pure numbers, others can have suffixes that define
1508 * the units of the number. Those get passed to cvtnum(), otherwise we
1509 * convert it ourselves to guarantee there is no trailing garbage in the
1510 * number.
1511 */
1512 if (sp->convert)
1513 c = cvtnum(blocksize, sectorsize, str);
1514 else {
1515 char *str_end;
1516
1517 c = strtoll(str, &str_end, 0);
1518 if (c == 0 && str_end == str)
1519 illegal_option(str, opts, index, NULL);
1520 if (*str_end != '\0')
1521 illegal_option(str, opts, index, NULL);
1522 }
1523
1524 /* Validity check the result. */
1525 if (c < sp->minval)
1526 illegal_option(str, opts, index, _("value is too small"));
1527 else if (c > sp->maxval)
1528 illegal_option(str, opts, index, _("value is too large"));
1529 if (sp->is_power_2 && !ispow2(c))
1530 illegal_option(str, opts, index, _("value must be a power of 2"));
1531 return c;
1532 }
1533
1534 /*
1535 * Option is a string - do all the option table work, and check there
1536 * is actually an option string. Otherwise we don't do anything with the string
1537 * here - validation will be done later when the string is converted to a value
1538 * or used as a file/device path.
1539 */
1540 static char *
1541 getstr(
1542 char *str,
1543 struct opt_params *opts,
1544 int index)
1545 {
1546 check_opt(opts, index, true);
1547
1548 /* empty strings for string options are not valid */
1549 if (!str || *str == '\0')
1550 reqval(opts->name, opts->subopts, index);
1551 return str;
1552 }
1553
1554 static int
1555 block_opts_parser(
1556 struct opt_params *opts,
1557 int subopt,
1558 char *value,
1559 struct cli_params *cli)
1560 {
1561 int blocklog;
1562
1563 switch (subopt) {
1564 case B_LOG:
1565 blocklog = getnum(value, opts, B_LOG);
1566 cli->blocksize = 1 << blocklog;
1567 break;
1568 case B_SIZE:
1569 cli->blocksize = getnum(value, opts, B_SIZE);
1570 break;
1571 default:
1572 return -EINVAL;
1573 }
1574 return 0;
1575 }
1576
1577 static int
1578 data_opts_parser(
1579 struct opt_params *opts,
1580 int subopt,
1581 char *value,
1582 struct cli_params *cli)
1583 {
1584 int sectorlog;
1585
1586 switch (subopt) {
1587 case D_AGCOUNT:
1588 cli->agcount = getnum(value, opts, D_AGCOUNT);
1589 break;
1590 case D_AGSIZE:
1591 cli->agsize = getstr(value, opts, D_AGSIZE);
1592 break;
1593 case D_FILE:
1594 cli->xi->disfile = getnum(value, opts, D_FILE);
1595 break;
1596 case D_NAME:
1597 cli->xi->dname = getstr(value, opts, D_NAME);
1598 break;
1599 case D_SIZE:
1600 cli->dsize = getstr(value, opts, D_SIZE);
1601 break;
1602 case D_SUNIT:
1603 cli->dsunit = getnum(value, opts, D_SUNIT);
1604 break;
1605 case D_SWIDTH:
1606 cli->dswidth = getnum(value, opts, D_SWIDTH);
1607 break;
1608 case D_SU:
1609 cli->dsu = getstr(value, opts, D_SU);
1610 break;
1611 case D_SW:
1612 cli->dsw = getnum(value, opts, D_SW);
1613 break;
1614 case D_NOALIGN:
1615 cli->sb_feat.nodalign = getnum(value, opts, D_NOALIGN);
1616 break;
1617 case D_SECTLOG:
1618 if (cli->sectorsize)
1619 conflict('d', opts->subopts, D_SECTSIZE, D_SECTLOG);
1620 sectorlog = getnum(value, opts, D_SECTLOG);
1621 cli->sectorsize = 1 << sectorlog;
1622 break;
1623 case D_SECTSIZE:
1624 if (cli->sectorsize)
1625 conflict('d', opts->subopts, D_SECTSIZE, D_SECTLOG);
1626 cli->sectorsize = getnum(value, opts, D_SECTSIZE);
1627 break;
1628 case D_RTINHERIT:
1629 if (getnum(value, opts, D_RTINHERIT))
1630 cli->fsx.fsx_xflags |= XFS_DIFLAG_RTINHERIT;
1631 break;
1632 case D_PROJINHERIT:
1633 cli->fsx.fsx_projid = getnum(value, opts, D_PROJINHERIT);
1634 cli->fsx.fsx_xflags |= XFS_DIFLAG_PROJINHERIT;
1635 break;
1636 case D_EXTSZINHERIT:
1637 cli->fsx.fsx_extsize = getnum(value, opts, D_EXTSZINHERIT);
1638 cli->fsx.fsx_xflags |= XFS_DIFLAG_EXTSZINHERIT;
1639 break;
1640 case D_COWEXTSIZE:
1641 cli->fsx.fsx_cowextsize = getnum(value, opts, D_COWEXTSIZE);
1642 cli->fsx.fsx_xflags |= FS_XFLAG_COWEXTSIZE;
1643 break;
1644 default:
1645 return -EINVAL;
1646 }
1647 return 0;
1648 }
1649
1650 static int
1651 inode_opts_parser(
1652 struct opt_params *opts,
1653 int subopt,
1654 char *value,
1655 struct cli_params *cli)
1656 {
1657 int inodelog;
1658
1659 switch (subopt) {
1660 case I_ALIGN:
1661 cli->sb_feat.inode_align = getnum(value, &iopts, I_ALIGN);
1662 break;
1663 case I_LOG:
1664 inodelog = getnum(value, &iopts, I_LOG);
1665 cli->inodesize = 1 << inodelog;
1666 break;
1667 case I_MAXPCT:
1668 cli->imaxpct = getnum(value, &iopts, I_MAXPCT);
1669 break;
1670 case I_PERBLOCK:
1671 cli->inopblock = getnum(value, &iopts, I_PERBLOCK);
1672 break;
1673 case I_SIZE:
1674 cli->inodesize = getnum(value, &iopts, I_SIZE);
1675 break;
1676 case I_ATTR:
1677 cli->sb_feat.attr_version = getnum(value, &iopts, I_ATTR);
1678 break;
1679 case I_PROJID32BIT:
1680 cli->sb_feat.projid16bit = !getnum(value, &iopts, I_PROJID32BIT);
1681 break;
1682 case I_SPINODES:
1683 cli->sb_feat.spinodes = getnum(value, &iopts, I_SPINODES);
1684 break;
1685 default:
1686 return -EINVAL;
1687 }
1688 return 0;
1689 }
1690
1691 static int
1692 log_opts_parser(
1693 struct opt_params *opts,
1694 int subopt,
1695 char *value,
1696 struct cli_params *cli)
1697 {
1698 int lsectorlog;
1699
1700 switch (subopt) {
1701 case L_AGNUM:
1702 cli->logagno = getnum(value, &lopts, L_AGNUM);
1703 break;
1704 case L_FILE:
1705 cli->xi->lisfile = getnum(value, &lopts, L_FILE);
1706 break;
1707 case L_INTERNAL:
1708 cli->loginternal = getnum(value, &lopts, L_INTERNAL);
1709 break;
1710 case L_SU:
1711 cli->lsu = getstr(value, &lopts, L_SU);
1712 break;
1713 case L_SUNIT:
1714 cli->lsunit = getnum(value, &lopts, L_SUNIT);
1715 break;
1716 case L_NAME:
1717 case L_DEV:
1718 cli->xi->logname = getstr(value, &lopts, L_NAME);
1719 cli->loginternal = 0;
1720 break;
1721 case L_VERSION:
1722 cli->sb_feat.log_version = getnum(value, &lopts, L_VERSION);
1723 break;
1724 case L_SIZE:
1725 cli->logsize = getstr(value, &lopts, L_SIZE);
1726 break;
1727 case L_SECTLOG:
1728 lsectorlog = getnum(value, &lopts, L_SECTLOG);
1729 cli->lsectorsize = 1 << lsectorlog;
1730 break;
1731 case L_SECTSIZE:
1732 cli->lsectorsize = getnum(value, &lopts, L_SECTSIZE);
1733 break;
1734 case L_LAZYSBCNTR:
1735 cli->sb_feat.lazy_sb_counters = getnum(value, &lopts, L_LAZYSBCNTR);
1736 break;
1737 default:
1738 return -EINVAL;
1739 }
1740 return 0;
1741 }
1742
1743 static int
1744 meta_opts_parser(
1745 struct opt_params *opts,
1746 int subopt,
1747 char *value,
1748 struct cli_params *cli)
1749 {
1750 switch (subopt) {
1751 case M_CRC:
1752 cli->sb_feat.crcs_enabled = getnum(value, &mopts, M_CRC);
1753 if (cli->sb_feat.crcs_enabled)
1754 cli->sb_feat.dirftype = true;
1755 break;
1756 case M_FINOBT:
1757 cli->sb_feat.finobt = getnum(value, &mopts, M_FINOBT);
1758 break;
1759 case M_UUID:
1760 if (!value || *value == '\0')
1761 reqval('m', opts->subopts, M_UUID);
1762 if (platform_uuid_parse(value, &cli->uuid))
1763 illegal(value, "m uuid");
1764 break;
1765 case M_RMAPBT:
1766 cli->sb_feat.rmapbt = getnum(value, &mopts, M_RMAPBT);
1767 break;
1768 case M_REFLINK:
1769 cli->sb_feat.reflink = getnum(value, &mopts, M_REFLINK);
1770 break;
1771 default:
1772 return -EINVAL;
1773 }
1774 return 0;
1775 }
1776
1777 static int
1778 naming_opts_parser(
1779 struct opt_params *opts,
1780 int subopt,
1781 char *value,
1782 struct cli_params *cli)
1783 {
1784 switch (subopt) {
1785 case N_LOG:
1786 cli->dirblocklog = getnum(value, opts, N_LOG);
1787 break;
1788 case N_SIZE:
1789 cli->dirblocksize = getstr(value, opts, N_SIZE);
1790 break;
1791 case N_VERSION:
1792 value = getstr(value, &nopts, N_VERSION);
1793 if (!strcasecmp(value, "ci")) {
1794 /* ASCII CI mode */
1795 cli->sb_feat.nci = true;
1796 } else {
1797 cli->sb_feat.dir_version = getnum(value, opts, N_VERSION);
1798 }
1799 break;
1800 case N_FTYPE:
1801 cli->sb_feat.dirftype = getnum(value, opts, N_FTYPE);
1802 break;
1803 default:
1804 return -EINVAL;
1805 }
1806 return 0;
1807 }
1808
1809 static int
1810 rtdev_opts_parser(
1811 struct opt_params *opts,
1812 int subopt,
1813 char *value,
1814 struct cli_params *cli)
1815 {
1816 switch (subopt) {
1817 case R_EXTSIZE:
1818 cli->rtextsize = getstr(value, &ropts, R_EXTSIZE);
1819 break;
1820 case R_FILE:
1821 cli->xi->risfile = getnum(value, &ropts, R_FILE);
1822 break;
1823 case R_NAME:
1824 case R_DEV:
1825 cli->xi->rtname = getstr(value, &ropts, R_NAME);
1826 break;
1827 case R_SIZE:
1828 cli->rtsize = getstr(value, &ropts, R_SIZE);
1829 break;
1830 case R_NOALIGN:
1831 cli->sb_feat.nortalign = getnum(value, &ropts, R_NOALIGN);
1832 break;
1833 default:
1834 return -EINVAL;
1835 }
1836 return 0;
1837 }
1838
1839 static int
1840 sector_opts_parser(
1841 struct opt_params *opts,
1842 int subopt,
1843 char *value,
1844 struct cli_params *cli)
1845 {
1846 int sectorlog;
1847
1848 switch (subopt) {
1849 case S_LOG:
1850 case S_SECTLOG:
1851 if (cli->sectorsize)
1852 conflict('s', opts->subopts, S_SECTSIZE, S_SECTLOG);
1853 sectorlog = getnum(value, &sopts, S_SECTLOG);
1854 cli->sectorsize = 1 << sectorlog;
1855 cli->lsectorsize = cli->sectorsize;
1856 break;
1857 case S_SIZE:
1858 case S_SECTSIZE:
1859 if (cli->sectorsize)
1860 conflict('s', opts->subopts, S_SECTLOG, S_SECTSIZE);
1861 cli->sectorsize = getnum(value, &sopts, S_SECTSIZE);
1862 cli->lsectorsize = cli->sectorsize;
1863 break;
1864 default:
1865 return -EINVAL;
1866 }
1867 return 0;
1868 }
1869
1870 struct subopts {
1871 char opt;
1872 struct opt_params *opts;
1873 int (*parser)();
1874 } subopt_tab[] = {
1875 { 'b', &bopts, block_opts_parser },
1876 { 'd', &dopts, data_opts_parser },
1877 { 'i', &iopts, inode_opts_parser },
1878 { 'l', &lopts, log_opts_parser },
1879 { 'm', &mopts, meta_opts_parser },
1880 { 'n', &nopts, naming_opts_parser },
1881 { 'r', &ropts, rtdev_opts_parser },
1882 { 's', &sopts, sector_opts_parser },
1883 { '\0', NULL, NULL },
1884 };
1885
1886 static void
1887 parse_subopts(
1888 char opt,
1889 char *arg,
1890 struct cli_params *cli)
1891 {
1892 struct subopts *sop = &subopt_tab[0];
1893 char *p;
1894 int ret = 0;
1895
1896 while (sop->opts) {
1897 if (sop->opt == opt)
1898 break;
1899 sop++;
1900 }
1901
1902 /* should never happen */
1903 if (!sop->opts)
1904 return;
1905
1906 p = arg;
1907 while (*p != '\0') {
1908 char **subopts = (char **)sop->opts->subopts;
1909 char *value;
1910 int subopt;
1911
1912 subopt = getsubopt(&p, subopts, &value);
1913
1914 ret = (sop->parser)(sop->opts, subopt, value, cli);
1915 if (ret)
1916 unknown(opt, value);
1917 }
1918 }
1919
1920 static void
1921 validate_sectorsize(
1922 struct mkfs_params *cfg,
1923 struct cli_params *cli,
1924 struct mkfs_default_params *dft,
1925 struct fs_topology *ft,
1926 char *dfile,
1927 int dry_run,
1928 int force_overwrite)
1929 {
1930 /* set configured sector sizes in preparation for checks */
1931 if (!cli->sectorsize) {
1932 cfg->sectorsize = dft->sectorsize;
1933 } else {
1934 cfg->sectorsize = cli->sectorsize;
1935 }
1936 cfg->sectorlog = libxfs_highbit32(cfg->sectorsize);
1937
1938 /*
1939 * Before anything else, verify that we are correctly operating on
1940 * files or block devices and set the control parameters correctly.
1941 */
1942 check_device_type(dfile, &cli->xi->disfile, !cli->dsize, !dfile,
1943 dry_run ? NULL : &cli->xi->dcreat,
1944 force_overwrite, "d");
1945 if (!cli->loginternal)
1946 check_device_type(cli->xi->logname, &cli->xi->lisfile,
1947 !cli->logsize, !cli->xi->logname,
1948 dry_run ? NULL : &cli->xi->lcreat,
1949 force_overwrite, "l");
1950 if (cli->xi->rtname)
1951 check_device_type(cli->xi->rtname, &cli->xi->risfile,
1952 !cli->rtsize, !cli->xi->rtname,
1953 dry_run ? NULL : &cli->xi->rcreat,
1954 force_overwrite, "r");
1955
1956 /*
1957 * Explicitly disable direct IO for image files so we don't error out on
1958 * sector size mismatches between the new filesystem and the underlying
1959 * host filesystem.
1960 */
1961 if (cli->xi->disfile || cli->xi->lisfile || cli->xi->risfile)
1962 cli->xi->isdirect = 0;
1963
1964 memset(ft, 0, sizeof(*ft));
1965 get_topology(cli->xi, ft, force_overwrite);
1966
1967 if (!cli->sectorsize) {
1968 /*
1969 * Unless specified manually on the command line use the
1970 * advertised sector size of the device. We use the physical
1971 * sector size unless the requested block size is smaller
1972 * than that, then we can use logical, but warn about the
1973 * inefficiency.
1974 *
1975 * Set the topology sectors if they were not probed to the
1976 * minimum supported sector size.
1977 */
1978
1979 if (!ft->lsectorsize)
1980 ft->lsectorsize = XFS_MIN_SECTORSIZE;
1981
1982 /* Older kernels may not have physical/logical distinction */
1983 if (!ft->psectorsize)
1984 ft->psectorsize = ft->lsectorsize;
1985
1986 cfg->sectorsize = ft->psectorsize;
1987 if (cfg->blocksize < cfg->sectorsize &&
1988 cfg->blocksize >= ft->lsectorsize) {
1989 fprintf(stderr,
1990 _("specified blocksize %d is less than device physical sector size %d\n"
1991 "switching to logical sector size %d\n"),
1992 cfg->blocksize, ft->psectorsize,
1993 ft->lsectorsize);
1994 cfg->sectorsize = ft->lsectorsize;
1995 }
1996
1997 cfg->sectorlog = libxfs_highbit32(cfg->sectorsize);
1998 }
1999
2000 /* validate specified/probed sector size */
2001 if (cfg->sectorsize < XFS_MIN_SECTORSIZE ||
2002 cfg->sectorsize > XFS_MAX_SECTORSIZE) {
2003 fprintf(stderr, _("illegal sector size %d\n"), cfg->sectorsize);
2004 usage();
2005 }
2006
2007 if (cfg->blocksize < cfg->sectorsize) {
2008 fprintf(stderr,
2009 _("block size %d cannot be smaller than sector size %d\n"),
2010 cfg->blocksize, cfg->sectorsize);
2011 usage();
2012 }
2013
2014 if (cfg->sectorsize < ft->lsectorsize) {
2015 fprintf(stderr, _("illegal sector size %d; hw sector is %d\n"),
2016 cfg->sectorsize, ft->lsectorsize);
2017 usage();
2018 }
2019 }
2020
2021 static void
2022 validate_blocksize(
2023 struct mkfs_params *cfg,
2024 struct cli_params *cli,
2025 struct mkfs_default_params *dft)
2026 {
2027 /*
2028 * Blocksize and sectorsize first, other things depend on them
2029 * For RAID4/5/6 we want to align sector size and block size,
2030 * so we need to start with the device geometry extraction too.
2031 */
2032 if (!cli->blocksize)
2033 cfg->blocksize = dft->blocksize;
2034 else
2035 cfg->blocksize = cli->blocksize;
2036 cfg->blocklog = libxfs_highbit32(cfg->blocksize);
2037
2038 /* validate block sizes are in range */
2039 if (cfg->blocksize < XFS_MIN_BLOCKSIZE ||
2040 cfg->blocksize > XFS_MAX_BLOCKSIZE) {
2041 fprintf(stderr, _("illegal block size %d\n"), cfg->blocksize);
2042 usage();
2043 }
2044
2045 if (cli->sb_feat.crcs_enabled &&
2046 cfg->blocksize < XFS_MIN_CRC_BLOCKSIZE) {
2047 fprintf(stderr,
2048 _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
2049 XFS_MIN_CRC_BLOCKSIZE);
2050 usage();
2051 }
2052
2053 }
2054
2055 /*
2056 * Grab log sector size and validate.
2057 *
2058 * XXX: should we probe sector size on external log device rather than using
2059 * the data device sector size?
2060 */
2061 static void
2062 validate_log_sectorsize(
2063 struct mkfs_params *cfg,
2064 struct cli_params *cli,
2065 struct mkfs_default_params *dft)
2066 {
2067
2068 if (cli->loginternal && cli->lsectorsize &&
2069 cli->lsectorsize != cfg->sectorsize) {
2070 fprintf(stderr,
2071 _("Can't change sector size on internal log!\n"));
2072 usage();
2073 }
2074
2075 if (cli->lsectorsize)
2076 cfg->lsectorsize = cli->lsectorsize;
2077 else if (cli->loginternal)
2078 cfg->lsectorsize = cfg->sectorsize;
2079 else
2080 cfg->lsectorsize = dft->sectorsize;
2081 cfg->lsectorlog = libxfs_highbit32(cfg->lsectorsize);
2082
2083 if (cfg->lsectorsize < XFS_MIN_SECTORSIZE ||
2084 cfg->lsectorsize > XFS_MAX_SECTORSIZE ||
2085 cfg->lsectorsize > cfg->blocksize) {
2086 fprintf(stderr, _("illegal log sector size %d\n"),
2087 cfg->lsectorsize);
2088 usage();
2089 }
2090 if (cfg->lsectorsize > XFS_MIN_SECTORSIZE) {
2091 if (cli->sb_feat.log_version < 2) {
2092 /* user specified non-default log version */
2093 fprintf(stderr,
2094 _("Version 1 logs do not support sector size %d\n"),
2095 cfg->lsectorsize);
2096 usage();
2097 }
2098 }
2099
2100 /* if lsu or lsunit was specified, automatically use v2 logs */
2101 if ((cli_opt_set(&lopts, L_SU) || cli_opt_set(&lopts, L_SUNIT)) &&
2102 cli->sb_feat.log_version == 1) {
2103 fprintf(stderr,
2104 _("log stripe unit specified, using v2 logs\n"));
2105 cli->sb_feat.log_version = 2;
2106 }
2107
2108 }
2109
2110 /*
2111 * Check that the incoming features make sense. The CLI structure was
2112 * initialised with the default values before parsing, so we can just
2113 * check it and copy it straight across to the cfg structure if it
2114 * checks out.
2115 */
2116 static void
2117 validate_sb_features(
2118 struct mkfs_params *cfg,
2119 struct cli_params *cli)
2120 {
2121 /*
2122 * Now we have blocks and sector sizes set up, check parameters that are
2123 * no longer optional for CRC enabled filesystems. Catch them up front
2124 * here before doing anything else.
2125 */
2126 if (cli->sb_feat.crcs_enabled) {
2127 /* minimum inode size is 512 bytes, rest checked later */
2128 if (cli->inodesize &&
2129 cli->inodesize < (1 << XFS_DINODE_DFL_CRC_LOG)) {
2130 fprintf(stderr,
2131 _("Minimum inode size for CRCs is %d bytes\n"),
2132 1 << XFS_DINODE_DFL_CRC_LOG);
2133 usage();
2134 }
2135
2136 /* inodes always aligned */
2137 if (!cli->sb_feat.inode_align) {
2138 fprintf(stderr,
2139 _("Inodes always aligned for CRC enabled filesytems\n"));
2140 usage();
2141 }
2142
2143 /* lazy sb counters always on */
2144 if (!cli->sb_feat.lazy_sb_counters) {
2145 fprintf(stderr,
2146 _("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
2147 usage();
2148 }
2149
2150 /* version 2 logs always on */
2151 if (cli->sb_feat.log_version != 2) {
2152 fprintf(stderr,
2153 _("V2 logs always enabled for CRC enabled filesytems\n"));
2154 usage();
2155 }
2156
2157 /* attr2 always on */
2158 if (cli->sb_feat.attr_version != 2) {
2159 fprintf(stderr,
2160 _("V2 attribute format always enabled on CRC enabled filesytems\n"));
2161 usage();
2162 }
2163
2164 /* 32 bit project quota always on */
2165 /* attr2 always on */
2166 if (cli->sb_feat.projid16bit) {
2167 fprintf(stderr,
2168 _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
2169 usage();
2170 }
2171
2172 /* ftype always on */
2173 if (!cli->sb_feat.dirftype) {
2174 fprintf(stderr,
2175 _("Directory ftype field always enabled on CRC enabled filesytems\n"));
2176 usage();
2177 }
2178
2179 } else {
2180 /*
2181 * The kernel doesn't currently support crc=0,finobt=1
2182 * filesystems. If crcs are not enabled and the user has not
2183 * explicitly turned finobt on, then silently turn it off to
2184 * avoid an unnecessary warning.
2185 * If the user explicitly tried to use crc=0,finobt=1,
2186 * then issue an error.
2187 * The same is also for sparse inodes.
2188 */
2189 if (cli->sb_feat.finobt && cli_opt_set(&mopts, M_FINOBT)) {
2190 fprintf(stderr,
2191 _("finobt not supported without CRC support\n"));
2192 usage();
2193 }
2194 cli->sb_feat.finobt = false;
2195
2196 if (cli->sb_feat.spinodes) {
2197 fprintf(stderr,
2198 _("sparse inodes not supported without CRC support\n"));
2199 usage();
2200 }
2201 cli->sb_feat.spinodes = false;
2202
2203 if (cli->sb_feat.rmapbt) {
2204 fprintf(stderr,
2205 _("rmapbt not supported without CRC support\n"));
2206 usage();
2207 }
2208 cli->sb_feat.rmapbt = false;
2209
2210 if (cli->sb_feat.reflink) {
2211 fprintf(stderr,
2212 _("reflink not supported without CRC support\n"));
2213 usage();
2214 }
2215 cli->sb_feat.reflink = false;
2216 }
2217
2218 if ((cli->fsx.fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
2219 !cli->sb_feat.reflink) {
2220 fprintf(stderr,
2221 _("cowextsize not supported without reflink support\n"));
2222 usage();
2223 }
2224
2225 if (cli->sb_feat.rmapbt && cli->xi->rtname) {
2226 fprintf(stderr,
2227 _("rmapbt not supported with realtime devices\n"));
2228 usage();
2229 cli->sb_feat.rmapbt = false;
2230 }
2231
2232 /*
2233 * Copy features across to config structure now.
2234 */
2235 cfg->sb_feat = cli->sb_feat;
2236 if (!platform_uuid_is_null(&cli->uuid))
2237 platform_uuid_copy(&cfg->uuid, &cli->uuid);
2238 }
2239
2240 static void
2241 validate_dirblocksize(
2242 struct mkfs_params *cfg,
2243 struct cli_params *cli)
2244 {
2245
2246 if (cli->dirblocksize)
2247 cfg->dirblocksize = getnum(cli->dirblocksize, &nopts, N_SIZE);
2248 if (cli->dirblocklog)
2249 cfg->dirblocksize = 1 << cli->dirblocklog;
2250
2251 if (cfg->dirblocksize) {
2252 if (cfg->dirblocksize < cfg->blocksize ||
2253 cfg->dirblocksize > XFS_MAX_BLOCKSIZE) {
2254 fprintf(stderr, _("illegal directory block size %d\n"),
2255 cfg->dirblocksize);
2256 usage();
2257 }
2258 cfg->dirblocklog = libxfs_highbit32(cfg->dirblocksize);
2259 return;
2260 }
2261
2262 /* use default size based on current block size */
2263 if (cfg->blocksize < (1 << XFS_MIN_REC_DIRSIZE))
2264 cfg->dirblocklog = XFS_MIN_REC_DIRSIZE;
2265 else
2266 cfg->dirblocklog = cfg->blocklog;
2267 cfg->dirblocksize = 1 << cfg->dirblocklog;
2268 }
2269
2270 static void
2271 validate_inodesize(
2272 struct mkfs_params *cfg,
2273 struct cli_params *cli)
2274 {
2275
2276 if (cli->inopblock)
2277 cfg->inodelog = cfg->blocklog - libxfs_highbit32(cli->inopblock);
2278 else if (cli->inodesize)
2279 cfg->inodelog = libxfs_highbit32(cli->inodesize);
2280 else if (cfg->sb_feat.crcs_enabled)
2281 cfg->inodelog = XFS_DINODE_DFL_CRC_LOG;
2282 else
2283 cfg->inodelog = XFS_DINODE_DFL_LOG;
2284
2285 cfg->inodesize = 1 << cfg->inodelog;
2286 cfg->inopblock = cfg->blocksize / cfg->inodesize;
2287
2288 /* input parsing has already validated non-crc inode size range */
2289 if (cfg->sb_feat.crcs_enabled &&
2290 cfg->inodelog < XFS_DINODE_DFL_CRC_LOG) {
2291 fprintf(stderr,
2292 _("Minimum inode size for CRCs is %d bytes\n"),
2293 1 << XFS_DINODE_DFL_CRC_LOG);
2294 usage();
2295 }
2296
2297 if (cfg->inodesize > cfg->blocksize / XFS_MIN_INODE_PERBLOCK ||
2298 cfg->inopblock < XFS_MIN_INODE_PERBLOCK ||
2299 cfg->inodesize < XFS_DINODE_MIN_SIZE ||
2300 cfg->inodesize > XFS_DINODE_MAX_SIZE) {
2301 int maxsz;
2302
2303 fprintf(stderr, _("illegal inode size %d\n"), cfg->inodesize);
2304 maxsz = MIN(cfg->blocksize / XFS_MIN_INODE_PERBLOCK,
2305 XFS_DINODE_MAX_SIZE);
2306 if (XFS_DINODE_MIN_SIZE == maxsz)
2307 fprintf(stderr,
2308 _("allowable inode size with %d byte blocks is %d\n"),
2309 cfg->blocksize, XFS_DINODE_MIN_SIZE);
2310 else
2311 fprintf(stderr,
2312 _("allowable inode size with %d byte blocks is between %d and %d\n"),
2313 cfg->blocksize, XFS_DINODE_MIN_SIZE, maxsz);
2314 exit(1);
2315 }
2316 }
2317
2318 static xfs_rfsblock_t
2319 calc_dev_size(
2320 char *size,
2321 struct mkfs_params *cfg,
2322 struct opt_params *opts,
2323 int sizeopt,
2324 char *type)
2325 {
2326 uint64_t dbytes;
2327 xfs_rfsblock_t dblocks;
2328
2329 if (!size)
2330 return 0;
2331
2332 dbytes = getnum(size, opts, sizeopt);
2333 if (dbytes % XFS_MIN_BLOCKSIZE) {
2334 fprintf(stderr,
2335 _("illegal %s length %lld, not a multiple of %d\n"),
2336 type, (long long)dbytes, XFS_MIN_BLOCKSIZE);
2337 usage();
2338 }
2339 dblocks = (xfs_rfsblock_t)(dbytes >> cfg->blocklog);
2340 if (dbytes % cfg->blocksize) {
2341 fprintf(stderr,
2342 _("warning: %s length %lld not a multiple of %d, truncated to %lld\n"),
2343 type, (long long)dbytes, cfg->blocksize,
2344 (long long)(dblocks << cfg->blocklog));
2345 }
2346 return dblocks;
2347 }
2348
2349 static void
2350 validate_rtextsize(
2351 struct mkfs_params *cfg,
2352 struct cli_params *cli,
2353 struct fs_topology *ft)
2354 {
2355 uint64_t rtextbytes;
2356
2357 /*
2358 * If specified, check rt extent size against its constraints.
2359 */
2360 if (cli->rtextsize) {
2361
2362 rtextbytes = getnum(cli->rtextsize, &ropts, R_EXTSIZE);
2363 if (rtextbytes % cfg->blocksize) {
2364 fprintf(stderr,
2365 _("illegal rt extent size %lld, not a multiple of %d\n"),
2366 (long long)rtextbytes, cfg->blocksize);
2367 usage();
2368 }
2369 cfg->rtextblocks = (xfs_extlen_t)(rtextbytes >> cfg->blocklog);
2370 } else {
2371 /*
2372 * If realtime extsize has not been specified by the user,
2373 * and the underlying volume is striped, then set rtextblocks
2374 * to the stripe width.
2375 */
2376 uint64_t rswidth;
2377
2378 if (!cfg->sb_feat.nortalign && !cli->xi->risfile &&
2379 !(!cli->rtsize && cli->xi->disfile))
2380 rswidth = ft->rtswidth;
2381 else
2382 rswidth = 0;
2383
2384 /* check that rswidth is a multiple of fs blocksize */
2385 if (!cfg->sb_feat.nortalign && rswidth &&
2386 !(BBTOB(rswidth) % cfg->blocksize)) {
2387 rswidth = DTOBT(rswidth, cfg->blocklog);
2388 rtextbytes = rswidth << cfg->blocklog;
2389 if (rtextbytes > XFS_MIN_RTEXTSIZE &&
2390 rtextbytes <= XFS_MAX_RTEXTSIZE) {
2391 cfg->rtextblocks = rswidth;
2392 }
2393 }
2394 if (!cfg->rtextblocks) {
2395 cfg->rtextblocks = (cfg->blocksize < XFS_MIN_RTEXTSIZE)
2396 ? XFS_MIN_RTEXTSIZE >> cfg->blocklog
2397 : 1;
2398 }
2399 }
2400 ASSERT(cfg->rtextblocks);
2401 }
2402
2403 static void
2404 print_mkfs_cfg(
2405 struct mkfs_params *cfg,
2406 char *dfile,
2407 char *logfile,
2408 char *rtfile)
2409 {
2410 struct sb_feat_args *fp = &cfg->sb_feat;
2411
2412 printf(_(
2413 "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
2414 " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
2415 " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u, reflink=%u\n"
2416 "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
2417 " =%-22s sunit=%-6u swidth=%u blks\n"
2418 "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n"
2419 "log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
2420 " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
2421 "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
2422 dfile, cfg->inodesize, (long long)cfg->agcount,
2423 (long long)cfg->agsize,
2424 "", cfg->sectorsize, fp->attr_version, !fp->projid16bit,
2425 "", fp->crcs_enabled, fp->finobt, fp->spinodes, fp->rmapbt,
2426 fp->reflink,
2427 "", cfg->blocksize, (long long)cfg->dblocks, cfg->imaxpct,
2428 "", cfg->dsunit, cfg->dswidth,
2429 fp->dir_version, cfg->dirblocksize, fp->nci, fp->dirftype,
2430 logfile, cfg->blocksize, (long long)cfg->logblocks,
2431 fp->log_version,
2432 "", cfg->lsectorsize, cfg->lsunit, fp->lazy_sb_counters,
2433 rtfile, (int)cfg->rtextblocks << cfg->blocklog,
2434 (long long)cfg->rtblocks, (long long)cfg->rtextents);
2435 }
2436
2437 /*
2438 * Format everything from the generated config into the superblock that
2439 * will be used to initialise the on-disk superblock. This is the in-memory
2440 * copy, so no need to care about endian swapping here.
2441 */
2442 static void
2443 setup_superblock(
2444 struct mkfs_params *cfg,
2445 struct xfs_mount *mp,
2446 struct xfs_sb *sbp)
2447 {
2448 if (cfg->label)
2449 strncpy(sbp->sb_fname, cfg->label, sizeof(sbp->sb_fname));
2450
2451 sbp->sb_magicnum = XFS_SB_MAGIC;
2452 sbp->sb_blocksize = cfg->blocksize;
2453 sbp->sb_dblocks = cfg->dblocks;
2454 sbp->sb_rblocks = cfg->rtblocks;
2455 sbp->sb_rextents = cfg->rtextents;
2456 platform_uuid_copy(&sbp->sb_uuid, &cfg->uuid);
2457 /* Only in memory; libxfs expects this as if read from disk */
2458 platform_uuid_copy(&sbp->sb_meta_uuid, &cfg->uuid);
2459 sbp->sb_logstart = cfg->logstart;
2460 sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
2461 sbp->sb_rextsize = cfg->rtextblocks;
2462 sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
2463 sbp->sb_rbmblocks = cfg->rtbmblocks;
2464 sbp->sb_logblocks = (xfs_extlen_t)cfg->logblocks;
2465 sbp->sb_sectsize = (uint16_t)cfg->sectorsize;
2466 sbp->sb_inodesize = (uint16_t)cfg->inodesize;
2467 sbp->sb_inopblock = (uint16_t)(cfg->blocksize / cfg->inodesize);
2468 sbp->sb_sectlog = (uint8_t)cfg->sectorlog;
2469 sbp->sb_inodelog = (uint8_t)cfg->inodelog;
2470 sbp->sb_inopblog = (uint8_t)(cfg->blocklog - cfg->inodelog);
2471 sbp->sb_rextslog = (uint8_t)(cfg->rtextents ?
2472 libxfs_highbit32((unsigned int)cfg->rtextents) : 0);
2473 sbp->sb_inprogress = 1; /* mkfs is in progress */
2474 sbp->sb_imax_pct = cfg->imaxpct;
2475 sbp->sb_icount = 0;
2476 sbp->sb_ifree = 0;
2477 sbp->sb_fdblocks = cfg->dblocks -
2478 cfg->agcount * libxfs_prealloc_blocks(mp) -
2479 (cfg->loginternal ? cfg->logblocks : 0);
2480 sbp->sb_frextents = 0; /* will do a free later */
2481 sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
2482 sbp->sb_qflags = 0;
2483 sbp->sb_unit = cfg->dsunit;
2484 sbp->sb_width = cfg->dswidth;
2485 sbp->sb_dirblklog = cfg->dirblocklog - cfg->blocklog;
2486
2487 /*
2488 * log stripe unit is stored in bytes on disk and cannot be zero
2489 * for v2 logs.
2490 */
2491 if (cfg->sb_feat.log_version == 2) {
2492 if (cfg->lsunit)
2493 sbp->sb_logsunit = XFS_FSB_TO_B(mp, cfg->lsunit);
2494 else
2495 sbp->sb_logsunit = 1;
2496 } else
2497 sbp->sb_logsunit = 0;
2498
2499 if (cfg->sb_feat.inode_align) {
2500 int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
2501 if (cfg->sb_feat.crcs_enabled)
2502 cluster_size *= cfg->inodesize / XFS_DINODE_MIN_SIZE;
2503 sbp->sb_inoalignmt = cluster_size >> cfg->blocklog;
2504 } else
2505 sbp->sb_inoalignmt = 0;
2506
2507 if (cfg->lsectorsize != BBSIZE || cfg->sectorsize != BBSIZE) {
2508 sbp->sb_logsectlog = (uint8_t)cfg->lsectorlog;
2509 sbp->sb_logsectsize = (uint16_t)cfg->lsectorsize;
2510 } else {
2511 sbp->sb_logsectlog = 0;
2512 sbp->sb_logsectsize = 0;
2513 }
2514 }
2515
2516 /*
2517 * Sanitise the data and log devices and prepare them so libxfs can mount the
2518 * device successfully. Also check we can access the rt device if configured.
2519 */
2520 static void
2521 prepare_devices(
2522 struct mkfs_params *cfg,
2523 struct libxfs_xinit *xi,
2524 struct xfs_mount *mp,
2525 struct xfs_sb *sbp,
2526 bool clear_stale)
2527 {
2528 struct xfs_buf *buf;
2529 int whack_blks = BTOBB(WHACK_SIZE);
2530 int lsunit;
2531
2532 /*
2533 * If there's an old XFS filesystem on the device with enough intact
2534 * information that we can parse the superblock, there's enough
2535 * information on disk to confuse a future xfs_repair call. To avoid
2536 * this, whack all the old secondary superblocks that we can find.
2537 */
2538 if (clear_stale)
2539 zero_old_xfs_structures(xi, sbp);
2540
2541 /*
2542 * If the data device is a file, grow out the file to its final size if
2543 * needed so that the reads for the end of the device in the mount code
2544 * will succeed.
2545 */
2546 if (xi->disfile &&
2547 xi->dsize * xi->dbsize < cfg->dblocks * cfg->blocksize) {
2548 if (ftruncate(xi->dfd, cfg->dblocks * cfg->blocksize) < 0) {
2549 fprintf(stderr,
2550 _("%s: Growing the data section failed\n"),
2551 progname);
2552 exit(1);
2553 }
2554
2555 /* update size to be able to whack blocks correctly */
2556 xi->dsize = BTOBB(cfg->dblocks * cfg->blocksize);
2557 }
2558
2559 /*
2560 * Zero out the end to obliterate any old MD RAID (or other) metadata at
2561 * the end of the device. (MD sb is ~64k from the end, take out a wider
2562 * swath to be sure)
2563 */
2564 buf = libxfs_getbuf(mp->m_ddev_targp, (xi->dsize - whack_blks),
2565 whack_blks);
2566 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
2567 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2568 libxfs_purgebuf(buf);
2569
2570 /*
2571 * Now zero out the beginning of the device, to obliterate any old
2572 * filesystem signatures out there. This should take care of
2573 * swap (somewhere around the page size), jfs (32k),
2574 * ext[2,3] and reiserfs (64k) - and hopefully all else.
2575 */
2576 buf = libxfs_getbuf(mp->m_ddev_targp, 0, whack_blks);
2577 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
2578 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2579 libxfs_purgebuf(buf);
2580
2581 /* OK, now write the superblock... */
2582 buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
2583 buf->b_ops = &xfs_sb_buf_ops;
2584 memset(XFS_BUF_PTR(buf), 0, cfg->sectorsize);
2585 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
2586 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2587 libxfs_purgebuf(buf);
2588
2589 /* ...and zero the log.... */
2590 lsunit = sbp->sb_logsunit;
2591 if (lsunit == 1)
2592 lsunit = sbp->sb_logsectsize;
2593
2594 libxfs_log_clear(mp->m_logdev_targp, NULL,
2595 XFS_FSB_TO_DADDR(mp, cfg->logstart),
2596 (xfs_extlen_t)XFS_FSB_TO_BB(mp, cfg->logblocks),
2597 &sbp->sb_uuid, cfg->sb_feat.log_version,
2598 lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
2599
2600 /* finally, check we can write the last block in the realtime area */
2601 if (mp->m_rtdev_targp->dev && cfg->rtblocks > 0) {
2602 buf = libxfs_getbuf(mp->m_rtdev_targp,
2603 XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
2604 BTOBB(cfg->blocksize));
2605 memset(XFS_BUF_PTR(buf), 0, cfg->blocksize);
2606 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2607 libxfs_purgebuf(buf);
2608 }
2609
2610 }
2611
2612 /*
2613 * XXX: this code is mostly common with the kernel growfs code.
2614 * These initialisations should be pulled into libxfs to keep the
2615 * kernel/userspace header initialisation code the same.
2616 */
2617 static void
2618 initialise_ag_headers(
2619 struct mkfs_params *cfg,
2620 struct xfs_mount *mp,
2621 struct xfs_sb *sbp,
2622 xfs_agnumber_t agno,
2623 int *worst_freelist)
2624 {
2625 struct xfs_perag *pag = libxfs_perag_get(mp, agno);
2626 struct xfs_agfl *agfl;
2627 struct xfs_agf *agf;
2628 struct xfs_agi *agi;
2629 struct xfs_buf *buf;
2630 struct xfs_btree_block *block;
2631 struct xfs_alloc_rec *arec;
2632 struct xfs_alloc_rec *nrec;
2633 int bucket;
2634 uint64_t agsize = cfg->agsize;
2635 xfs_agblock_t agblocks;
2636 bool is_log_ag = false;
2637 int c;
2638
2639 if (cfg->loginternal && agno == cfg->logagno)
2640 is_log_ag = true;
2641
2642 /*
2643 * Superblock.
2644 */
2645 buf = libxfs_getbuf(mp->m_ddev_targp,
2646 XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
2647 XFS_FSS_TO_BB(mp, 1));
2648 buf->b_ops = &xfs_sb_buf_ops;
2649 memset(XFS_BUF_PTR(buf), 0, cfg->sectorsize);
2650 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
2651 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2652
2653 /*
2654 * AG header block: freespace
2655 */
2656 buf = libxfs_getbuf(mp->m_ddev_targp,
2657 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
2658 XFS_FSS_TO_BB(mp, 1));
2659 buf->b_ops = &xfs_agf_buf_ops;
2660 agf = XFS_BUF_TO_AGF(buf);
2661 memset(agf, 0, cfg->sectorsize);
2662 if (agno == cfg->agcount - 1)
2663 agsize = cfg->dblocks - (xfs_rfsblock_t)(agno * agsize);
2664 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
2665 agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
2666 agf->agf_seqno = cpu_to_be32(agno);
2667 agf->agf_length = cpu_to_be32(agsize);
2668 agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
2669 agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
2670 agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
2671 agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
2672 pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
2673 pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
2674
2675 if (xfs_sb_version_hasrmapbt(sbp)) {
2676 agf->agf_roots[XFS_BTNUM_RMAPi] = cpu_to_be32(XFS_RMAP_BLOCK(mp));
2677 agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
2678 agf->agf_rmap_blocks = cpu_to_be32(1);
2679 }
2680
2681 if (xfs_sb_version_hasreflink(sbp)) {
2682 agf->agf_refcount_root = cpu_to_be32(libxfs_refc_block(mp));
2683 agf->agf_refcount_level = cpu_to_be32(1);
2684 agf->agf_refcount_blocks = cpu_to_be32(1);
2685 }
2686
2687 agf->agf_flfirst = 0;
2688 agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
2689 agf->agf_flcount = 0;
2690 agblocks = (xfs_agblock_t)(agsize - libxfs_prealloc_blocks(mp));
2691 agf->agf_freeblks = cpu_to_be32(agblocks);
2692 agf->agf_longest = cpu_to_be32(agblocks);
2693
2694 if (xfs_sb_version_hascrc(sbp))
2695 platform_uuid_copy(&agf->agf_uuid, &sbp->sb_uuid);
2696
2697 if (is_log_ag) {
2698 be32_add_cpu(&agf->agf_freeblks, -(int64_t)cfg->logblocks);
2699 agf->agf_longest = cpu_to_be32(agsize -
2700 XFS_FSB_TO_AGBNO(mp, cfg->logstart) - cfg->logblocks);
2701 }
2702 if (libxfs_alloc_min_freelist(mp, pag) > *worst_freelist)
2703 *worst_freelist = libxfs_alloc_min_freelist(mp, pag);
2704 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2705
2706 /*
2707 * AG freelist header block
2708 */
2709 buf = libxfs_getbuf(mp->m_ddev_targp,
2710 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
2711 XFS_FSS_TO_BB(mp, 1));
2712 buf->b_ops = &xfs_agfl_buf_ops;
2713 agfl = XFS_BUF_TO_AGFL(buf);
2714 /* setting to 0xff results in initialisation to NULLAGBLOCK */
2715 memset(agfl, 0xff, cfg->sectorsize);
2716 if (xfs_sb_version_hascrc(sbp)) {
2717 agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
2718 agfl->agfl_seqno = cpu_to_be32(agno);
2719 platform_uuid_copy(&agfl->agfl_uuid, &sbp->sb_uuid);
2720 for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
2721 agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
2722 }
2723
2724 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2725
2726 /*
2727 * AG header block: inodes
2728 */
2729 buf = libxfs_getbuf(mp->m_ddev_targp,
2730 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
2731 XFS_FSS_TO_BB(mp, 1));
2732 agi = XFS_BUF_TO_AGI(buf);
2733 buf->b_ops = &xfs_agi_buf_ops;
2734 memset(agi, 0, cfg->sectorsize);
2735 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
2736 agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
2737 agi->agi_seqno = cpu_to_be32(agno);
2738 agi->agi_length = cpu_to_be32(agsize);
2739 agi->agi_count = 0;
2740 agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
2741 agi->agi_level = cpu_to_be32(1);
2742 if (xfs_sb_version_hasfinobt(sbp)) {
2743 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
2744 agi->agi_free_level = cpu_to_be32(1);
2745 }
2746 agi->agi_freecount = 0;
2747 agi->agi_newino = cpu_to_be32(NULLAGINO);
2748 agi->agi_dirino = cpu_to_be32(NULLAGINO);
2749 if (xfs_sb_version_hascrc(sbp))
2750 platform_uuid_copy(&agi->agi_uuid, &sbp->sb_uuid);
2751 for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
2752 agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
2753 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2754
2755 /*
2756 * BNO btree root block
2757 */
2758 buf = libxfs_getbuf(mp->m_ddev_targp,
2759 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
2760 BTOBB(cfg->blocksize));
2761 buf->b_ops = &xfs_allocbt_buf_ops;
2762 block = XFS_BUF_TO_BLOCK(buf);
2763 memset(block, 0, cfg->blocksize);
2764 libxfs_btree_init_block(mp, buf, XFS_BTNUM_BNO, 0, 1, agno, 0);
2765
2766 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
2767 arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
2768 if (is_log_ag) {
2769 xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, cfg->logstart);
2770
2771 ASSERT(start >= libxfs_prealloc_blocks(mp));
2772 if (start != libxfs_prealloc_blocks(mp)) {
2773 /*
2774 * Modify first record to pad stripe align of log
2775 */
2776 arec->ar_blockcount = cpu_to_be32(start -
2777 libxfs_prealloc_blocks(mp));
2778 nrec = arec + 1;
2779 /*
2780 * Insert second record at start of internal log
2781 * which then gets trimmed.
2782 */
2783 nrec->ar_startblock = cpu_to_be32(
2784 be32_to_cpu(arec->ar_startblock) +
2785 be32_to_cpu(arec->ar_blockcount));
2786 arec = nrec;
2787 be16_add_cpu(&block->bb_numrecs, 1);
2788 }
2789 /*
2790 * Change record start to after the internal log
2791 */
2792 be32_add_cpu(&arec->ar_startblock, cfg->logblocks);
2793 }
2794 /*
2795 * Calculate the record block count and check for the case where
2796 * the log might have consumed all available space in the AG. If
2797 * so, reset the record count to 0 to avoid exposure of an invalid
2798 * record start block.
2799 */
2800 arec->ar_blockcount = cpu_to_be32(agsize -
2801 be32_to_cpu(arec->ar_startblock));
2802 if (!arec->ar_blockcount)
2803 block->bb_numrecs = 0;
2804
2805 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2806
2807 /*
2808 * CNT btree root block
2809 */
2810 buf = libxfs_getbuf(mp->m_ddev_targp,
2811 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
2812 BTOBB(cfg->blocksize));
2813 buf->b_ops = &xfs_allocbt_buf_ops;
2814 block = XFS_BUF_TO_BLOCK(buf);
2815 memset(block, 0, cfg->blocksize);
2816 libxfs_btree_init_block(mp, buf, XFS_BTNUM_CNT, 0, 1, agno, 0);
2817
2818 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
2819 arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
2820 if (is_log_ag) {
2821 xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, cfg->logstart);
2822
2823 ASSERT(start >= libxfs_prealloc_blocks(mp));
2824 if (start != libxfs_prealloc_blocks(mp)) {
2825 arec->ar_blockcount = cpu_to_be32(start -
2826 libxfs_prealloc_blocks(mp));
2827 nrec = arec + 1;
2828 nrec->ar_startblock = cpu_to_be32(
2829 be32_to_cpu(arec->ar_startblock) +
2830 be32_to_cpu(arec->ar_blockcount));
2831 arec = nrec;
2832 be16_add_cpu(&block->bb_numrecs, 1);
2833 }
2834 be32_add_cpu(&arec->ar_startblock, cfg->logblocks);
2835 }
2836 /*
2837 * Calculate the record block count and check for the case where
2838 * the log might have consumed all available space in the AG. If
2839 * so, reset the record count to 0 to avoid exposure of an invalid
2840 * record start block.
2841 */
2842 arec->ar_blockcount = cpu_to_be32(agsize -
2843 be32_to_cpu(arec->ar_startblock));
2844 if (!arec->ar_blockcount)
2845 block->bb_numrecs = 0;
2846
2847 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2848
2849 /*
2850 * refcount btree root block
2851 */
2852 if (xfs_sb_version_hasreflink(sbp)) {
2853 buf = libxfs_getbuf(mp->m_ddev_targp,
2854 XFS_AGB_TO_DADDR(mp, agno, libxfs_refc_block(mp)),
2855 BTOBB(cfg->blocksize));
2856 buf->b_ops = &xfs_refcountbt_buf_ops;
2857
2858 block = XFS_BUF_TO_BLOCK(buf);
2859 memset(block, 0, cfg->blocksize);
2860 libxfs_btree_init_block(mp, buf, XFS_BTNUM_REFC, 0, 0, agno, 0);
2861 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2862 }
2863
2864 /*
2865 * INO btree root block
2866 */
2867 buf = libxfs_getbuf(mp->m_ddev_targp,
2868 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
2869 BTOBB(cfg->blocksize));
2870 buf->b_ops = &xfs_inobt_buf_ops;
2871 block = XFS_BUF_TO_BLOCK(buf);
2872 memset(block, 0, cfg->blocksize);
2873 libxfs_btree_init_block(mp, buf, XFS_BTNUM_INO, 0, 0, agno, 0);
2874 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2875
2876 /*
2877 * Free INO btree root block
2878 */
2879 if (xfs_sb_version_hasfinobt(sbp)) {
2880 buf = libxfs_getbuf(mp->m_ddev_targp,
2881 XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
2882 BTOBB(cfg->blocksize));
2883 buf->b_ops = &xfs_inobt_buf_ops;
2884 block = XFS_BUF_TO_BLOCK(buf);
2885 memset(block, 0, cfg->blocksize);
2886 libxfs_btree_init_block(mp, buf, XFS_BTNUM_FINO, 0, 0, agno, 0);
2887 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2888 }
2889
2890 /* RMAP btree root block */
2891 if (xfs_sb_version_hasrmapbt(sbp)) {
2892 struct xfs_rmap_rec *rrec;
2893
2894 buf = libxfs_getbuf(mp->m_ddev_targp,
2895 XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)),
2896 BTOBB(cfg->blocksize));
2897 buf->b_ops = &xfs_rmapbt_buf_ops;
2898 block = XFS_BUF_TO_BLOCK(buf);
2899 memset(block, 0, cfg->blocksize);
2900
2901 libxfs_btree_init_block(mp, buf, XFS_BTNUM_RMAP, 0, 0, agno, 0);
2902
2903 /*
2904 * mark the AG header regions as static metadata
2905 * The BNO btree block is the first block after the
2906 * headers, so it's location defines the size of region
2907 * the static metadata consumes.
2908 */
2909 rrec = XFS_RMAP_REC_ADDR(block, 1);
2910 rrec->rm_startblock = 0;
2911 rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
2912 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
2913 rrec->rm_offset = 0;
2914 be16_add_cpu(&block->bb_numrecs, 1);
2915
2916 /* account freespace btree root blocks */
2917 rrec = XFS_RMAP_REC_ADDR(block, 2);
2918 rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
2919 rrec->rm_blockcount = cpu_to_be32(2);
2920 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
2921 rrec->rm_offset = 0;
2922 be16_add_cpu(&block->bb_numrecs, 1);
2923
2924 /* account inode btree root blocks */
2925 rrec = XFS_RMAP_REC_ADDR(block, 3);
2926 rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
2927 rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
2928 XFS_IBT_BLOCK(mp));
2929 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
2930 rrec->rm_offset = 0;
2931 be16_add_cpu(&block->bb_numrecs, 1);
2932
2933 /* account for rmap btree root */
2934 rrec = XFS_RMAP_REC_ADDR(block, 4);
2935 rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
2936 rrec->rm_blockcount = cpu_to_be32(1);
2937 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
2938 rrec->rm_offset = 0;
2939 be16_add_cpu(&block->bb_numrecs, 1);
2940
2941 /* account for refcount btree root */
2942 if (xfs_sb_version_hasreflink(sbp)) {
2943 rrec = XFS_RMAP_REC_ADDR(block, 5);
2944 rrec->rm_startblock = cpu_to_be32(libxfs_refc_block(mp));
2945 rrec->rm_blockcount = cpu_to_be32(1);
2946 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
2947 rrec->rm_offset = 0;
2948 be16_add_cpu(&block->bb_numrecs, 1);
2949 }
2950
2951 /* account for the log space */
2952 if (is_log_ag) {
2953 rrec = XFS_RMAP_REC_ADDR(block,
2954 be16_to_cpu(block->bb_numrecs) + 1);
2955 rrec->rm_startblock = cpu_to_be32(
2956 XFS_FSB_TO_AGBNO(mp, cfg->logstart));
2957 rrec->rm_blockcount = cpu_to_be32(cfg->logblocks);
2958 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
2959 rrec->rm_offset = 0;
2960 be16_add_cpu(&block->bb_numrecs, 1);
2961 }
2962
2963 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2964 }
2965
2966 libxfs_perag_put(pag);
2967 }
2968
2969 static void
2970 initialise_ag_freespace(
2971 struct xfs_mount *mp,
2972 xfs_agnumber_t agno,
2973 int worst_freelist)
2974 {
2975 struct xfs_alloc_arg args;
2976 struct xfs_trans *tp;
2977 struct xfs_trans_res tres = {0};
2978 int c;
2979
2980 c = libxfs_trans_alloc(mp, &tres, worst_freelist, 0, 0, &tp);
2981 if (c)
2982 res_failed(c);
2983
2984 memset(&args, 0, sizeof(args));
2985 args.tp = tp;
2986 args.mp = mp;
2987 args.agno = agno;
2988 args.alignment = 1;
2989 args.pag = libxfs_perag_get(mp, agno);
2990
2991 libxfs_alloc_fix_freelist(&args, 0);
2992 libxfs_perag_put(args.pag);
2993 libxfs_trans_commit(tp);
2994 }
2995
2996 /*
2997 * rewrite several secondary superblocks with the root inode number filled out.
2998 * This can help repair recovery from a trashed primary superblock without
2999 * losing the root inode.
3000 */
3001 static void
3002 rewrite_secondary_superblocks(
3003 struct xfs_mount *mp)
3004 {
3005 struct xfs_buf *buf;
3006
3007 /* rewrite the last superblock */
3008 buf = libxfs_readbuf(mp->m_dev,
3009 XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount - 1,
3010 XFS_SB_DADDR),
3011 XFS_FSS_TO_BB(mp, 1),
3012 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3013 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
3014 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3015
3016 /* and one in the middle for luck if there's enough AGs for that */
3017 if (mp->m_sb.sb_agcount <= 2)
3018 return;
3019
3020 buf = libxfs_readbuf(mp->m_dev,
3021 XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount - 1) / 2,
3022 XFS_SB_DADDR),
3023 XFS_FSS_TO_BB(mp, 1),
3024 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3025 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
3026 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3027 }
3028
3029 int
3030 main(
3031 int argc,
3032 char **argv)
3033 {
3034 uint64_t agcount;
3035 xfs_agnumber_t agno;
3036 uint64_t agsize;
3037 int blocklog;
3038 xfs_buf_t *buf;
3039 int c;
3040 int daflag;
3041 int dasize;
3042 xfs_rfsblock_t dblocks;
3043 char *dfile;
3044 int dirblocklog;
3045 int dirblocksize;
3046 char *dsize;
3047 int dsu;
3048 int dsw;
3049 int dsunit;
3050 int dswidth;
3051 int dsflag;
3052 int force_overwrite;
3053 struct fsxattr fsx;
3054 int imaxpct;
3055 int imflag;
3056 int inodelog;
3057 int inopblock;
3058 int isize;
3059 char *label = NULL;
3060 int laflag;
3061 int lalign;
3062 int ldflag;
3063 int liflag;
3064 xfs_agnumber_t logagno;
3065 xfs_rfsblock_t logblocks;
3066 char *logfile;
3067 int loginternal;
3068 char *logsize;
3069 xfs_fsblock_t logstart;
3070 int lvflag;
3071 int lsflag;
3072 int lsuflag;
3073 int lsunitflag;
3074 int lsectorlog;
3075 int lsectorsize;
3076 int lsu;
3077 int lsunit;
3078 int min_logblocks;
3079 xfs_mount_t *mp;
3080 xfs_mount_t mbuf;
3081 xfs_extlen_t nbmblocks;
3082 int nodsflag;
3083 int dry_run = 0;
3084 int discard = 1;
3085 char *protofile;
3086 char *protostring;
3087 int quiet = 0;
3088 xfs_rfsblock_t rtblocks;
3089 xfs_extlen_t rtextblocks;
3090 xfs_rtblock_t rtextents;
3091 char *rtfile;
3092 char *rtsize;
3093 xfs_sb_t *sbp;
3094 int sectorlog;
3095 uint64_t sector_mask;
3096 uint64_t tmp_agsize;
3097 uuid_t uuid;
3098 int worst_freelist;
3099 libxfs_init_t xi;
3100 struct fs_topology ft;
3101 struct sb_feat_args sb_feat;
3102 /* build time defaults */
3103 struct mkfs_default_params dft = {
3104 .source = "package build definitions",
3105 .sectorsize = XFS_MIN_SECTORSIZE,
3106 .blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG,
3107 .sb_feat = {
3108 .log_version = 2,
3109 .attr_version = 2,
3110 .dir_version = XFS_DFL_DIR_VERSION,
3111 .inode_align = XFS_IFLAG_ALIGN,
3112 .nci = false,
3113 .lazy_sb_counters = true,
3114 .projid16bit = false,
3115 .crcs_enabled = true,
3116 .dirftype = true,
3117 .finobt = true,
3118 .spinodes = false,
3119 .rmapbt = false,
3120 .reflink = false,
3121 .parent_pointers = false,
3122 .nodalign = false,
3123 .nortalign = false,
3124 },
3125 };
3126 struct cli_params cli = {
3127 .xi = &xi,
3128 };
3129 struct mkfs_params cfg = {};
3130
3131 platform_uuid_generate(&cli.uuid);
3132 progname = basename(argv[0]);
3133 setlocale(LC_ALL, "");
3134 bindtextdomain(PACKAGE, LOCALEDIR);
3135 textdomain(PACKAGE);
3136
3137 /*
3138 * TODO: Sourcing defaults from a config file
3139 *
3140 * Before anything else, see if there's a config file with different
3141 * defaults. If a file exists in <package location>, read in the new
3142 * default values and overwrite them in the &dft structure. This way the
3143 * new defaults will apply before we parse the CLI, and the CLI will
3144 * still be able to override them. Emit a message to indicate where the
3145 * defaults being used came from.
3146 */
3147 printf(_("Default configuration sourced from %s\n"), dft.source);
3148
3149 /* copy new defaults into CLI parsing structure */
3150 memcpy(&cli.sb_feat, &dft.sb_feat, sizeof(cli.sb_feat));
3151 memcpy(&cli.fsx, &dft.fsx, sizeof(cli.fsx));
3152
3153 /*
3154 * Initialise cli parameters that can be set to zero to an appropriate
3155 * value so we can tell if they have been set or or changed from the
3156 * default value.
3157 */
3158 cli.loginternal = 1; /* internal by default */
3159
3160 agsize = daflag = dasize = dblocks = 0;
3161 imflag = 0;
3162 liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = 0;
3163 loginternal = 1;
3164 logagno = logblocks = rtblocks = rtextblocks = 0;
3165 imaxpct = inodelog = inopblock = isize = 0;
3166 dfile = logfile = rtfile = NULL;
3167 dsize = logsize = rtsize = protofile = NULL;
3168 dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
3169 dsflag = nodsflag = 0;
3170 force_overwrite = 0;
3171 worst_freelist = 0;
3172 memset(&fsx, 0, sizeof(fsx));
3173
3174 memset(&xi, 0, sizeof(xi));
3175 xi.isdirect = LIBXFS_DIRECT;
3176 xi.isreadonly = LIBXFS_EXCLUSIVELY;
3177
3178 while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
3179 switch (c) {
3180 case 'C':
3181 case 'f':
3182 force_overwrite = 1;
3183 break;
3184 case 'b':
3185 case 'n':
3186 case 's':
3187 parse_subopts(c, optarg, &cli);
3188 break;
3189 case 'd':
3190 parse_subopts(c, optarg, &cli);
3191
3192 /* temp don't break code */
3193 agcount = cli.agcount;
3194 if (cli_opt_set(&dopts, D_AGSIZE)) {
3195 agsize = getnum(cli.agsize, &dopts, D_AGSIZE);
3196 dasize = 1;
3197 }
3198 daflag = cli_opt_set(&dopts, D_AGCOUNT);
3199
3200 dsunit = cli.dsunit;
3201 dswidth = cli.dswidth;
3202 dsw = cli.dsw;
3203 if (cli_opt_set(&dopts, D_SU)) {
3204 dsu = getnum(cli.dsu, &dopts, D_SU);
3205 dsflag = 1;
3206 }
3207 dsflag |= cli_opt_set(&dopts, D_SW) ||
3208 cli_opt_set(&dopts, D_SUNIT) ||
3209 cli_opt_set(&dopts, D_SWIDTH);
3210 nodsflag = cli_opt_set(&dopts, D_NOALIGN);
3211
3212 fsx.fsx_xflags |= cli.fsx.fsx_xflags;
3213 fsx.fsx_projid = cli.fsx.fsx_projid;
3214 fsx.fsx_extsize = cli.fsx.fsx_extsize;
3215 /* end temp don't break code */
3216 break;
3217 case 'i':
3218 parse_subopts(c, optarg, &cli);
3219
3220 /* temp don't break code */
3221 imaxpct = cli.imaxpct;
3222 imflag = cli_opt_set(&iopts, I_MAXPCT);
3223 /* end temp don't break code */
3224 break;
3225 case 'l':
3226 parse_subopts(c, optarg, &cli);
3227
3228 /* temp don't break code */
3229 logagno = cli.logagno;
3230 loginternal = cli.loginternal;
3231 logfile = xi.logname;
3232 logsize = cli.logsize;
3233
3234 lsunit = cli.lsunit;
3235 lsunitflag = cli_opt_set(&lopts, L_SUNIT);
3236 if (cli_opt_set(&lopts, L_SU)) {
3237 lsu = getnum(cli.lsu, &lopts, L_SU);
3238 lsuflag = 1;
3239 }
3240
3241 laflag = cli_opt_set(&lopts, L_AGNUM);
3242 liflag = cli_opt_set(&lopts, L_INTERNAL);
3243 ldflag = cli_opt_set(&lopts, L_NAME) ||
3244 cli_opt_set(&lopts, L_DEV);
3245 lvflag = cli_opt_set(&lopts, L_VERSION);
3246 /* end temp don't break code */
3247 break;
3248 case 'L':
3249 if (strlen(optarg) > sizeof(sbp->sb_fname))
3250 illegal(optarg, "L");
3251 label = optarg;
3252 break;
3253 case 'm':
3254 parse_subopts(c, optarg, &cli);
3255
3256 /* temp don't break code */
3257 platform_uuid_copy(&uuid, &cli.uuid);
3258 /* end temp don't break code */
3259 break;
3260 case 'N':
3261 dry_run = 1;
3262 break;
3263 case 'K':
3264 discard = 0;
3265 break;
3266 case 'p':
3267 if (protofile)
3268 respec('p', NULL, 0);
3269 protofile = optarg;
3270 break;
3271 case 'q':
3272 quiet = 1;
3273 break;
3274 case 'r':
3275 parse_subopts(c, optarg, &cli);
3276
3277 /* temp don't break code */
3278 rtsize = cli.rtsize;
3279 /* end temp don't break code */
3280 break;
3281 break;
3282 case 'V':
3283 printf(_("%s version %s\n"), progname, VERSION);
3284 exit(0);
3285 case '?':
3286 unknown(optopt, "");
3287 }
3288 }
3289 if (argc - optind > 1) {
3290 fprintf(stderr, _("extra arguments\n"));
3291 usage();
3292 } else if (argc - optind == 1) {
3293 dfile = xi.volname = getstr(argv[optind], &dopts, D_NAME);
3294 } else
3295 dfile = xi.dname;
3296
3297 /* temp don't break code */
3298 sb_feat = cli.sb_feat;
3299 /* end temp don't break code */
3300
3301 /*
3302 * Extract as much of the valid config as we can from the CLI input
3303 * before opening the libxfs devices.
3304 */
3305 validate_blocksize(&cfg, &cli, &dft);
3306 validate_sectorsize(&cfg, &cli, &dft, &ft, dfile, dry_run,
3307 force_overwrite);
3308 validate_log_sectorsize(&cfg, &cli, &dft);
3309 validate_sb_features(&cfg, &cli);
3310
3311 /*
3312 * we've now completed basic validation of the features, sector and
3313 * block sizes, so from this point onwards we use the values found in
3314 * the cfg structure for them, not the command line structure.
3315 */
3316 validate_dirblocksize(&cfg, &cli);
3317 validate_inodesize(&cfg, &cli);
3318
3319 /*
3320 * if the device size was specified convert it to a block count
3321 * now we have a valid block size. These will be set to zero if
3322 * nothing was specified, indicating we should use the full device.
3323 */
3324 cfg.dblocks = calc_dev_size(cli.dsize, &cfg, &dopts, D_SIZE, "data");
3325 cfg.logblocks = calc_dev_size(cli.logsize, &cfg, &lopts, L_SIZE, "log");
3326 cfg.rtblocks = calc_dev_size(cli.rtsize, &cfg, &ropts, R_SIZE, "rt");
3327
3328 validate_rtextsize(&cfg, &cli, &ft);
3329
3330 /* temp don't break code */
3331 sectorsize = cfg.sectorsize;
3332 sectorlog = cfg.sectorlog;
3333 blocksize = cfg.blocksize;
3334 blocklog = cfg.blocklog;
3335 lsectorsize = cfg.lsectorsize;
3336 lsectorlog = cfg.lsectorlog;
3337 platform_uuid_copy(&uuid, &cfg.uuid);
3338 sb_feat = cfg.sb_feat;
3339 dirblocksize = cfg.dirblocksize;
3340 dirblocklog = cfg.dirblocklog;
3341 isize = cfg.inodesize;
3342 inodelog = cfg.inodelog;
3343 inopblock = cfg.inopblock;
3344 dblocks = cfg.dblocks;
3345 logblocks = cfg.logblocks;
3346 rtblocks = cfg.rtblocks;
3347 rtextblocks = cfg.rtextblocks;
3348 /* end temp don't break code */
3349
3350
3351 calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize,
3352 &dsunit, &dswidth, &lsunit);
3353
3354 /* If sunit & swidth were manually specified as 0, same as noalign */
3355 if (dsflag && !dsunit && !dswidth)
3356 nodsflag = 1;
3357
3358 xi.setblksize = sectorsize;
3359
3360 /*
3361 * Initialize. This will open the log and rt devices as well.
3362 */
3363 if (!libxfs_init(&xi))
3364 usage();
3365 if (!xi.ddev) {
3366 fprintf(stderr, _("no device name given in argument list\n"));
3367 usage();
3368 }
3369
3370 /*
3371 * Ok, Linux only has a 1024-byte resolution on device _size_,
3372 * and the sizes below are in basic 512-byte blocks,
3373 * so if we have (size % 2), on any partition, we can't get
3374 * to the last 512 bytes. The same issue exists for larger
3375 * sector sizes - we cannot write past the last sector.
3376 *
3377 * So, we reduce the size (in basic blocks) to a perfect
3378 * multiple of the sector size, or 1024, whichever is larger.
3379 */
3380
3381 sector_mask = (uint64_t)-1 << (MAX(sectorlog, 10) - BBSHIFT);
3382 xi.dsize &= sector_mask;
3383 xi.rtsize &= sector_mask;
3384 xi.logBBsize &= (uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
3385
3386
3387 /* don't do discards on print-only runs or on files */
3388 if (discard && !dry_run) {
3389 if (!xi.disfile)
3390 discard_blocks(xi.ddev, xi.dsize);
3391 if (xi.rtdev && !xi.risfile)
3392 discard_blocks(xi.rtdev, xi.rtsize);
3393 if (xi.logdev && xi.logdev != xi.ddev && !xi.lisfile)
3394 discard_blocks(xi.logdev, xi.logBBsize);
3395 }
3396
3397 if (!liflag && !ldflag)
3398 loginternal = xi.logdev == 0;
3399 if (xi.logname)
3400 logfile = xi.logname;
3401 else if (loginternal)
3402 logfile = _("internal log");
3403 else if (xi.volname && xi.logdev)
3404 logfile = _("volume log");
3405 else if (!ldflag) {
3406 fprintf(stderr, _("no log subvolume or internal log\n"));
3407 usage();
3408 }
3409 if (xi.rtname)
3410 rtfile = xi.rtname;
3411 else
3412 if (xi.volname && xi.rtdev)
3413 rtfile = _("volume rt");
3414 else if (!xi.rtdev)
3415 rtfile = _("none");
3416 if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize, blocklog)) {
3417 fprintf(stderr,
3418 _("size %s specified for data subvolume is too large, "
3419 "maximum is %lld blocks\n"),
3420 dsize, (long long)DTOBT(xi.dsize, blocklog));
3421 usage();
3422 } else if (!dsize && xi.dsize > 0)
3423 dblocks = DTOBT(xi.dsize, blocklog);
3424 else if (!dsize) {
3425 fprintf(stderr, _("can't get size of data subvolume\n"));
3426 usage();
3427 }
3428 if (dblocks < XFS_MIN_DATA_BLOCKS) {
3429 fprintf(stderr,
3430 _("size %lld of data subvolume is too small, minimum %d blocks\n"),
3431 (long long)dblocks, XFS_MIN_DATA_BLOCKS);
3432 usage();
3433 }
3434
3435 if (loginternal && xi.logdev) {
3436 fprintf(stderr,
3437 _("can't have both external and internal logs\n"));
3438 usage();
3439 } else if (loginternal && sectorsize != lsectorsize) {
3440 fprintf(stderr,
3441 _("data and log sector sizes must be equal for internal logs\n"));
3442 usage();
3443 }
3444
3445 if (xi.dbsize > sectorsize) {
3446 fprintf(stderr, _(
3447 "Warning: the data subvolume sector size %u is less than the sector size \n\
3448 reported by the device (%u).\n"),
3449 sectorsize, xi.dbsize);
3450 }
3451 if (!loginternal && xi.lbsize > lsectorsize) {
3452 fprintf(stderr, _(
3453 "Warning: the log subvolume sector size %u is less than the sector size\n\
3454 reported by the device (%u).\n"),
3455 lsectorsize, xi.lbsize);
3456 }
3457 if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
3458 fprintf(stderr, _(
3459 "Warning: the realtime subvolume sector size %u is less than the sector size\n\
3460 reported by the device (%u).\n"),
3461 sectorsize, xi.rtbsize);
3462 }
3463
3464 if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize, blocklog)) {
3465 fprintf(stderr,
3466 _("size %s specified for rt subvolume is too large, "
3467 "maximum is %lld blocks\n"),
3468 rtsize, (long long)DTOBT(xi.rtsize, blocklog));
3469 usage();
3470 } else if (!rtsize && xi.rtsize > 0)
3471 rtblocks = DTOBT(xi.rtsize, blocklog);
3472 else if (rtsize && !xi.rtdev) {
3473 fprintf(stderr,
3474 _("size specified for non-existent rt subvolume\n"));
3475 usage();
3476 }
3477 if (xi.rtdev) {
3478 rtextents = rtblocks / rtextblocks;
3479 nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize);
3480 } else {
3481 rtextents = rtblocks = 0;
3482 nbmblocks = 0;
3483 }
3484
3485 if (!nodsflag) {
3486 if (dsunit) {
3487 if (ft.dsunit && ft.dsunit != dsunit) {
3488 fprintf(stderr,
3489 _("%s: Specified data stripe unit %d "
3490 "is not the same as the volume stripe "
3491 "unit %d\n"),
3492 progname, dsunit, ft.dsunit);
3493 }
3494 if (ft.dswidth && ft.dswidth != dswidth) {
3495 fprintf(stderr,
3496 _("%s: Specified data stripe width %d "
3497 "is not the same as the volume stripe "
3498 "width %d\n"),
3499 progname, dswidth, ft.dswidth);
3500 }
3501 } else {
3502 dsunit = ft.dsunit;
3503 dswidth = ft.dswidth;
3504 nodsflag = 1;
3505 }
3506 } /* else dsunit & dswidth can't be set if nodsflag is set */
3507
3508 if (dasize) { /* User-specified AG size */
3509 /*
3510 * Check specified agsize is a multiple of blocksize.
3511 */
3512 if (agsize % blocksize) {
3513 fprintf(stderr,
3514 _("agsize (%lld) not a multiple of fs blk size (%d)\n"),
3515 (long long)agsize, blocksize);
3516 usage();
3517 }
3518 agsize /= blocksize;
3519 agcount = dblocks / agsize + (dblocks % agsize != 0);
3520
3521 } else if (daflag) { /* User-specified AG count */
3522 agsize = dblocks / agcount + (dblocks % agcount != 0);
3523 } else {
3524 calc_default_ag_geometry(blocklog, dblocks,
3525 dsunit | dswidth, &agsize, &agcount);
3526 }
3527
3528 /*
3529 * If dsunit is a multiple of fs blocksize, then check that is a
3530 * multiple of the agsize too
3531 */
3532 if (dsunit && !(BBTOB(dsunit) % blocksize) &&
3533 dswidth && !(BBTOB(dswidth) % blocksize)) {
3534
3535 /* convert from 512 byte blocks to fs blocksize */
3536 dsunit = DTOBT(dsunit, blocklog);
3537 dswidth = DTOBT(dswidth, blocklog);
3538
3539 /*
3540 * agsize is not a multiple of dsunit
3541 */
3542 if ((agsize % dsunit) != 0) {
3543 /*
3544 * Round up to stripe unit boundary. Also make sure
3545 * that agsize is still larger than
3546 * XFS_AG_MIN_BLOCKS(blocklog)
3547 */
3548 tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit;
3549 /*
3550 * Round down to stripe unit boundary if rounding up
3551 * created an AG size that is larger than the AG max.
3552 */
3553 if (tmp_agsize > XFS_AG_MAX_BLOCKS(blocklog))
3554 tmp_agsize = ((agsize) / dsunit) * dsunit;
3555
3556 if ((tmp_agsize >= XFS_AG_MIN_BLOCKS(blocklog)) &&
3557 (tmp_agsize <= XFS_AG_MAX_BLOCKS(blocklog))) {
3558 agsize = tmp_agsize;
3559 if (!daflag)
3560 agcount = dblocks/agsize +
3561 (dblocks % agsize != 0);
3562 if (dasize)
3563 fprintf(stderr,
3564 _("agsize rounded to %lld, swidth = %d\n"),
3565 (long long)agsize, dswidth);
3566 } else {
3567 if (nodsflag) {
3568 dsunit = dswidth = 0;
3569 } else {
3570 /*
3571 * agsize is out of bounds, this will
3572 * print nice details & exit.
3573 */
3574 validate_ag_geometry(blocklog, dblocks,
3575 agsize, agcount);
3576 exit(1);
3577 }
3578 }
3579 }
3580 if (dswidth && ((agsize % dswidth) == 0)
3581 && (dswidth != dsunit)
3582 && (agcount > 1)) {
3583 /* This is a non-optimal configuration because all AGs
3584 * start on the same disk in the stripe. Changing
3585 * the AG size by one sunit will guarantee that this
3586 * does not happen.
3587 */
3588 tmp_agsize = agsize - dsunit;
3589 if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
3590 tmp_agsize = agsize + dsunit;
3591 if (dblocks < agsize) {
3592 /* oh well, nothing to do */
3593 tmp_agsize = agsize;
3594 }
3595 }
3596 if (daflag || dasize) {
3597 fprintf(stderr, _(
3598 "Warning: AG size is a multiple of stripe width. This can cause performance\n\
3599 problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
3600 an AG size that is one stripe unit smaller, for example %llu.\n"),
3601 (unsigned long long)tmp_agsize);
3602 } else {
3603 agsize = tmp_agsize;
3604 agcount = dblocks/agsize + (dblocks % agsize != 0);
3605 /*
3606 * If the last AG is too small, reduce the
3607 * filesystem size and drop the blocks.
3608 */
3609 if ( dblocks % agsize != 0 &&
3610 (dblocks % agsize <
3611 XFS_AG_MIN_BLOCKS(blocklog))) {
3612 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
3613 agcount--;
3614 ASSERT(agcount != 0);
3615 }
3616 }
3617 }
3618 } else {
3619 if (nodsflag)
3620 dsunit = dswidth = 0;
3621 else {
3622 fprintf(stderr,
3623 _("%s: Stripe unit(%d) or stripe width(%d) is "
3624 "not a multiple of the block size(%d)\n"),
3625 progname, BBTOB(dsunit), BBTOB(dswidth),
3626 blocksize);
3627 exit(1);
3628 }
3629 }
3630
3631 /*
3632 * If the last AG is too small, reduce the filesystem size
3633 * and drop the blocks.
3634 */
3635 if ( dblocks % agsize != 0 &&
3636 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
3637 ASSERT(!daflag);
3638 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
3639 agcount--;
3640 ASSERT(agcount != 0);
3641 }
3642
3643 validate_ag_geometry(blocklog, dblocks, agsize, agcount);
3644
3645 if (!imflag)
3646 imaxpct = calc_default_imaxpct(blocklog, dblocks);
3647
3648 /*
3649 * check that log sunit is modulo fsblksize or default it to dsunit.
3650 */
3651
3652 if (lsunit) {
3653 /* convert from 512 byte blocks to fs blocks */
3654 lsunit = DTOBT(lsunit, blocklog);
3655 } else if (sb_feat.log_version == 2 && loginternal && dsunit) {
3656 /* lsunit and dsunit now in fs blocks */
3657 lsunit = dsunit;
3658 }
3659
3660 if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
3661 /* Warn only if specified on commandline */
3662 if (lsuflag || lsunitflag) {
3663 fprintf(stderr,
3664 _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
3665 (lsunit * blocksize));
3666 fprintf(stderr,
3667 _("log stripe unit adjusted to 32KiB\n"));
3668 }
3669 lsunit = (32 * 1024) >> blocklog;
3670 }
3671
3672 min_logblocks = max_trans_res(agsize,
3673 sb_feat.crcs_enabled, sb_feat.dir_version,
3674 sectorlog, blocklog, inodelog, dirblocklog,
3675 sb_feat.log_version, lsunit, sb_feat.finobt,
3676 sb_feat.rmapbt, sb_feat.reflink,
3677 sb_feat.inode_align);
3678 ASSERT(min_logblocks);
3679 min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
3680 if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
3681 min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
3682 if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize, blocklog)) {
3683 fprintf(stderr,
3684 _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
3685 logsize, (long long)DTOBT(xi.logBBsize, blocklog));
3686 usage();
3687 } else if (!logsize && xi.logBBsize > 0) {
3688 logblocks = DTOBT(xi.logBBsize, blocklog);
3689 } else if (logsize && !xi.logdev && !loginternal) {
3690 fprintf(stderr,
3691 _("size specified for non-existent log subvolume\n"));
3692 usage();
3693 } else if (loginternal && logsize && logblocks >= dblocks) {
3694 fprintf(stderr, _("size %lld too large for internal log\n"),
3695 (long long)logblocks);
3696 usage();
3697 } else if (!loginternal && !xi.logdev) {
3698 logblocks = 0;
3699 } else if (loginternal && !logsize) {
3700
3701 if (dblocks < GIGABYTES(1, blocklog)) {
3702 /* tiny filesystems get minimum sized logs. */
3703 logblocks = min_logblocks;
3704 } else if (dblocks < GIGABYTES(16, blocklog)) {
3705
3706 /*
3707 * For small filesystems, we want to use the
3708 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
3709 * at all possible, ramping up to 128MB at 256GB.
3710 */
3711 logblocks = MIN(XFS_MIN_LOG_BYTES >> blocklog,
3712 min_logblocks * XFS_DFL_LOG_FACTOR);
3713 } else {
3714 /*
3715 * With a 2GB max log size, default to maximum size
3716 * at 4TB. This keeps the same ratio from the older
3717 * max log size of 128M at 256GB fs size. IOWs,
3718 * the ratio of fs size to log size is 2048:1.
3719 */
3720 logblocks = (dblocks << blocklog) / 2048;
3721 logblocks = logblocks >> blocklog;
3722 }
3723
3724 /* Ensure the chosen size meets minimum log size requirements */
3725 logblocks = MAX(min_logblocks, logblocks);
3726
3727 /* make sure the log fits wholly within an AG */
3728 if (logblocks >= agsize)
3729 logblocks = min_logblocks;
3730
3731 /* and now clamp the size to the maximum supported size */
3732 logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
3733 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES)
3734 logblocks = XFS_MAX_LOG_BYTES >> blocklog;
3735
3736 }
3737 validate_log_size(logblocks, blocklog, min_logblocks);
3738
3739 protostring = setup_proto(protofile);
3740 mp = &mbuf;
3741 sbp = &mp->m_sb;
3742 memset(mp, 0, sizeof(xfs_mount_t));
3743 sbp->sb_blocklog = (uint8_t)blocklog;
3744 sbp->sb_sectlog = (uint8_t)sectorlog;
3745 sbp->sb_agblklog = (uint8_t)log2_roundup((unsigned int)agsize);
3746 sbp->sb_agblocks = (xfs_agblock_t)agsize;
3747 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
3748 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
3749
3750 /*
3751 * sb_versionnum, finobt and rmapbt flags must be set before we use
3752 * libxfs_prealloc_blocks().
3753 */
3754 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
3755
3756
3757 if (loginternal) {
3758 /*
3759 * Readjust the log size to fit within an AG if it was sized
3760 * automatically.
3761 */
3762 if (!logsize) {
3763 logblocks = MIN(logblocks,
3764 libxfs_alloc_ag_max_usable(mp));
3765
3766 /* revalidate the log size is valid if we changed it */
3767 validate_log_size(logblocks, blocklog, min_logblocks);
3768 }
3769 if (logblocks > agsize - libxfs_prealloc_blocks(mp)) {
3770 fprintf(stderr,
3771 _("internal log size %lld too large, must fit in allocation group\n"),
3772 (long long)logblocks);
3773 usage();
3774 }
3775
3776 if (laflag) {
3777 if (logagno >= agcount) {
3778 fprintf(stderr,
3779 _("log ag number %d too large, must be less than %lld\n"),
3780 logagno, (long long)agcount);
3781 usage();
3782 }
3783 } else
3784 logagno = (xfs_agnumber_t)(agcount / 2);
3785
3786 logstart = XFS_AGB_TO_FSB(mp, logagno, libxfs_prealloc_blocks(mp));
3787 /*
3788 * Align the logstart at stripe unit boundary.
3789 */
3790 if (lsunit) {
3791 logstart = fixup_internal_log_stripe(mp,
3792 lsflag, logstart, agsize, lsunit,
3793 &logblocks, blocklog, &lalign);
3794 } else if (dsunit) {
3795 logstart = fixup_internal_log_stripe(mp,
3796 lsflag, logstart, agsize, dsunit,
3797 &logblocks, blocklog, &lalign);
3798 }
3799 } else {
3800 logstart = 0;
3801 if (lsunit)
3802 fixup_log_stripe_unit(lsflag, lsunit,
3803 &logblocks, blocklog);
3804 }
3805 validate_log_size(logblocks, blocklog, min_logblocks);
3806
3807 /* Temp support code to set up mkfs cfg parameters */
3808 cfg.blocksize = blocksize;
3809 cfg.blocklog = blocklog;
3810 cfg.sectorsize = sectorsize;
3811 cfg.sectorlog = sectorlog;
3812 cfg.lsectorsize = lsectorsize;
3813 cfg.lsectorlog = lsectorlog;
3814 cfg.dirblocksize = dirblocksize;
3815 cfg.dirblocklog = dirblocklog;
3816 cfg.inodesize = isize;
3817 cfg.inodelog = inodelog;
3818 cfg.inopblock = inopblock;
3819
3820 cfg.dblocks = dblocks;
3821 cfg.logblocks = logblocks;
3822 cfg.rtblocks = rtblocks;
3823 cfg.rtextblocks = rtextblocks;
3824 cfg.rtextents = rtextents;
3825 cfg.rtbmblocks = nbmblocks;
3826 cfg.dsunit = dsunit;
3827 cfg.dswidth = dswidth;
3828 cfg.lsunit = lsunit;
3829 cfg.agsize = agsize;
3830 cfg.agcount = agcount;
3831 cfg.imaxpct = imaxpct;
3832 cfg.loginternal = loginternal;
3833 cfg.logstart = logstart;
3834 cfg.logagno = logagno;
3835 cfg.label = label;
3836 platform_uuid_copy(&cfg.uuid, &uuid);
3837 memcpy(&cfg.sb_feat, &sb_feat, sizeof(sb_feat));
3838 /* end temp support code */
3839
3840 if (!quiet || dry_run) {
3841 print_mkfs_cfg(&cfg, dfile, logfile, rtfile);
3842 if (dry_run)
3843 exit(0);
3844 }
3845
3846 /*
3847 * Finish setting up the superblock state ready for formatting.
3848 */
3849 setup_superblock(&cfg, mp, sbp);
3850
3851 /*
3852 * we need the libxfs buffer cache from here on in.
3853 */
3854 libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
3855
3856 /*
3857 * Before we mount the filesystem we need to make sure the devices have
3858 * enough of the filesystem structure on them that allows libxfs to
3859 * mount.
3860 */
3861 prepare_devices(&cfg, &xi, mp, sbp, force_overwrite);
3862 mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
3863 if (mp == NULL) {
3864 fprintf(stderr, _("%s: filesystem failed to initialize\n"),
3865 progname);
3866 exit(1);
3867 }
3868
3869 /*
3870 * Initialise all the static on disk metadata.
3871 */
3872 for (agno = 0; agno < cfg.agcount; agno++)
3873 initialise_ag_headers(&cfg, mp, sbp, agno, &worst_freelist);
3874
3875 /*
3876 * Initialise the freespace freelists (i.e. AGFLs) in each AG.
3877 */
3878 for (agno = 0; agno < cfg.agcount; agno++)
3879 initialise_ag_freespace(mp, agno, worst_freelist);
3880
3881 /*
3882 * Allocate the root inode and anything else in the proto file.
3883 */
3884 parse_proto(mp, &fsx, &protostring);
3885
3886 /*
3887 * Protect ourselves against possible stupidity
3888 */
3889 if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
3890 fprintf(stderr,
3891 _("%s: root inode created in AG %u, not AG 0\n"),
3892 progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
3893 exit(1);
3894 }
3895
3896 /*
3897 * Re-write multiple secondary superblocks with rootinode field set
3898 */
3899 if (mp->m_sb.sb_agcount > 1)
3900 rewrite_secondary_superblocks(mp);
3901
3902 /*
3903 * Dump all inodes and buffers before marking us all done.
3904 * Need to drop references to inodes we still hold, first.
3905 */
3906 libxfs_rtmount_destroy(mp);
3907 libxfs_bcache_purge();
3908
3909 /*
3910 * Mark the filesystem ok.
3911 */
3912 buf = libxfs_getsb(mp, LIBXFS_EXIT_ON_FAILURE);
3913 (XFS_BUF_TO_SBP(buf))->sb_inprogress = 0;
3914 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3915
3916 libxfs_umount(mp);
3917 if (xi.rtdev)
3918 libxfs_device_close(xi.rtdev);
3919 if (xi.logdev && xi.logdev != xi.ddev)
3920 libxfs_device_close(xi.logdev);
3921 libxfs_device_close(xi.ddev);
3922
3923 return 0;
3924 }
3925
3926 static void
3927 conflict(
3928 char opt,
3929 const char *tab[],
3930 int oldidx,
3931 int newidx)
3932 {
3933 fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
3934 opt, tab[oldidx], opt, tab[newidx]);
3935 usage();
3936 }
3937
3938
3939 static void
3940 illegal(
3941 const char *value,
3942 const char *opt)
3943 {
3944 fprintf(stderr, _("Illegal value %s for -%s option\n"), value, opt);
3945 usage();
3946 }
3947
3948 static int
3949 ispow2(
3950 unsigned int i)
3951 {
3952 return (i & (i - 1)) == 0;
3953 }
3954
3955 static void __attribute__((noreturn))
3956 reqval(
3957 char opt,
3958 const char *tab[],
3959 int idx)
3960 {
3961 fprintf(stderr, _("-%c %s option requires a value\n"), opt, tab[idx]);
3962 usage();
3963 }
3964
3965 static void
3966 respec(
3967 char opt,
3968 const char *tab[],
3969 int idx)
3970 {
3971 fprintf(stderr, "-%c ", opt);
3972 if (tab)
3973 fprintf(stderr, "%s ", tab[idx]);
3974 fprintf(stderr, _("option respecified\n"));
3975 usage();
3976 }
3977
3978 static void
3979 unknown(
3980 char opt,
3981 char *s)
3982 {
3983 fprintf(stderr, _("unknown option -%c %s\n"), opt, s);
3984 usage();
3985 }
3986
3987 long long
3988 cvtnum(
3989 unsigned int blksize,
3990 unsigned int sectsize,
3991 const char *s)
3992 {
3993 long long i;
3994 char *sp;
3995 int c;
3996
3997 i = strtoll(s, &sp, 0);
3998 if (i == 0 && sp == s)
3999 return -1LL;
4000 if (*sp == '\0')
4001 return i;
4002
4003 if (sp[1] != '\0')
4004 return -1LL;
4005
4006 if (*sp == 'b') {
4007 if (!blksize) {
4008 fprintf(stderr,
4009 _("Blocksize must be provided prior to using 'b' suffix.\n"));
4010 usage();
4011 } else {
4012 return i * blksize;
4013 }
4014 }
4015 if (*sp == 's') {
4016 if (!sectsize) {
4017 fprintf(stderr,
4018 _("Sectorsize must be specified prior to using 's' suffix.\n"));
4019 usage();
4020 } else {
4021 return i * sectsize;
4022 }
4023 }
4024
4025 c = tolower(*sp);
4026 switch (c) {
4027 case 'e':
4028 i *= 1024LL;
4029 /* fall through */
4030 case 'p':
4031 i *= 1024LL;
4032 /* fall through */
4033 case 't':
4034 i *= 1024LL;
4035 /* fall through */
4036 case 'g':
4037 i *= 1024LL;
4038 /* fall through */
4039 case 'm':
4040 i *= 1024LL;
4041 /* fall through */
4042 case 'k':
4043 return i * 1024LL;
4044 default:
4045 break;
4046 }
4047 return -1LL;
4048 }
4049
4050 static void __attribute__((noreturn))
4051 usage( void )
4052 {
4053 fprintf(stderr, _("Usage: %s\n\
4054 /* blocksize */ [-b log=n|size=num]\n\
4055 /* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n\
4056 /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
4057 (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
4058 sectlog=n|sectsize=num\n\
4059 /* force overwrite */ [-f]\n\
4060 /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
4061 projid32bit=0|1,sparse=0|1]\n\
4062 /* no discard */ [-K]\n\
4063 /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
4064 sunit=value|su=num,sectlog=n|sectsize=num,\n\
4065 lazy-count=0|1]\n\
4066 /* label */ [-L label (maximum 12 characters)]\n\
4067 /* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\
4068 /* no-op info only */ [-N]\n\
4069 /* prototype file */ [-p fname]\n\
4070 /* quiet */ [-q]\n\
4071 /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\
4072 /* sectorsize */ [-s log=n|size=num]\n\
4073 /* version */ [-V]\n\
4074 devicename\n\
4075 <devicename> is required unless -d name=xxx is given.\n\
4076 <num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\
4077 xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\
4078 <value> is xxx (512 byte blocks).\n"),
4079 progname);
4080 exit(1);
4081 }