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