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