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