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