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