]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfs/xfs_mkfs.c
libxfs: fix xfs_trans_alloc reservation abuse
[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 bool discard)
2394 {
2395 uint64_t sector_mask;
2396
2397 /*
2398 * Initialize. This will open the log and rt devices as well.
2399 */
2400 xi->setblksize = cfg->sectorsize;
2401 if (!libxfs_init(xi))
2402 usage();
2403 if (!xi->ddev) {
2404 fprintf(stderr, _("no device name given in argument list\n"));
2405 usage();
2406 }
2407
2408 /*
2409 * Ok, Linux only has a 1024-byte resolution on device _size_,
2410 * and the sizes below are in basic 512-byte blocks,
2411 * so if we have (size % 2), on any partition, we can't get
2412 * to the last 512 bytes. The same issue exists for larger
2413 * sector sizes - we cannot write past the last sector.
2414 *
2415 * So, we reduce the size (in basic blocks) to a perfect
2416 * multiple of the sector size, or 1024, whichever is larger.
2417 */
2418 sector_mask = (uint64_t)-1 << (max(cfg->sectorlog, 10) - BBSHIFT);
2419 xi->dsize &= sector_mask;
2420 xi->rtsize &= sector_mask;
2421 xi->logBBsize &= (uint64_t)-1 << (max(cfg->lsectorlog, 10) - BBSHIFT);
2422
2423
2424 if (!discard)
2425 return;
2426
2427 if (!xi->disfile)
2428 discard_blocks(xi->ddev, xi->dsize);
2429 if (xi->rtdev && !xi->risfile)
2430 discard_blocks(xi->rtdev, xi->rtsize);
2431 if (xi->logdev && xi->logdev != xi->ddev && !xi->lisfile)
2432 discard_blocks(xi->logdev, xi->logBBsize);
2433 }
2434
2435 static void
2436 validate_datadev(
2437 struct mkfs_params *cfg,
2438 struct cli_params *cli)
2439 {
2440 struct libxfs_xinit *xi = cli->xi;
2441
2442 if (!xi->dsize) {
2443 /*
2444 * if the device is a file, we can't validate the size here.
2445 * Instead, the file will be truncated to the correct length
2446 * later on. if it's not a file, we've got a dud device.
2447 */
2448 if (!xi->disfile) {
2449 fprintf(stderr, _("can't get size of data subvolume\n"));
2450 usage();
2451 }
2452 ASSERT(cfg->dblocks);
2453 } else if (cfg->dblocks) {
2454 /* check the size fits into the underlying device */
2455 if (cfg->dblocks > DTOBT(xi->dsize, cfg->blocklog)) {
2456 fprintf(stderr,
2457 _("size %s specified for data subvolume is too large, maximum is %lld blocks\n"),
2458 cli->dsize,
2459 (long long)DTOBT(xi->dsize, cfg->blocklog));
2460 usage();
2461 }
2462 } else {
2463 /* no user size, so use the full block device */
2464 cfg->dblocks = DTOBT(xi->dsize, cfg->blocklog);
2465 }
2466
2467 if (cfg->dblocks < XFS_MIN_DATA_BLOCKS) {
2468 fprintf(stderr,
2469 _("size %lld of data subvolume is too small, minimum %d blocks\n"),
2470 (long long)cfg->dblocks, XFS_MIN_DATA_BLOCKS);
2471 usage();
2472 }
2473
2474 if (xi->dbsize > cfg->sectorsize) {
2475 fprintf(stderr, _(
2476 "Warning: the data subvolume sector size %u is less than the sector size \n\
2477 reported by the device (%u).\n"),
2478 cfg->sectorsize, xi->dbsize);
2479 }
2480 }
2481
2482 /*
2483 * This is more complex than it needs to be because we still support volume
2484 * based external logs. They are only discovered *after* the devices have been
2485 * opened, hence the crazy "is this really an internal log" checks here.
2486 */
2487 static void
2488 validate_logdev(
2489 struct mkfs_params *cfg,
2490 struct cli_params *cli,
2491 char **devname)
2492 {
2493 struct libxfs_xinit *xi = cli->xi;
2494
2495 *devname = NULL;
2496
2497 /* check for volume log first */
2498 if (cli->loginternal && xi->volname && xi->logdev) {
2499 *devname = _("volume log");
2500 cfg->loginternal = false;
2501 } else
2502 cfg->loginternal = cli->loginternal;
2503
2504 /* now run device checks */
2505 if (cfg->loginternal) {
2506 if (xi->logdev) {
2507 fprintf(stderr,
2508 _("can't have both external and internal logs\n"));
2509 usage();
2510 }
2511
2512 /*
2513 * if no sector size has been specified on the command line,
2514 * use what has been configured and validated for the data
2515 * device.
2516 */
2517 if (!cli->lsectorsize) {
2518 cfg->lsectorsize = cfg->sectorsize;
2519 cfg->lsectorlog = cfg->sectorlog;
2520 }
2521
2522 if (cfg->sectorsize != cfg->lsectorsize) {
2523 fprintf(stderr,
2524 _("data and log sector sizes must be equal for internal logs\n"));
2525 usage();
2526 }
2527 if (cli->logsize && cfg->logblocks >= cfg->dblocks) {
2528 fprintf(stderr,
2529 _("log size %lld too large for internal log\n"),
2530 (long long)cfg->logblocks);
2531 usage();
2532 }
2533 *devname = _("internal log");
2534 return;
2535 }
2536
2537 /* External/log subvolume checks */
2538 if (xi->logname)
2539 *devname = xi->logname;
2540 if (!*devname || !xi->logdev) {
2541 fprintf(stderr, _("no log subvolume or external log.\n"));
2542 usage();
2543 }
2544
2545 if (!cfg->logblocks) {
2546 if (xi->logBBsize == 0) {
2547 fprintf(stderr,
2548 _("unable to get size of the log subvolume.\n"));
2549 usage();
2550 }
2551 cfg->logblocks = DTOBT(xi->logBBsize, cfg->blocklog);
2552 } else if (cfg->logblocks > DTOBT(xi->logBBsize, cfg->blocklog)) {
2553 fprintf(stderr,
2554 _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
2555 cli->logsize,
2556 (long long)DTOBT(xi->logBBsize, cfg->blocklog));
2557 usage();
2558 }
2559
2560 if (xi->lbsize > cfg->lsectorsize) {
2561 fprintf(stderr, _(
2562 "Warning: the log subvolume sector size %u is less than the sector size\n\
2563 reported by the device (%u).\n"),
2564 cfg->lsectorsize, xi->lbsize);
2565 }
2566 }
2567
2568 static void
2569 validate_rtdev(
2570 struct mkfs_params *cfg,
2571 struct cli_params *cli,
2572 char **devname)
2573 {
2574 struct libxfs_xinit *xi = cli->xi;
2575
2576 *devname = NULL;
2577
2578 if (!xi->rtdev) {
2579 if (cli->rtsize) {
2580 fprintf(stderr,
2581 _("size specified for non-existent rt subvolume\n"));
2582 usage();
2583 }
2584
2585 *devname = _("none");
2586 cfg->rtblocks = 0;
2587 cfg->rtextents = 0;
2588 cfg->rtbmblocks = 0;
2589 return;
2590 }
2591 if (!xi->rtsize) {
2592 fprintf(stderr, _("Invalid zero length rt subvolume found\n"));
2593 usage();
2594 }
2595
2596 /* volume rtdev */
2597 if (xi->volname)
2598 *devname = _("volume rt");
2599 else
2600 *devname = xi->rtname;
2601
2602 if (cli->rtsize) {
2603 if (cfg->rtblocks > DTOBT(xi->rtsize, cfg->blocklog)) {
2604 fprintf(stderr,
2605 _("size %s specified for rt subvolume is too large, maxi->um is %lld blocks\n"),
2606 cli->rtsize,
2607 (long long)DTOBT(xi->rtsize, cfg->blocklog));
2608 usage();
2609 }
2610 if (xi->rtbsize > cfg->sectorsize) {
2611 fprintf(stderr, _(
2612 "Warning: the realtime subvolume sector size %u is less than the sector size\n\
2613 reported by the device (%u).\n"),
2614 cfg->sectorsize, xi->rtbsize);
2615 }
2616 } else {
2617 /* grab volume size */
2618 cfg->rtblocks = DTOBT(xi->rtsize, cfg->blocklog);
2619 }
2620
2621 cfg->rtextents = cfg->rtblocks / cfg->rtextblocks;
2622 cfg->rtbmblocks = (xfs_extlen_t)howmany(cfg->rtextents,
2623 NBBY * cfg->blocksize);
2624 }
2625
2626 static void
2627 calculate_initial_ag_geometry(
2628 struct mkfs_params *cfg,
2629 struct cli_params *cli)
2630 {
2631 if (cli->agsize) { /* User-specified AG size */
2632 cfg->agsize = getnum(cli->agsize, &dopts, D_AGSIZE);
2633
2634 /*
2635 * Check specified agsize is a multiple of blocksize.
2636 */
2637 if (cfg->agsize % cfg->blocksize) {
2638 fprintf(stderr,
2639 _("agsize (%s) not a multiple of fs blk size (%d)\n"),
2640 cli->agsize, cfg->blocksize);
2641 usage();
2642 }
2643 cfg->agsize /= cfg->blocksize;
2644 cfg->agcount = cfg->dblocks / cfg->agsize +
2645 (cfg->dblocks % cfg->agsize != 0);
2646
2647 } else if (cli->agcount) { /* User-specified AG count */
2648 cfg->agcount = cli->agcount;
2649 cfg->agsize = cfg->dblocks / cfg->agcount +
2650 (cfg->dblocks % cfg->agcount != 0);
2651 } else {
2652 calc_default_ag_geometry(cfg->blocklog, cfg->dblocks,
2653 cfg->dsunit, &cfg->agsize,
2654 &cfg->agcount);
2655 }
2656 }
2657
2658 /*
2659 * Align the AG size to stripe geometry. If this fails and we are using
2660 * discovered stripe geometry, tell the caller to clear the stripe geometry.
2661 * Otherwise, set the aligned geometry (valid or invalid!) so that the
2662 * validation call will fail and exit.
2663 */
2664 static void
2665 align_ag_geometry(
2666 struct mkfs_params *cfg)
2667 {
2668 uint64_t tmp_agsize;
2669 int dsunit = cfg->dsunit;
2670
2671 if (!dsunit)
2672 goto validate;
2673
2674 /*
2675 * agsize is not a multiple of dsunit
2676 */
2677 if ((cfg->agsize % dsunit) != 0) {
2678 /*
2679 * Round up to stripe unit boundary. Also make sure
2680 * that agsize is still larger than
2681 * XFS_AG_MIN_BLOCKS(blocklog)
2682 */
2683 tmp_agsize = ((cfg->agsize + dsunit - 1) / dsunit) * dsunit;
2684 /*
2685 * Round down to stripe unit boundary if rounding up
2686 * created an AG size that is larger than the AG max.
2687 */
2688 if (tmp_agsize > XFS_AG_MAX_BLOCKS(cfg->blocklog))
2689 tmp_agsize = (cfg->agsize / dsunit) * dsunit;
2690
2691 if (tmp_agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog) &&
2692 tmp_agsize > XFS_AG_MAX_BLOCKS(cfg->blocklog)) {
2693
2694 /*
2695 * If the AG size is invalid and we are using device
2696 * probed stripe alignment, just clear the alignment
2697 * and continue on.
2698 */
2699 if (!cli_opt_set(&dopts, D_SUNIT) &&
2700 !cli_opt_set(&dopts, D_SU)) {
2701 cfg->dsunit = 0;
2702 cfg->dswidth = 0;
2703 goto validate;
2704 }
2705 /*
2706 * set the agsize to the invalid value so the following
2707 * validation of the ag will fail and print a nice error
2708 * and exit.
2709 */
2710 cfg->agsize = tmp_agsize;
2711 goto validate;
2712 }
2713
2714 /* update geometry to be stripe unit aligned */
2715 cfg->agsize = tmp_agsize;
2716 if (!cli_opt_set(&dopts, D_AGCOUNT))
2717 cfg->agcount = cfg->dblocks / cfg->agsize +
2718 (cfg->dblocks % cfg->agsize != 0);
2719 if (cli_opt_set(&dopts, D_AGSIZE))
2720 fprintf(stderr,
2721 _("agsize rounded to %lld, sunit = %d\n"),
2722 (long long)cfg->agsize, dsunit);
2723 }
2724
2725 if ((cfg->agsize % cfg->dswidth) == 0 &&
2726 cfg->dswidth != cfg->dsunit &&
2727 cfg->agcount > 1) {
2728
2729 if (cli_opt_set(&dopts, D_AGCOUNT) ||
2730 cli_opt_set(&dopts, D_AGSIZE)) {
2731 fprintf(stderr, _(
2732 "Warning: AG size is a multiple of stripe width. This can cause performance\n\
2733 problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
2734 an AG size that is one stripe unit smaller or larger, for example %llu.\n"),
2735 (unsigned long long)cfg->agsize - dsunit);
2736 goto validate;
2737 }
2738
2739 /*
2740 * This is a non-optimal configuration because all AGs start on
2741 * the same disk in the stripe. Changing the AG size by one
2742 * sunit will guarantee that this does not happen.
2743 */
2744 tmp_agsize = cfg->agsize - dsunit;
2745 if (tmp_agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog)) {
2746 tmp_agsize = cfg->agsize + dsunit;
2747 if (cfg->dblocks < cfg->agsize) {
2748 /* oh well, nothing to do */
2749 tmp_agsize = cfg->agsize;
2750 }
2751 }
2752
2753 cfg->agsize = tmp_agsize;
2754 cfg->agcount = cfg->dblocks / cfg->agsize +
2755 (cfg->dblocks % cfg->agsize != 0);
2756 }
2757
2758 validate:
2759 /*
2760 * If the last AG is too small, reduce the filesystem size
2761 * and drop the blocks.
2762 */
2763 if (cfg->dblocks % cfg->agsize != 0 &&
2764 (cfg->dblocks % cfg->agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog))) {
2765 ASSERT(!cli_opt_set(&dopts, D_AGCOUNT));
2766 cfg->dblocks = (xfs_rfsblock_t)((cfg->agcount - 1) * cfg->agsize);
2767 cfg->agcount--;
2768 ASSERT(cfg->agcount != 0);
2769 }
2770
2771 validate_ag_geometry(cfg->blocklog, cfg->dblocks,
2772 cfg->agsize, cfg->agcount);
2773 }
2774
2775 static void
2776 calculate_imaxpct(
2777 struct mkfs_params *cfg,
2778 struct cli_params *cli)
2779 {
2780 cfg->imaxpct = cli->imaxpct;
2781 if (cfg->imaxpct)
2782 return;
2783
2784 /*
2785 * This returns the % of the disk space that is used for
2786 * inodes, it changes relatively to the FS size:
2787 * - over 50 TB, use 1%,
2788 * - 1TB - 50 TB, use 5%,
2789 * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%).
2790 */
2791
2792 if (cfg->dblocks < TERABYTES(1, cfg->blocklog))
2793 cfg->imaxpct = XFS_DFL_IMAXIMUM_PCT;
2794 else if (cfg->dblocks < TERABYTES(50, cfg->blocklog))
2795 cfg->imaxpct = 5;
2796 else
2797 cfg->imaxpct = 1;
2798 }
2799
2800 /*
2801 * Set up the initial state of the superblock so we can start using the
2802 * libxfs geometry macros.
2803 */
2804 static void
2805 sb_set_features(
2806 struct mkfs_params *cfg,
2807 struct xfs_sb *sbp)
2808 {
2809 struct sb_feat_args *fp = &cfg->sb_feat;
2810
2811 sbp->sb_versionnum = XFS_DFL_SB_VERSION_BITS;
2812 if (fp->crcs_enabled)
2813 sbp->sb_versionnum |= XFS_SB_VERSION_5;
2814 else
2815 sbp->sb_versionnum |= XFS_SB_VERSION_4;
2816
2817 if (fp->inode_align) {
2818 int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
2819
2820 sbp->sb_versionnum |= XFS_SB_VERSION_ALIGNBIT;
2821 if (cfg->sb_feat.crcs_enabled)
2822 cluster_size *= cfg->inodesize / XFS_DINODE_MIN_SIZE;
2823 sbp->sb_inoalignmt = cluster_size >> cfg->blocklog;
2824 } else
2825 sbp->sb_inoalignmt = 0;
2826
2827 if (cfg->dsunit)
2828 sbp->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT;
2829 if (fp->log_version == 2)
2830 sbp->sb_versionnum |= XFS_SB_VERSION_LOGV2BIT;
2831 if (fp->attr_version == 1)
2832 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
2833 if (fp->nci)
2834 sbp->sb_versionnum |= XFS_SB_VERSION_BORGBIT;
2835
2836 if (cfg->sectorsize > BBSIZE || cfg->lsectorsize > BBSIZE) {
2837 sbp->sb_versionnum |= XFS_SB_VERSION_SECTORBIT;
2838 sbp->sb_logsectlog = (uint8_t)cfg->lsectorlog;
2839 sbp->sb_logsectsize = (uint16_t)cfg->lsectorsize;
2840 } else {
2841 sbp->sb_logsectlog = 0;
2842 sbp->sb_logsectsize = 0;
2843 }
2844
2845 sbp->sb_features2 = 0;
2846 if (fp->lazy_sb_counters)
2847 sbp->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
2848 if (fp->projid32bit)
2849 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
2850 if (fp->parent_pointers)
2851 sbp->sb_features2 |= XFS_SB_VERSION2_PARENTBIT;
2852 if (fp->crcs_enabled)
2853 sbp->sb_features2 |= XFS_SB_VERSION2_CRCBIT;
2854 if (fp->attr_version == 2)
2855 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
2856
2857 /* v5 superblocks have their own feature bit for dirftype */
2858 if (fp->dirftype && !fp->crcs_enabled)
2859 sbp->sb_features2 |= XFS_SB_VERSION2_FTYPE;
2860
2861 /* update whether extended features are in use */
2862 if (sbp->sb_features2 != 0)
2863 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
2864
2865 /*
2866 * Due to a structure alignment issue, sb_features2 ended up in one
2867 * of two locations, the second "incorrect" location represented by
2868 * the sb_bad_features2 field. To avoid older kernels mounting
2869 * filesystems they shouldn't, set both field to the same value.
2870 */
2871 sbp->sb_bad_features2 = sbp->sb_features2;
2872
2873 if (!fp->crcs_enabled)
2874 return;
2875
2876 /* default features for v5 filesystems */
2877 sbp->sb_features_compat = 0;
2878 sbp->sb_features_ro_compat = 0;
2879 sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE;
2880 sbp->sb_features_log_incompat = 0;
2881
2882 if (fp->finobt)
2883 sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT;
2884 if (fp->rmapbt)
2885 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT;
2886 if (fp->reflink)
2887 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
2888
2889 /*
2890 * Sparse inode chunk support has two main inode alignment requirements.
2891 * First, sparse chunk alignment must match the cluster size. Second,
2892 * full chunk alignment must match the inode chunk size.
2893 *
2894 * Copy the already calculated/scaled inoalignmt to spino_align and
2895 * update the former to the full inode chunk size.
2896 */
2897 if (fp->spinodes) {
2898 sbp->sb_spino_align = sbp->sb_inoalignmt;
2899 sbp->sb_inoalignmt = XFS_INODES_PER_CHUNK *
2900 cfg->inodesize >> cfg->blocklog;
2901 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
2902 }
2903
2904 }
2905
2906 /*
2907 * Make sure that the log size is a multiple of the stripe unit
2908 */
2909 static void
2910 align_log_size(
2911 struct mkfs_params *cfg,
2912 int sunit)
2913 {
2914 uint64_t tmp_logblocks;
2915
2916 /* nothing to do if it's already aligned. */
2917 if ((cfg->logblocks % sunit) == 0)
2918 return;
2919
2920 if (cli_opt_set(&lopts, L_SIZE)) {
2921 fprintf(stderr,
2922 _("log size %lld is not a multiple of the log stripe unit %d\n"),
2923 (long long) cfg->logblocks, sunit);
2924 usage();
2925 }
2926
2927 tmp_logblocks = ((cfg->logblocks + (sunit - 1)) / sunit) * sunit;
2928
2929 /* If the log is too large, round down instead of round up */
2930 if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) ||
2931 ((tmp_logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES)) {
2932 tmp_logblocks = (cfg->logblocks / sunit) * sunit;
2933 }
2934 cfg->logblocks = tmp_logblocks;
2935 }
2936
2937 /*
2938 * Make sure that the internal log is correctly aligned to the specified
2939 * stripe unit.
2940 */
2941 static void
2942 align_internal_log(
2943 struct mkfs_params *cfg,
2944 struct xfs_mount *mp,
2945 int sunit)
2946 {
2947 /* round up log start if necessary */
2948 if ((cfg->logstart % sunit) != 0)
2949 cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit;
2950
2951 /* round up/down the log size now */
2952 align_log_size(cfg, sunit);
2953
2954 /* check the aligned log still fits in an AG. */
2955 if (cfg->logblocks > cfg->agsize - XFS_FSB_TO_AGBNO(mp, cfg->logstart)) {
2956 fprintf(stderr,
2957 _("Due to stripe alignment, the internal log size (%lld) is too large.\n"
2958 "Must fit within an allocation group.\n"),
2959 (long long) cfg->logblocks);
2960 usage();
2961 }
2962 }
2963
2964 void
2965 validate_log_size(uint64_t logblocks, int blocklog, int min_logblocks)
2966 {
2967 if (logblocks < min_logblocks) {
2968 fprintf(stderr,
2969 _("log size %lld blocks too small, minimum size is %d blocks\n"),
2970 (long long)logblocks, min_logblocks);
2971 usage();
2972 }
2973 if (logblocks > XFS_MAX_LOG_BLOCKS) {
2974 fprintf(stderr,
2975 _("log size %lld blocks too large, maximum size is %lld blocks\n"),
2976 (long long)logblocks, XFS_MAX_LOG_BLOCKS);
2977 usage();
2978 }
2979 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
2980 fprintf(stderr,
2981 _("log size %lld bytes too large, maximum size is %lld bytes\n"),
2982 (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES);
2983 usage();
2984 }
2985 }
2986
2987 static void
2988 calculate_log_size(
2989 struct mkfs_params *cfg,
2990 struct cli_params *cli,
2991 struct xfs_mount *mp)
2992 {
2993 struct xfs_sb *sbp = &mp->m_sb;
2994 int min_logblocks;
2995 struct xfs_mount mount;
2996
2997 /* we need a temporary mount to calculate the minimum log size. */
2998 memset(&mount, 0, sizeof(mount));
2999 mount.m_sb = *sbp;
3000 libxfs_mount(&mount, &mp->m_sb, 0, 0, 0, 0);
3001 min_logblocks = libxfs_log_calc_minimum_size(&mount);
3002 libxfs_umount(&mount);
3003
3004 ASSERT(min_logblocks);
3005 min_logblocks = max(XFS_MIN_LOG_BLOCKS, min_logblocks);
3006
3007 /* if we have lots of blocks, check against XFS_MIN_LOG_BYTES, too */
3008 if (!cli->logsize &&
3009 cfg->dblocks >= (1024*1024*1024) >> cfg->blocklog)
3010 min_logblocks = max(min_logblocks,
3011 XFS_MIN_LOG_BYTES >> cfg->blocklog);
3012
3013 /*
3014 * external logs will have a device and size by now, so all we have
3015 * to do is validate it against minimum size and align it.
3016 */
3017 if (!cfg->loginternal) {
3018 if (min_logblocks > cfg->logblocks) {
3019 fprintf(stderr,
3020 _("external log device %lld too small, must be at least %lld blocks\n"),
3021 (long long)cfg->logblocks,
3022 (long long)min_logblocks);
3023 usage();
3024 }
3025 cfg->logstart = 0;
3026 cfg->logagno = 0;
3027 if (cfg->lsunit)
3028 align_log_size(cfg, cfg->lsunit);
3029
3030 validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
3031 return;
3032 }
3033
3034 /* internal log - if no size specified, calculate automatically */
3035 if (!cfg->logblocks) {
3036 if (cfg->dblocks < GIGABYTES(1, cfg->blocklog)) {
3037 /* tiny filesystems get minimum sized logs. */
3038 cfg->logblocks = min_logblocks;
3039 } else if (cfg->dblocks < GIGABYTES(16, cfg->blocklog)) {
3040
3041 /*
3042 * For small filesystems, we want to use the
3043 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
3044 * at all possible, ramping up to 128MB at 256GB.
3045 */
3046 cfg->logblocks = min(XFS_MIN_LOG_BYTES >> cfg->blocklog,
3047 min_logblocks * XFS_DFL_LOG_FACTOR);
3048 } else {
3049 /*
3050 * With a 2GB max log size, default to maximum size
3051 * at 4TB. This keeps the same ratio from the older
3052 * max log size of 128M at 256GB fs size. IOWs,
3053 * the ratio of fs size to log size is 2048:1.
3054 */
3055 cfg->logblocks = (cfg->dblocks << cfg->blocklog) / 2048;
3056 cfg->logblocks = cfg->logblocks >> cfg->blocklog;
3057 }
3058
3059 /* Ensure the chosen size meets minimum log size requirements */
3060 cfg->logblocks = max(min_logblocks, cfg->logblocks);
3061
3062 /*
3063 * Make sure the log fits wholly within an AG
3064 *
3065 * XXX: If agf->freeblks ends up as 0 because the log uses all
3066 * the free space, it causes the kernel all sorts of problems
3067 * with per-ag reservations. Right now just back it off one
3068 * block, but there's a whole can of worms here that needs to be
3069 * opened to decide what is the valid maximum size of a log in
3070 * an AG.
3071 */
3072 cfg->logblocks = min(cfg->logblocks,
3073 libxfs_alloc_ag_max_usable(mp) - 1);
3074
3075 /* and now clamp the size to the maximum supported size */
3076 cfg->logblocks = min(cfg->logblocks, XFS_MAX_LOG_BLOCKS);
3077 if ((cfg->logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES)
3078 cfg->logblocks = XFS_MAX_LOG_BYTES >> cfg->blocklog;
3079
3080 validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
3081 }
3082
3083 if (cfg->logblocks > sbp->sb_agblocks - libxfs_prealloc_blocks(mp)) {
3084 fprintf(stderr,
3085 _("internal log size %lld too large, must fit in allocation group\n"),
3086 (long long)cfg->logblocks);
3087 usage();
3088 }
3089
3090 if (cli_opt_set(&lopts, L_AGNUM)) {
3091 if (cli->logagno >= sbp->sb_agcount) {
3092 fprintf(stderr,
3093 _("log ag number %lld too large, must be less than %lld\n"),
3094 (long long)cli->logagno,
3095 (long long)sbp->sb_agcount);
3096 usage();
3097 }
3098 cfg->logagno = cli->logagno;
3099 } else
3100 cfg->logagno = (xfs_agnumber_t)(sbp->sb_agcount / 2);
3101
3102 cfg->logstart = XFS_AGB_TO_FSB(mp, cfg->logagno,
3103 libxfs_prealloc_blocks(mp));
3104
3105 /*
3106 * Align the logstart at stripe unit boundary.
3107 */
3108 if (cfg->lsunit) {
3109 align_internal_log(cfg, mp, cfg->lsunit);
3110 } else if (cfg->dsunit) {
3111 align_internal_log(cfg, mp, cfg->dsunit);
3112 }
3113 validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
3114 }
3115
3116 /*
3117 * Set up superblock with the minimum parameters required for
3118 * the libxfs macros needed by the log sizing code to run successfully.
3119 * This includes a minimum log size calculation, so we need everything
3120 * that goes into that calculation to be setup here including feature
3121 * flags.
3122 */
3123 static void
3124 start_superblock_setup(
3125 struct mkfs_params *cfg,
3126 struct xfs_mount *mp,
3127 struct xfs_sb *sbp)
3128 {
3129 sbp->sb_magicnum = XFS_SB_MAGIC;
3130 sbp->sb_sectsize = (uint16_t)cfg->sectorsize;
3131 sbp->sb_sectlog = (uint8_t)cfg->sectorlog;
3132 sbp->sb_blocksize = cfg->blocksize;
3133 sbp->sb_blocklog = (uint8_t)cfg->blocklog;
3134
3135 sbp->sb_agblocks = (xfs_agblock_t)cfg->agsize;
3136 sbp->sb_agblklog = (uint8_t)log2_roundup(cfg->agsize);
3137 sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
3138
3139 sbp->sb_inodesize = (uint16_t)cfg->inodesize;
3140 sbp->sb_inodelog = (uint8_t)cfg->inodelog;
3141 sbp->sb_inopblock = (uint16_t)(cfg->blocksize / cfg->inodesize);
3142 sbp->sb_inopblog = (uint8_t)(cfg->blocklog - cfg->inodelog);
3143
3144 sbp->sb_dirblklog = cfg->dirblocklog - cfg->blocklog;
3145
3146 sb_set_features(cfg, sbp);
3147
3148 /*
3149 * log stripe unit is stored in bytes on disk and cannot be zero
3150 * for v2 logs.
3151 */
3152 if (cfg->sb_feat.log_version == 2) {
3153 if (cfg->lsunit)
3154 sbp->sb_logsunit = XFS_FSB_TO_B(mp, cfg->lsunit);
3155 else
3156 sbp->sb_logsunit = 1;
3157 } else
3158 sbp->sb_logsunit = 0;
3159
3160 }
3161
3162 static void
3163 initialise_mount(
3164 struct mkfs_params *cfg,
3165 struct xfs_mount *mp,
3166 struct xfs_sb *sbp)
3167 {
3168 /* Minimum needed for libxfs_prealloc_blocks() */
3169 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
3170 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
3171 }
3172
3173 /*
3174 * Format everything from the generated config into the superblock that
3175 * will be used to initialise the on-disk superblock. This is the in-memory
3176 * copy, so no need to care about endian swapping here.
3177 */
3178 static void
3179 finish_superblock_setup(
3180 struct mkfs_params *cfg,
3181 struct xfs_mount *mp,
3182 struct xfs_sb *sbp)
3183 {
3184 if (cfg->label)
3185 strncpy(sbp->sb_fname, cfg->label, sizeof(sbp->sb_fname));
3186
3187 sbp->sb_dblocks = cfg->dblocks;
3188 sbp->sb_rblocks = cfg->rtblocks;
3189 sbp->sb_rextents = cfg->rtextents;
3190 platform_uuid_copy(&sbp->sb_uuid, &cfg->uuid);
3191 /* Only in memory; libxfs expects this as if read from disk */
3192 platform_uuid_copy(&sbp->sb_meta_uuid, &cfg->uuid);
3193 sbp->sb_logstart = cfg->logstart;
3194 sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
3195 sbp->sb_rextsize = cfg->rtextblocks;
3196 sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
3197 sbp->sb_rbmblocks = cfg->rtbmblocks;
3198 sbp->sb_logblocks = (xfs_extlen_t)cfg->logblocks;
3199 sbp->sb_rextslog = (uint8_t)(cfg->rtextents ?
3200 libxfs_highbit32((unsigned int)cfg->rtextents) : 0);
3201 sbp->sb_inprogress = 1; /* mkfs is in progress */
3202 sbp->sb_imax_pct = cfg->imaxpct;
3203 sbp->sb_icount = 0;
3204 sbp->sb_ifree = 0;
3205 sbp->sb_fdblocks = cfg->dblocks -
3206 cfg->agcount * libxfs_prealloc_blocks(mp) -
3207 (cfg->loginternal ? cfg->logblocks : 0);
3208 sbp->sb_frextents = 0; /* will do a free later */
3209 sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
3210 sbp->sb_qflags = 0;
3211 sbp->sb_unit = cfg->dsunit;
3212 sbp->sb_width = cfg->dswidth;
3213
3214 }
3215
3216 /*
3217 * Sanitise the data and log devices and prepare them so libxfs can mount the
3218 * device successfully. Also check we can access the rt device if configured.
3219 */
3220 static void
3221 prepare_devices(
3222 struct mkfs_params *cfg,
3223 struct libxfs_xinit *xi,
3224 struct xfs_mount *mp,
3225 struct xfs_sb *sbp,
3226 bool clear_stale)
3227 {
3228 struct xfs_buf *buf;
3229 int whack_blks = BTOBB(WHACK_SIZE);
3230 int lsunit;
3231
3232 /*
3233 * If there's an old XFS filesystem on the device with enough intact
3234 * information that we can parse the superblock, there's enough
3235 * information on disk to confuse a future xfs_repair call. To avoid
3236 * this, whack all the old secondary superblocks that we can find.
3237 */
3238 if (clear_stale)
3239 zero_old_xfs_structures(xi, sbp);
3240
3241 /*
3242 * If the data device is a file, grow out the file to its final size if
3243 * needed so that the reads for the end of the device in the mount code
3244 * will succeed.
3245 */
3246 if (xi->disfile &&
3247 xi->dsize * xi->dbsize < cfg->dblocks * cfg->blocksize) {
3248 if (ftruncate(xi->dfd, cfg->dblocks * cfg->blocksize) < 0) {
3249 fprintf(stderr,
3250 _("%s: Growing the data section failed\n"),
3251 progname);
3252 exit(1);
3253 }
3254
3255 /* update size to be able to whack blocks correctly */
3256 xi->dsize = BTOBB(cfg->dblocks * cfg->blocksize);
3257 }
3258
3259 /*
3260 * Zero out the end to obliterate any old MD RAID (or other) metadata at
3261 * the end of the device. (MD sb is ~64k from the end, take out a wider
3262 * swath to be sure)
3263 */
3264 buf = libxfs_getbuf(mp->m_ddev_targp, (xi->dsize - whack_blks),
3265 whack_blks);
3266 memset(buf->b_addr, 0, WHACK_SIZE);
3267 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3268 libxfs_purgebuf(buf);
3269
3270 /*
3271 * Now zero out the beginning of the device, to obliterate any old
3272 * filesystem signatures out there. This should take care of
3273 * swap (somewhere around the page size), jfs (32k),
3274 * ext[2,3] and reiserfs (64k) - and hopefully all else.
3275 */
3276 buf = libxfs_getbuf(mp->m_ddev_targp, 0, whack_blks);
3277 memset(buf->b_addr, 0, WHACK_SIZE);
3278 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3279 libxfs_purgebuf(buf);
3280
3281 /* OK, now write the superblock... */
3282 buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
3283 buf->b_ops = &xfs_sb_buf_ops;
3284 memset(buf->b_addr, 0, cfg->sectorsize);
3285 libxfs_sb_to_disk(buf->b_addr, sbp);
3286 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3287 libxfs_purgebuf(buf);
3288
3289 /* ...and zero the log.... */
3290 lsunit = sbp->sb_logsunit;
3291 if (lsunit == 1)
3292 lsunit = sbp->sb_logsectsize;
3293
3294 libxfs_log_clear(mp->m_logdev_targp, NULL,
3295 XFS_FSB_TO_DADDR(mp, cfg->logstart),
3296 (xfs_extlen_t)XFS_FSB_TO_BB(mp, cfg->logblocks),
3297 &sbp->sb_uuid, cfg->sb_feat.log_version,
3298 lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
3299
3300 /* finally, check we can write the last block in the realtime area */
3301 if (mp->m_rtdev_targp->dev && cfg->rtblocks > 0) {
3302 buf = libxfs_getbuf(mp->m_rtdev_targp,
3303 XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
3304 BTOBB(cfg->blocksize));
3305 memset(buf->b_addr, 0, cfg->blocksize);
3306 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3307 libxfs_purgebuf(buf);
3308 }
3309
3310 }
3311
3312 /*
3313 * XXX: this code is mostly common with the kernel growfs code.
3314 * These initialisations should be pulled into libxfs to keep the
3315 * kernel/userspace header initialisation code the same.
3316 */
3317 static void
3318 initialise_ag_headers(
3319 struct mkfs_params *cfg,
3320 struct xfs_mount *mp,
3321 struct xfs_sb *sbp,
3322 xfs_agnumber_t agno,
3323 int *worst_freelist)
3324 {
3325 struct xfs_perag *pag = libxfs_perag_get(mp, agno);
3326 struct xfs_agfl *agfl;
3327 struct xfs_agf *agf;
3328 struct xfs_agi *agi;
3329 struct xfs_buf *buf;
3330 struct xfs_btree_block *block;
3331 struct xfs_alloc_rec *arec;
3332 struct xfs_alloc_rec *nrec;
3333 int bucket;
3334 uint64_t agsize = cfg->agsize;
3335 xfs_agblock_t agblocks;
3336 bool is_log_ag = false;
3337 int c;
3338
3339 if (cfg->loginternal && agno == cfg->logagno)
3340 is_log_ag = true;
3341
3342 /*
3343 * Superblock.
3344 */
3345 buf = libxfs_getbuf(mp->m_ddev_targp,
3346 XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
3347 XFS_FSS_TO_BB(mp, 1));
3348 buf->b_ops = &xfs_sb_buf_ops;
3349 memset(buf->b_addr, 0, cfg->sectorsize);
3350 libxfs_sb_to_disk(buf->b_addr, sbp);
3351 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3352
3353 /*
3354 * AG header block: freespace
3355 */
3356 buf = libxfs_getbuf(mp->m_ddev_targp,
3357 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
3358 XFS_FSS_TO_BB(mp, 1));
3359 buf->b_ops = &xfs_agf_buf_ops;
3360 agf = XFS_BUF_TO_AGF(buf);
3361 memset(agf, 0, cfg->sectorsize);
3362 if (agno == cfg->agcount - 1)
3363 agsize = cfg->dblocks - (xfs_rfsblock_t)(agno * agsize);
3364 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
3365 agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
3366 agf->agf_seqno = cpu_to_be32(agno);
3367 agf->agf_length = cpu_to_be32(agsize);
3368 agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
3369 agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
3370 agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
3371 agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
3372 pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
3373 pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
3374
3375 if (xfs_sb_version_hasrmapbt(sbp)) {
3376 agf->agf_roots[XFS_BTNUM_RMAPi] = cpu_to_be32(XFS_RMAP_BLOCK(mp));
3377 agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
3378 agf->agf_rmap_blocks = cpu_to_be32(1);
3379 }
3380
3381 if (xfs_sb_version_hasreflink(sbp)) {
3382 agf->agf_refcount_root = cpu_to_be32(libxfs_refc_block(mp));
3383 agf->agf_refcount_level = cpu_to_be32(1);
3384 agf->agf_refcount_blocks = cpu_to_be32(1);
3385 }
3386
3387 agf->agf_flfirst = 0;
3388 agf->agf_fllast = cpu_to_be32(libxfs_agfl_size(mp) - 1);
3389 agf->agf_flcount = 0;
3390 agblocks = (xfs_agblock_t)(agsize - libxfs_prealloc_blocks(mp));
3391 agf->agf_freeblks = cpu_to_be32(agblocks);
3392 agf->agf_longest = cpu_to_be32(agblocks);
3393
3394 if (xfs_sb_version_hascrc(sbp))
3395 platform_uuid_copy(&agf->agf_uuid, &sbp->sb_uuid);
3396
3397 if (is_log_ag) {
3398 be32_add_cpu(&agf->agf_freeblks, -(int64_t)cfg->logblocks);
3399 agf->agf_longest = cpu_to_be32(agsize -
3400 XFS_FSB_TO_AGBNO(mp, cfg->logstart) - cfg->logblocks);
3401 }
3402 if (libxfs_alloc_min_freelist(mp, pag) > *worst_freelist)
3403 *worst_freelist = libxfs_alloc_min_freelist(mp, pag);
3404 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3405
3406 /*
3407 * AG freelist header block
3408 */
3409 buf = libxfs_getbuf(mp->m_ddev_targp,
3410 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
3411 XFS_FSS_TO_BB(mp, 1));
3412 buf->b_ops = &xfs_agfl_buf_ops;
3413 agfl = XFS_BUF_TO_AGFL(buf);
3414 /* setting to 0xff results in initialisation to NULLAGBLOCK */
3415 memset(agfl, 0xff, cfg->sectorsize);
3416 if (xfs_sb_version_hascrc(sbp)) {
3417 agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
3418 agfl->agfl_seqno = cpu_to_be32(agno);
3419 platform_uuid_copy(&agfl->agfl_uuid, &sbp->sb_uuid);
3420 for (bucket = 0; bucket < libxfs_agfl_size(mp); bucket++)
3421 agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
3422 }
3423
3424 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3425
3426 /*
3427 * AG header block: inodes
3428 */
3429 buf = libxfs_getbuf(mp->m_ddev_targp,
3430 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
3431 XFS_FSS_TO_BB(mp, 1));
3432 agi = XFS_BUF_TO_AGI(buf);
3433 buf->b_ops = &xfs_agi_buf_ops;
3434 memset(agi, 0, cfg->sectorsize);
3435 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
3436 agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
3437 agi->agi_seqno = cpu_to_be32(agno);
3438 agi->agi_length = cpu_to_be32(agsize);
3439 agi->agi_count = 0;
3440 agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
3441 agi->agi_level = cpu_to_be32(1);
3442 if (xfs_sb_version_hasfinobt(sbp)) {
3443 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
3444 agi->agi_free_level = cpu_to_be32(1);
3445 }
3446 agi->agi_freecount = 0;
3447 agi->agi_newino = cpu_to_be32(NULLAGINO);
3448 agi->agi_dirino = cpu_to_be32(NULLAGINO);
3449 if (xfs_sb_version_hascrc(sbp))
3450 platform_uuid_copy(&agi->agi_uuid, &sbp->sb_uuid);
3451 for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
3452 agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
3453 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3454
3455 /*
3456 * BNO btree root block
3457 */
3458 buf = libxfs_getbuf(mp->m_ddev_targp,
3459 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
3460 BTOBB(cfg->blocksize));
3461 buf->b_ops = &xfs_allocbt_buf_ops;
3462 block = XFS_BUF_TO_BLOCK(buf);
3463 memset(block, 0, cfg->blocksize);
3464 libxfs_btree_init_block(mp, buf, XFS_BTNUM_BNO, 0, 1, agno, 0);
3465
3466 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3467 arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
3468 if (is_log_ag) {
3469 xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, cfg->logstart);
3470
3471 ASSERT(start >= libxfs_prealloc_blocks(mp));
3472 if (start != libxfs_prealloc_blocks(mp)) {
3473 /*
3474 * Modify first record to pad stripe align of log
3475 */
3476 arec->ar_blockcount = cpu_to_be32(start -
3477 libxfs_prealloc_blocks(mp));
3478 nrec = arec + 1;
3479 /*
3480 * Insert second record at start of internal log
3481 * which then gets trimmed.
3482 */
3483 nrec->ar_startblock = cpu_to_be32(
3484 be32_to_cpu(arec->ar_startblock) +
3485 be32_to_cpu(arec->ar_blockcount));
3486 arec = nrec;
3487 be16_add_cpu(&block->bb_numrecs, 1);
3488 }
3489 /*
3490 * Change record start to after the internal log
3491 */
3492 be32_add_cpu(&arec->ar_startblock, cfg->logblocks);
3493 }
3494 /*
3495 * Calculate the record block count and check for the case where
3496 * the log might have consumed all available space in the AG. If
3497 * so, reset the record count to 0 to avoid exposure of an invalid
3498 * record start block.
3499 */
3500 arec->ar_blockcount = cpu_to_be32(agsize -
3501 be32_to_cpu(arec->ar_startblock));
3502 if (!arec->ar_blockcount)
3503 block->bb_numrecs = 0;
3504
3505 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3506
3507 /*
3508 * CNT btree root block
3509 */
3510 buf = libxfs_getbuf(mp->m_ddev_targp,
3511 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
3512 BTOBB(cfg->blocksize));
3513 buf->b_ops = &xfs_allocbt_buf_ops;
3514 block = XFS_BUF_TO_BLOCK(buf);
3515 memset(block, 0, cfg->blocksize);
3516 libxfs_btree_init_block(mp, buf, XFS_BTNUM_CNT, 0, 1, agno, 0);
3517
3518 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3519 arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
3520 if (is_log_ag) {
3521 xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, cfg->logstart);
3522
3523 ASSERT(start >= libxfs_prealloc_blocks(mp));
3524 if (start != libxfs_prealloc_blocks(mp)) {
3525 arec->ar_blockcount = cpu_to_be32(start -
3526 libxfs_prealloc_blocks(mp));
3527 nrec = arec + 1;
3528 nrec->ar_startblock = cpu_to_be32(
3529 be32_to_cpu(arec->ar_startblock) +
3530 be32_to_cpu(arec->ar_blockcount));
3531 arec = nrec;
3532 be16_add_cpu(&block->bb_numrecs, 1);
3533 }
3534 be32_add_cpu(&arec->ar_startblock, cfg->logblocks);
3535 }
3536 /*
3537 * Calculate the record block count and check for the case where
3538 * the log might have consumed all available space in the AG. If
3539 * so, reset the record count to 0 to avoid exposure of an invalid
3540 * record start block.
3541 */
3542 arec->ar_blockcount = cpu_to_be32(agsize -
3543 be32_to_cpu(arec->ar_startblock));
3544 if (!arec->ar_blockcount)
3545 block->bb_numrecs = 0;
3546
3547 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3548
3549 /*
3550 * refcount btree root block
3551 */
3552 if (xfs_sb_version_hasreflink(sbp)) {
3553 buf = libxfs_getbuf(mp->m_ddev_targp,
3554 XFS_AGB_TO_DADDR(mp, agno, libxfs_refc_block(mp)),
3555 BTOBB(cfg->blocksize));
3556 buf->b_ops = &xfs_refcountbt_buf_ops;
3557
3558 block = XFS_BUF_TO_BLOCK(buf);
3559 memset(block, 0, cfg->blocksize);
3560 libxfs_btree_init_block(mp, buf, XFS_BTNUM_REFC, 0, 0, agno, 0);
3561 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3562 }
3563
3564 /*
3565 * INO btree root block
3566 */
3567 buf = libxfs_getbuf(mp->m_ddev_targp,
3568 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
3569 BTOBB(cfg->blocksize));
3570 buf->b_ops = &xfs_inobt_buf_ops;
3571 block = XFS_BUF_TO_BLOCK(buf);
3572 memset(block, 0, cfg->blocksize);
3573 libxfs_btree_init_block(mp, buf, XFS_BTNUM_INO, 0, 0, agno, 0);
3574 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3575
3576 /*
3577 * Free INO btree root block
3578 */
3579 if (xfs_sb_version_hasfinobt(sbp)) {
3580 buf = libxfs_getbuf(mp->m_ddev_targp,
3581 XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
3582 BTOBB(cfg->blocksize));
3583 buf->b_ops = &xfs_inobt_buf_ops;
3584 block = XFS_BUF_TO_BLOCK(buf);
3585 memset(block, 0, cfg->blocksize);
3586 libxfs_btree_init_block(mp, buf, XFS_BTNUM_FINO, 0, 0, agno, 0);
3587 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3588 }
3589
3590 /* RMAP btree root block */
3591 if (xfs_sb_version_hasrmapbt(sbp)) {
3592 struct xfs_rmap_rec *rrec;
3593
3594 buf = libxfs_getbuf(mp->m_ddev_targp,
3595 XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)),
3596 BTOBB(cfg->blocksize));
3597 buf->b_ops = &xfs_rmapbt_buf_ops;
3598 block = XFS_BUF_TO_BLOCK(buf);
3599 memset(block, 0, cfg->blocksize);
3600
3601 libxfs_btree_init_block(mp, buf, XFS_BTNUM_RMAP, 0, 0, agno, 0);
3602
3603 /*
3604 * mark the AG header regions as static metadata
3605 * The BNO btree block is the first block after the
3606 * headers, so it's location defines the size of region
3607 * the static metadata consumes.
3608 */
3609 rrec = XFS_RMAP_REC_ADDR(block, 1);
3610 rrec->rm_startblock = 0;
3611 rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
3612 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
3613 rrec->rm_offset = 0;
3614 be16_add_cpu(&block->bb_numrecs, 1);
3615
3616 /* account freespace btree root blocks */
3617 rrec = XFS_RMAP_REC_ADDR(block, 2);
3618 rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
3619 rrec->rm_blockcount = cpu_to_be32(2);
3620 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
3621 rrec->rm_offset = 0;
3622 be16_add_cpu(&block->bb_numrecs, 1);
3623
3624 /* account inode btree root blocks */
3625 rrec = XFS_RMAP_REC_ADDR(block, 3);
3626 rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
3627 rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
3628 XFS_IBT_BLOCK(mp));
3629 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
3630 rrec->rm_offset = 0;
3631 be16_add_cpu(&block->bb_numrecs, 1);
3632
3633 /* account for rmap btree root */
3634 rrec = XFS_RMAP_REC_ADDR(block, 4);
3635 rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
3636 rrec->rm_blockcount = cpu_to_be32(1);
3637 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
3638 rrec->rm_offset = 0;
3639 be16_add_cpu(&block->bb_numrecs, 1);
3640
3641 /* account for refcount btree root */
3642 if (xfs_sb_version_hasreflink(sbp)) {
3643 rrec = XFS_RMAP_REC_ADDR(block, 5);
3644 rrec->rm_startblock = cpu_to_be32(libxfs_refc_block(mp));
3645 rrec->rm_blockcount = cpu_to_be32(1);
3646 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
3647 rrec->rm_offset = 0;
3648 be16_add_cpu(&block->bb_numrecs, 1);
3649 }
3650
3651 /* account for the log space */
3652 if (is_log_ag) {
3653 rrec = XFS_RMAP_REC_ADDR(block,
3654 be16_to_cpu(block->bb_numrecs) + 1);
3655 rrec->rm_startblock = cpu_to_be32(
3656 XFS_FSB_TO_AGBNO(mp, cfg->logstart));
3657 rrec->rm_blockcount = cpu_to_be32(cfg->logblocks);
3658 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
3659 rrec->rm_offset = 0;
3660 be16_add_cpu(&block->bb_numrecs, 1);
3661 }
3662
3663 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3664 }
3665
3666 libxfs_perag_put(pag);
3667 }
3668
3669 static void
3670 initialise_ag_freespace(
3671 struct xfs_mount *mp,
3672 xfs_agnumber_t agno,
3673 int worst_freelist)
3674 {
3675 struct xfs_alloc_arg args;
3676 struct xfs_trans *tp;
3677 int c;
3678
3679 c = -libxfs_trans_alloc_rollable(mp, worst_freelist, &tp);
3680 if (c)
3681 res_failed(c);
3682
3683 memset(&args, 0, sizeof(args));
3684 args.tp = tp;
3685 args.mp = mp;
3686 args.agno = agno;
3687 args.alignment = 1;
3688 args.pag = libxfs_perag_get(mp, agno);
3689
3690 libxfs_alloc_fix_freelist(&args, 0);
3691 libxfs_perag_put(args.pag);
3692 libxfs_trans_commit(tp);
3693 }
3694
3695 /*
3696 * rewrite several secondary superblocks with the root inode number filled out.
3697 * This can help repair recovery from a trashed primary superblock without
3698 * losing the root inode.
3699 */
3700 static void
3701 rewrite_secondary_superblocks(
3702 struct xfs_mount *mp)
3703 {
3704 struct xfs_buf *buf;
3705
3706 /* rewrite the last superblock */
3707 buf = libxfs_readbuf(mp->m_dev,
3708 XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount - 1,
3709 XFS_SB_DADDR),
3710 XFS_FSS_TO_BB(mp, 1),
3711 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3712 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
3713 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3714
3715 /* and one in the middle for luck if there's enough AGs for that */
3716 if (mp->m_sb.sb_agcount <= 2)
3717 return;
3718
3719 buf = libxfs_readbuf(mp->m_dev,
3720 XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount - 1) / 2,
3721 XFS_SB_DADDR),
3722 XFS_FSS_TO_BB(mp, 1),
3723 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3724 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
3725 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3726 }
3727
3728 int
3729 main(
3730 int argc,
3731 char **argv)
3732 {
3733 xfs_agnumber_t agno;
3734 xfs_buf_t *buf;
3735 int c;
3736 char *dfile = NULL;
3737 char *logfile = NULL;
3738 char *rtfile = NULL;
3739 int dry_run = 0;
3740 int discard = 1;
3741 int force_overwrite = 0;
3742 int quiet = 0;
3743 char *protofile = NULL;
3744 char *protostring = NULL;
3745 int worst_freelist = 0;
3746
3747 struct libxfs_xinit xi = {
3748 .isdirect = LIBXFS_DIRECT,
3749 .isreadonly = LIBXFS_EXCLUSIVELY,
3750 };
3751 struct xfs_mount mbuf = {};
3752 struct xfs_mount *mp = &mbuf;
3753 struct xfs_sb *sbp = &mp->m_sb;
3754 struct fs_topology ft = {};
3755 struct cli_params cli = {
3756 .xi = &xi,
3757 .loginternal = 1,
3758 };
3759 struct mkfs_params cfg = {};
3760
3761 /* build time defaults */
3762 struct mkfs_default_params dft = {
3763 .source = _("package build definitions"),
3764 .sectorsize = XFS_MIN_SECTORSIZE,
3765 .blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG,
3766 .sb_feat = {
3767 .log_version = 2,
3768 .attr_version = 2,
3769 .dir_version = 2,
3770 .inode_align = true,
3771 .nci = false,
3772 .lazy_sb_counters = true,
3773 .projid32bit = true,
3774 .crcs_enabled = true,
3775 .dirftype = true,
3776 .finobt = true,
3777 .spinodes = true,
3778 .rmapbt = false,
3779 .reflink = false,
3780 .parent_pointers = false,
3781 .nodalign = false,
3782 .nortalign = false,
3783 },
3784 };
3785
3786 platform_uuid_generate(&cli.uuid);
3787 progname = basename(argv[0]);
3788 setlocale(LC_ALL, "");
3789 bindtextdomain(PACKAGE, LOCALEDIR);
3790 textdomain(PACKAGE);
3791
3792 /*
3793 * TODO: Sourcing defaults from a config file
3794 *
3795 * Before anything else, see if there's a config file with different
3796 * defaults. If a file exists in <package location>, read in the new
3797 * default values and overwrite them in the &dft structure. This way the
3798 * new defaults will apply before we parse the CLI, and the CLI will
3799 * still be able to override them. When more than one source is
3800 * implemented, emit a message to indicate where the defaults being
3801 * used came from.
3802 *
3803 * printf(_("Default configuration sourced from %s\n"), dft.source);
3804 */
3805
3806 /* copy new defaults into CLI parsing structure */
3807 memcpy(&cli.sb_feat, &dft.sb_feat, sizeof(cli.sb_feat));
3808 memcpy(&cli.fsx, &dft.fsx, sizeof(cli.fsx));
3809
3810 while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
3811 switch (c) {
3812 case 'C':
3813 case 'f':
3814 force_overwrite = 1;
3815 break;
3816 case 'b':
3817 case 'd':
3818 case 'i':
3819 case 'l':
3820 case 'm':
3821 case 'n':
3822 case 'r':
3823 case 's':
3824 parse_subopts(c, optarg, &cli);
3825 break;
3826 case 'L':
3827 if (strlen(optarg) > sizeof(sbp->sb_fname))
3828 illegal(optarg, "L");
3829 cfg.label = optarg;
3830 break;
3831 case 'N':
3832 dry_run = 1;
3833 break;
3834 case 'K':
3835 discard = 0;
3836 break;
3837 case 'p':
3838 if (protofile)
3839 respec('p', NULL, 0);
3840 protofile = optarg;
3841 break;
3842 case 'q':
3843 quiet = 1;
3844 break;
3845 case 'V':
3846 printf(_("%s version %s\n"), progname, VERSION);
3847 exit(0);
3848 case '?':
3849 unknown(optopt, "");
3850 }
3851 }
3852 if (argc - optind > 1) {
3853 fprintf(stderr, _("extra arguments\n"));
3854 usage();
3855 } else if (argc - optind == 1) {
3856 dfile = xi.volname = getstr(argv[optind], &dopts, D_NAME);
3857 } else
3858 dfile = xi.dname;
3859
3860 protostring = setup_proto(protofile);
3861
3862 /*
3863 * Extract as much of the valid config as we can from the CLI input
3864 * before opening the libxfs devices.
3865 */
3866 validate_blocksize(&cfg, &cli, &dft);
3867 validate_sectorsize(&cfg, &cli, &dft, &ft, dfile, dry_run,
3868 force_overwrite);
3869
3870 /*
3871 * XXX: we still need to set block size and sector size global variables
3872 * so that getnum/cvtnum works correctly
3873 */
3874 blocksize = cfg.blocksize;
3875 sectorsize = cfg.sectorsize;
3876
3877 validate_log_sectorsize(&cfg, &cli, &dft);
3878 validate_sb_features(&cfg, &cli);
3879
3880 /*
3881 * we've now completed basic validation of the features, sector and
3882 * block sizes, so from this point onwards we use the values found in
3883 * the cfg structure for them, not the command line structure.
3884 */
3885 validate_dirblocksize(&cfg, &cli);
3886 validate_inodesize(&cfg, &cli);
3887
3888 /*
3889 * if the device size was specified convert it to a block count
3890 * now we have a valid block size. These will be set to zero if
3891 * nothing was specified, indicating we should use the full device.
3892 */
3893 cfg.dblocks = calc_dev_size(cli.dsize, &cfg, &dopts, D_SIZE, "data");
3894 cfg.logblocks = calc_dev_size(cli.logsize, &cfg, &lopts, L_SIZE, "log");
3895 cfg.rtblocks = calc_dev_size(cli.rtsize, &cfg, &ropts, R_SIZE, "rt");
3896
3897 validate_rtextsize(&cfg, &cli, &ft);
3898 calc_stripe_factors(&cfg, &cli, &ft);
3899
3900 /*
3901 * Open and validate the device configurations
3902 */
3903 open_devices(&cfg, &xi, (discard && !dry_run));
3904 validate_datadev(&cfg, &cli);
3905 validate_logdev(&cfg, &cli, &logfile);
3906 validate_rtdev(&cfg, &cli, &rtfile);
3907
3908 /*
3909 * At this point when know exactly what size all the devices are,
3910 * so we can start validating and calculating layout options that are
3911 * dependent on device sizes. Once calculated, make sure everything
3912 * aligns to device geometry correctly.
3913 */
3914 calculate_initial_ag_geometry(&cfg, &cli);
3915 align_ag_geometry(&cfg);
3916
3917 calculate_imaxpct(&cfg, &cli);
3918
3919 /*
3920 * Set up the basic superblock parameters now so that we can use
3921 * the geometry information we've already validated in libxfs
3922 * provided functions to determine on-disk format information.
3923 */
3924 start_superblock_setup(&cfg, mp, sbp);
3925 initialise_mount(&cfg, mp, sbp);
3926
3927 /*
3928 * With the mount set up, we can finally calculate the log size
3929 * constraints and do default size calculations and final validation
3930 */
3931 calculate_log_size(&cfg, &cli, mp);
3932
3933 finish_superblock_setup(&cfg, mp, sbp);
3934
3935 /* Print the intended geometry of the fs. */
3936 if (!quiet || dry_run) {
3937 struct xfs_fsop_geom geo;
3938 int error;
3939
3940 error = -libxfs_fs_geometry(sbp, &geo,
3941 XFS_FS_GEOM_MAX_STRUCT_VER);
3942 if (error) {
3943 fprintf(stderr,
3944 _("%s: failed to generate filesystem geometry\n"),
3945 progname);
3946 exit(1);
3947 }
3948
3949 xfs_report_geom(&geo, dfile, logfile, rtfile);
3950 if (dry_run)
3951 exit(0);
3952 }
3953
3954 /*
3955 * we need the libxfs buffer cache from here on in.
3956 */
3957 libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
3958
3959 /*
3960 * Before we mount the filesystem we need to make sure the devices have
3961 * enough of the filesystem structure on them that allows libxfs to
3962 * mount.
3963 */
3964 prepare_devices(&cfg, &xi, mp, sbp, force_overwrite);
3965 mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
3966 if (mp == NULL) {
3967 fprintf(stderr, _("%s: filesystem failed to initialize\n"),
3968 progname);
3969 exit(1);
3970 }
3971
3972 /*
3973 * Initialise all the static on disk metadata.
3974 */
3975 for (agno = 0; agno < cfg.agcount; agno++)
3976 initialise_ag_headers(&cfg, mp, sbp, agno, &worst_freelist);
3977
3978 /*
3979 * Initialise the freespace freelists (i.e. AGFLs) in each AG.
3980 */
3981 for (agno = 0; agno < cfg.agcount; agno++)
3982 initialise_ag_freespace(mp, agno, worst_freelist);
3983
3984 /*
3985 * Allocate the root inode and anything else in the proto file.
3986 */
3987 parse_proto(mp, &cli.fsx, &protostring);
3988
3989 /*
3990 * Protect ourselves against possible stupidity
3991 */
3992 if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
3993 fprintf(stderr,
3994 _("%s: root inode created in AG %u, not AG 0\n"),
3995 progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
3996 exit(1);
3997 }
3998
3999 /*
4000 * Re-write multiple secondary superblocks with rootinode field set
4001 */
4002 if (mp->m_sb.sb_agcount > 1)
4003 rewrite_secondary_superblocks(mp);
4004
4005 /*
4006 * Dump all inodes and buffers before marking us all done.
4007 * Need to drop references to inodes we still hold, first.
4008 */
4009 libxfs_rtmount_destroy(mp);
4010 libxfs_bcache_purge();
4011
4012 /*
4013 * Mark the filesystem ok.
4014 */
4015 buf = libxfs_getsb(mp, LIBXFS_EXIT_ON_FAILURE);
4016 (XFS_BUF_TO_SBP(buf))->sb_inprogress = 0;
4017 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
4018
4019 libxfs_umount(mp);
4020 if (xi.rtdev)
4021 libxfs_device_close(xi.rtdev);
4022 if (xi.logdev && xi.logdev != xi.ddev)
4023 libxfs_device_close(xi.logdev);
4024 libxfs_device_close(xi.ddev);
4025 libxfs_destroy();
4026
4027 return 0;
4028 }