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