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