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