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