]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfs/xfs_mkfs.c
mkfs.xfs: annotate fallthrough cases in cvtnum
[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
19 #include "libxfs.h"
20 #include <ctype.h>
21 #ifdef ENABLE_BLKID
22 # include <blkid/blkid.h>
23 #endif /* ENABLE_BLKID */
24 #include "xfs_multidisk.h"
25 #include "libxcmd.h"
26
27 /*
28 * Prototypes for internal functions.
29 */
30 static void conflict(char opt, char *tab[], int oldidx, int newidx);
31 static void illegal(const char *value, const char *opt);
32 static __attribute__((noreturn)) void usage (void);
33 static __attribute__((noreturn)) void reqval(char opt, char *tab[], int idx);
34 static void respec(char opt, char *tab[], int idx);
35 static void unknown(char opt, char *s);
36 static int ispow2(unsigned int i);
37
38 /*
39 * The configured block and sector sizes are defined as global variables so
40 * that they don't need to be passed to functions that require them.
41 */
42 unsigned int blocksize;
43 unsigned int sectorsize;
44
45 #define MAX_SUBOPTS 16
46 #define SUBOPT_NEEDS_VAL (-1LL)
47 #define MAX_CONFLICTS 8
48 #define LAST_CONFLICT (-1)
49
50 /*
51 * Table for parsing mkfs parameters.
52 *
53 * Description of the structure members follows:
54 *
55 * name MANDATORY
56 * Name is a single char, e.g., for '-d file', name is 'd'.
57 *
58 * subopts MANDATORY
59 * Subopts is a list of strings naming suboptions. In the example above,
60 * it would contain "file". The last entry of this list has to be NULL.
61 *
62 * subopt_params MANDATORY
63 * This is a list of structs tied with subopts. For each entry in subopts,
64 * a corresponding entry has to be defined:
65 *
66 * subopt_params struct:
67 * index MANDATORY
68 * This number, starting from zero, denotes which item in subopt_params
69 * it is. The index has to be the same as is the order in subopts list,
70 * so we can access the right item both in subopt_param and subopts.
71 *
72 * seen INTERNAL
73 * Do not set this flag when definning a subopt. It is used to remeber that
74 * this subopt was already seen, for example for conflicts detection.
75 *
76 * str_seen INTERNAL
77 * Do not set. It is used internally for respecification, when some options
78 * has to be parsed twice - at first as a string, then later as a number.
79 *
80 * convert OPTIONAL
81 * A flag signalling whether the user-given value can use suffixes.
82 * If you want to allow the use of user-friendly values like 13k, 42G,
83 * set it to true.
84 *
85 * is_power_2 OPTIONAL
86 * An optional flag for subopts where the given value has to be a power
87 * of two.
88 *
89 * conflicts MANDATORY
90 * If your subopt is in a conflict with some other option, specify it.
91 * Accepts the .index values of the conflicting subopts and the last
92 * member of this list has to be LAST_CONFLICT.
93 *
94 * minval, maxval OPTIONAL
95 * These options are used for automatic range check and they have to be
96 * always used together in pair. If you don't want to limit the max value,
97 * use something like UINT_MAX. If no value is given, then you must either
98 * supply your own validation, or refuse any value in the 'case
99 * X_SOMETHING' block. If you forget to define the min and max value, but
100 * call a standard function for validating user's value, it will cause an
101 * error message notifying you about this issue.
102 *
103 * (Said in another way, you can't have minval and maxval both equal
104 * to zero. But if one value is different: minval=0 and maxval=1,
105 * then it is OK.)
106 *
107 * defaultval MANDATORY
108 * The value used if user specifies the subopt, but no value.
109 * If the subopt accepts some values (-d file=[1|0]), then this
110 * sets what is used with simple specifying the subopt (-d file).
111 * A special SUBOPT_NEEDS_VAL can be used to require a user-given
112 * value in any case.
113 */
114 struct opt_params {
115 const char name;
116 const char *subopts[MAX_SUBOPTS];
117
118 struct subopt_param {
119 int index;
120 bool seen;
121 bool str_seen;
122 bool convert;
123 bool is_power_2;
124 int conflicts[MAX_CONFLICTS];
125 long long minval;
126 long long maxval;
127 long long defaultval;
128 } subopt_params[MAX_SUBOPTS];
129 };
130
131 struct opt_params bopts = {
132 .name = 'b',
133 .subopts = {
134 #define B_LOG 0
135 "log",
136 #define B_SIZE 1
137 "size",
138 NULL
139 },
140 .subopt_params = {
141 { .index = B_LOG,
142 .conflicts = { B_SIZE,
143 LAST_CONFLICT },
144 .minval = XFS_MIN_BLOCKSIZE_LOG,
145 .maxval = XFS_MAX_BLOCKSIZE_LOG,
146 .defaultval = SUBOPT_NEEDS_VAL,
147 },
148 { .index = B_SIZE,
149 .convert = true,
150 .is_power_2 = true,
151 .conflicts = { B_LOG,
152 LAST_CONFLICT },
153 .minval = XFS_MIN_BLOCKSIZE,
154 .maxval = XFS_MAX_BLOCKSIZE,
155 .defaultval = SUBOPT_NEEDS_VAL,
156 },
157 },
158 };
159
160 struct opt_params dopts = {
161 .name = 'd',
162 .subopts = {
163 #define D_AGCOUNT 0
164 "agcount",
165 #define D_FILE 1
166 "file",
167 #define D_NAME 2
168 "name",
169 #define D_SIZE 3
170 "size",
171 #define D_SUNIT 4
172 "sunit",
173 #define D_SWIDTH 5
174 "swidth",
175 #define D_AGSIZE 6
176 "agsize",
177 #define D_SU 7
178 "su",
179 #define D_SW 8
180 "sw",
181 #define D_SECTLOG 9
182 "sectlog",
183 #define D_SECTSIZE 10
184 "sectsize",
185 #define D_NOALIGN 11
186 "noalign",
187 #define D_RTINHERIT 12
188 "rtinherit",
189 #define D_PROJINHERIT 13
190 "projinherit",
191 #define D_EXTSZINHERIT 14
192 "extszinherit",
193 NULL
194 },
195 .subopt_params = {
196 { .index = D_AGCOUNT,
197 .conflicts = { D_AGSIZE,
198 LAST_CONFLICT },
199 .minval = 1,
200 .maxval = XFS_MAX_AGNUMBER,
201 .defaultval = SUBOPT_NEEDS_VAL,
202 },
203 { .index = D_FILE,
204 .conflicts = { LAST_CONFLICT },
205 .minval = 0,
206 .maxval = 1,
207 .defaultval = 1,
208 },
209 { .index = D_NAME,
210 .conflicts = { LAST_CONFLICT },
211 .defaultval = SUBOPT_NEEDS_VAL,
212 },
213 { .index = D_SIZE,
214 .conflicts = { LAST_CONFLICT },
215 .convert = true,
216 .minval = XFS_AG_MIN_BYTES,
217 .maxval = LLONG_MAX,
218 .defaultval = SUBOPT_NEEDS_VAL,
219 },
220 { .index = D_SUNIT,
221 .conflicts = { D_NOALIGN,
222 D_SU,
223 D_SW,
224 LAST_CONFLICT },
225 .minval = 0,
226 .maxval = UINT_MAX,
227 .defaultval = SUBOPT_NEEDS_VAL,
228 },
229 { .index = D_SWIDTH,
230 .conflicts = { D_NOALIGN,
231 D_SU,
232 D_SW,
233 LAST_CONFLICT },
234 .minval = 0,
235 .maxval = UINT_MAX,
236 .defaultval = SUBOPT_NEEDS_VAL,
237 },
238 { .index = D_AGSIZE,
239 .conflicts = { D_AGCOUNT,
240 LAST_CONFLICT },
241 .convert = true,
242 .minval = XFS_AG_MIN_BYTES,
243 .maxval = XFS_AG_MAX_BYTES,
244 .defaultval = SUBOPT_NEEDS_VAL,
245 },
246 { .index = D_SU,
247 .conflicts = { D_NOALIGN,
248 D_SUNIT,
249 D_SWIDTH,
250 LAST_CONFLICT },
251 .convert = true,
252 .minval = 0,
253 .maxval = UINT_MAX,
254 .defaultval = SUBOPT_NEEDS_VAL,
255 },
256 { .index = D_SW,
257 .conflicts = { D_NOALIGN,
258 D_SUNIT,
259 D_SWIDTH,
260 LAST_CONFLICT },
261 .minval = 0,
262 .maxval = UINT_MAX,
263 .defaultval = SUBOPT_NEEDS_VAL,
264 },
265 { .index = D_SECTLOG,
266 .conflicts = { D_SECTSIZE,
267 LAST_CONFLICT },
268 .minval = XFS_MIN_SECTORSIZE_LOG,
269 .maxval = XFS_MAX_SECTORSIZE_LOG,
270 .defaultval = SUBOPT_NEEDS_VAL,
271 },
272 { .index = D_SECTSIZE,
273 .conflicts = { D_SECTLOG,
274 LAST_CONFLICT },
275 .convert = true,
276 .is_power_2 = true,
277 .minval = XFS_MIN_SECTORSIZE,
278 .maxval = XFS_MAX_SECTORSIZE,
279 .defaultval = SUBOPT_NEEDS_VAL,
280 },
281 { .index = D_NOALIGN,
282 .conflicts = { D_SU,
283 D_SW,
284 D_SUNIT,
285 D_SWIDTH,
286 LAST_CONFLICT },
287 .minval = 0,
288 .maxval = 1,
289 .defaultval = 1,
290 },
291 { .index = D_RTINHERIT,
292 .conflicts = { LAST_CONFLICT },
293 .minval = 1,
294 .maxval = 1,
295 .defaultval = 1,
296 },
297 { .index = D_PROJINHERIT,
298 .conflicts = { LAST_CONFLICT },
299 .minval = 0,
300 .maxval = UINT_MAX,
301 .defaultval = SUBOPT_NEEDS_VAL,
302 },
303 { .index = D_EXTSZINHERIT,
304 .conflicts = { LAST_CONFLICT },
305 .minval = 0,
306 .maxval = UINT_MAX,
307 .defaultval = SUBOPT_NEEDS_VAL,
308 },
309 },
310 };
311
312
313 struct opt_params iopts = {
314 .name = 'i',
315 .subopts = {
316 #define I_ALIGN 0
317 "align",
318 #define I_LOG 1
319 "log",
320 #define I_MAXPCT 2
321 "maxpct",
322 #define I_PERBLOCK 3
323 "perblock",
324 #define I_SIZE 4
325 "size",
326 #define I_ATTR 5
327 "attr",
328 #define I_PROJID32BIT 6
329 "projid32bit",
330 #define I_SPINODES 7
331 "sparse",
332 NULL
333 },
334 .subopt_params = {
335 { .index = I_ALIGN,
336 .conflicts = { LAST_CONFLICT },
337 .minval = 0,
338 .maxval = 1,
339 .defaultval = 1,
340 },
341 { .index = I_LOG,
342 .conflicts = { I_PERBLOCK,
343 I_SIZE,
344 LAST_CONFLICT },
345 .minval = XFS_DINODE_MIN_LOG,
346 .maxval = XFS_DINODE_MAX_LOG,
347 .defaultval = SUBOPT_NEEDS_VAL,
348 },
349 { .index = I_MAXPCT,
350 .conflicts = { LAST_CONFLICT },
351 .minval = 0,
352 .maxval = 100,
353 .defaultval = SUBOPT_NEEDS_VAL,
354 },
355 { .index = I_PERBLOCK,
356 .conflicts = { I_LOG,
357 I_SIZE,
358 LAST_CONFLICT },
359 .is_power_2 = true,
360 .minval = XFS_MIN_INODE_PERBLOCK,
361 .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
362 .defaultval = SUBOPT_NEEDS_VAL,
363 },
364 { .index = I_SIZE,
365 .conflicts = { I_PERBLOCK,
366 I_LOG,
367 LAST_CONFLICT },
368 .is_power_2 = true,
369 .minval = XFS_DINODE_MIN_SIZE,
370 .maxval = XFS_DINODE_MAX_SIZE,
371 .defaultval = SUBOPT_NEEDS_VAL,
372 },
373 { .index = I_ATTR,
374 .conflicts = { LAST_CONFLICT },
375 .minval = 0,
376 .maxval = 2,
377 .defaultval = SUBOPT_NEEDS_VAL,
378 },
379 { .index = I_PROJID32BIT,
380 .conflicts = { LAST_CONFLICT },
381 .minval = 0,
382 .maxval = 1,
383 .defaultval = 1,
384 },
385 { .index = I_SPINODES,
386 .conflicts = { LAST_CONFLICT },
387 .minval = 0,
388 .maxval = 1,
389 .defaultval = 1,
390 },
391 },
392 };
393
394 struct opt_params lopts = {
395 .name = 'l',
396 .subopts = {
397 #define L_AGNUM 0
398 "agnum",
399 #define L_INTERNAL 1
400 "internal",
401 #define L_SIZE 2
402 "size",
403 #define L_VERSION 3
404 "version",
405 #define L_SUNIT 4
406 "sunit",
407 #define L_SU 5
408 "su",
409 #define L_DEV 6
410 "logdev",
411 #define L_SECTLOG 7
412 "sectlog",
413 #define L_SECTSIZE 8
414 "sectsize",
415 #define L_FILE 9
416 "file",
417 #define L_NAME 10
418 "name",
419 #define L_LAZYSBCNTR 11
420 "lazy-count",
421 NULL
422 },
423 .subopt_params = {
424 { .index = L_AGNUM,
425 .conflicts = { L_DEV,
426 LAST_CONFLICT },
427 .minval = 0,
428 .maxval = UINT_MAX,
429 .defaultval = SUBOPT_NEEDS_VAL,
430 },
431 { .index = L_INTERNAL,
432 .conflicts = { L_FILE,
433 L_DEV,
434 LAST_CONFLICT },
435 .minval = 0,
436 .maxval = 1,
437 .defaultval = 1,
438 },
439 { .index = L_SIZE,
440 .conflicts = { LAST_CONFLICT },
441 .convert = true,
442 .minval = 2 * 1024 * 1024LL, /* XXX: XFS_MIN_LOG_BYTES */
443 .maxval = XFS_MAX_LOG_BYTES,
444 .defaultval = SUBOPT_NEEDS_VAL,
445 },
446 { .index = L_VERSION,
447 .conflicts = { LAST_CONFLICT },
448 .minval = 1,
449 .maxval = 2,
450 .defaultval = SUBOPT_NEEDS_VAL,
451 },
452 { .index = L_SUNIT,
453 .conflicts = { L_SU,
454 LAST_CONFLICT },
455 .minval = BTOBB(XLOG_MIN_RECORD_BSIZE),
456 .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
457 .defaultval = SUBOPT_NEEDS_VAL,
458 },
459 { .index = L_SU,
460 .conflicts = { L_SUNIT,
461 LAST_CONFLICT },
462 .convert = true,
463 .minval = XLOG_MIN_RECORD_BSIZE,
464 .maxval = XLOG_MAX_RECORD_BSIZE,
465 .defaultval = SUBOPT_NEEDS_VAL,
466 },
467 { .index = L_DEV,
468 .conflicts = { L_AGNUM,
469 L_INTERNAL,
470 LAST_CONFLICT },
471 .defaultval = SUBOPT_NEEDS_VAL,
472 },
473 { .index = L_SECTLOG,
474 .conflicts = { L_SECTSIZE,
475 LAST_CONFLICT },
476 .minval = XFS_MIN_SECTORSIZE_LOG,
477 .maxval = XFS_MAX_SECTORSIZE_LOG,
478 .defaultval = SUBOPT_NEEDS_VAL,
479 },
480 { .index = L_SECTSIZE,
481 .conflicts = { L_SECTLOG,
482 LAST_CONFLICT },
483 .convert = true,
484 .is_power_2 = true,
485 .minval = XFS_MIN_SECTORSIZE,
486 .maxval = XFS_MAX_SECTORSIZE,
487 .defaultval = SUBOPT_NEEDS_VAL,
488 },
489 { .index = L_FILE,
490 .conflicts = { L_INTERNAL,
491 LAST_CONFLICT },
492 .minval = 0,
493 .maxval = 1,
494 .defaultval = 1,
495 },
496 { .index = L_NAME,
497 .conflicts = { L_AGNUM,
498 L_INTERNAL,
499 LAST_CONFLICT },
500 .defaultval = SUBOPT_NEEDS_VAL,
501 },
502 { .index = L_LAZYSBCNTR,
503 .conflicts = { LAST_CONFLICT },
504 .minval = 0,
505 .maxval = 1,
506 .defaultval = 1,
507 },
508 },
509 };
510
511 struct opt_params nopts = {
512 .name = 'n',
513 .subopts = {
514 #define N_LOG 0
515 "log",
516 #define N_SIZE 1
517 "size",
518 #define N_VERSION 2
519 "version",
520 #define N_FTYPE 3
521 "ftype",
522 NULL,
523 },
524 .subopt_params = {
525 { .index = N_LOG,
526 .conflicts = { N_SIZE,
527 LAST_CONFLICT },
528 .minval = XFS_MIN_REC_DIRSIZE,
529 .maxval = XFS_MAX_BLOCKSIZE_LOG,
530 .defaultval = SUBOPT_NEEDS_VAL,
531 },
532 { .index = N_SIZE,
533 .conflicts = { N_LOG,
534 LAST_CONFLICT },
535 .convert = true,
536 .is_power_2 = true,
537 .minval = 1 << XFS_MIN_REC_DIRSIZE,
538 .maxval = XFS_MAX_BLOCKSIZE,
539 .defaultval = SUBOPT_NEEDS_VAL,
540 },
541 { .index = N_VERSION,
542 .conflicts = { LAST_CONFLICT },
543 .minval = 2,
544 .maxval = 2,
545 .defaultval = SUBOPT_NEEDS_VAL,
546 },
547 { .index = N_FTYPE,
548 .conflicts = { LAST_CONFLICT },
549 .minval = 0,
550 .maxval = 1,
551 .defaultval = 1,
552 },
553 },
554 };
555
556 struct opt_params ropts = {
557 .name = 'r',
558 .subopts = {
559 #define R_EXTSIZE 0
560 "extsize",
561 #define R_SIZE 1
562 "size",
563 #define R_DEV 2
564 "rtdev",
565 #define R_FILE 3
566 "file",
567 #define R_NAME 4
568 "name",
569 #define R_NOALIGN 5
570 "noalign",
571 NULL
572 },
573 .subopt_params = {
574 { .index = R_EXTSIZE,
575 .conflicts = { LAST_CONFLICT },
576 .convert = true,
577 .minval = XFS_MIN_RTEXTSIZE,
578 .maxval = XFS_MAX_RTEXTSIZE,
579 .defaultval = SUBOPT_NEEDS_VAL,
580 },
581 { .index = R_SIZE,
582 .conflicts = { LAST_CONFLICT },
583 .convert = true,
584 .minval = 0,
585 .maxval = LLONG_MAX,
586 .defaultval = SUBOPT_NEEDS_VAL,
587 },
588 { .index = R_DEV,
589 .conflicts = { LAST_CONFLICT },
590 .defaultval = SUBOPT_NEEDS_VAL,
591 },
592 { .index = R_FILE,
593 .minval = 0,
594 .maxval = 1,
595 .defaultval = 1,
596 .conflicts = { LAST_CONFLICT },
597 },
598 { .index = R_NAME,
599 .conflicts = { LAST_CONFLICT },
600 .defaultval = SUBOPT_NEEDS_VAL,
601 },
602 { .index = R_NOALIGN,
603 .minval = 0,
604 .maxval = 1,
605 .defaultval = 1,
606 .conflicts = { LAST_CONFLICT },
607 },
608 },
609 };
610
611 struct opt_params sopts = {
612 .name = 's',
613 .subopts = {
614 #define S_LOG 0
615 "log",
616 #define S_SECTLOG 1
617 "sectlog",
618 #define S_SIZE 2
619 "size",
620 #define S_SECTSIZE 3
621 "sectsize",
622 NULL
623 },
624 .subopt_params = {
625 { .index = S_LOG,
626 .conflicts = { S_SIZE,
627 S_SECTSIZE,
628 LAST_CONFLICT },
629 .minval = XFS_MIN_SECTORSIZE_LOG,
630 .maxval = XFS_MAX_SECTORSIZE_LOG,
631 .defaultval = SUBOPT_NEEDS_VAL,
632 },
633 { .index = S_SECTLOG,
634 .conflicts = { S_SIZE,
635 S_SECTSIZE,
636 LAST_CONFLICT },
637 .minval = XFS_MIN_SECTORSIZE_LOG,
638 .maxval = XFS_MAX_SECTORSIZE_LOG,
639 .defaultval = SUBOPT_NEEDS_VAL,
640 },
641 { .index = S_SIZE,
642 .conflicts = { S_LOG,
643 S_SECTLOG,
644 LAST_CONFLICT },
645 .convert = true,
646 .is_power_2 = true,
647 .minval = XFS_MIN_SECTORSIZE,
648 .maxval = XFS_MAX_SECTORSIZE,
649 .defaultval = SUBOPT_NEEDS_VAL,
650 },
651 { .index = S_SECTSIZE,
652 .conflicts = { S_LOG,
653 S_SECTLOG,
654 LAST_CONFLICT },
655 .convert = true,
656 .is_power_2 = true,
657 .minval = XFS_MIN_SECTORSIZE,
658 .maxval = XFS_MAX_SECTORSIZE,
659 .defaultval = SUBOPT_NEEDS_VAL,
660 },
661 },
662 };
663
664 struct opt_params mopts = {
665 .name = 'm',
666 .subopts = {
667 #define M_CRC 0
668 "crc",
669 #define M_FINOBT 1
670 "finobt",
671 #define M_UUID 2
672 "uuid",
673 NULL
674 },
675 .subopt_params = {
676 { .index = M_CRC,
677 .conflicts = { LAST_CONFLICT },
678 .minval = 0,
679 .maxval = 1,
680 .defaultval = 1,
681 },
682 { .index = M_FINOBT,
683 .conflicts = { LAST_CONFLICT },
684 .minval = 0,
685 .maxval = 1,
686 .defaultval = 1,
687 },
688 { .index = M_UUID,
689 .conflicts = { LAST_CONFLICT },
690 .defaultval = SUBOPT_NEEDS_VAL,
691 },
692 },
693 };
694
695 #define TERABYTES(count, blog) ((__uint64_t)(count) << (40 - (blog)))
696 #define GIGABYTES(count, blog) ((__uint64_t)(count) << (30 - (blog)))
697 #define MEGABYTES(count, blog) ((__uint64_t)(count) << (20 - (blog)))
698
699 /*
700 * Use this macro before we have superblock and mount structure
701 */
702 #define DTOBT(d) ((xfs_rfsblock_t)((d) >> (blocklog - BBSHIFT)))
703
704 /*
705 * Use this for block reservations needed for mkfs's conditions
706 * (basically no fragmentation).
707 */
708 #define MKFS_BLOCKRES_INODE \
709 ((uint)(mp->m_ialloc_blks + (mp->m_in_maxlevels - 1)))
710 #define MKFS_BLOCKRES(rb) \
711 ((uint)(MKFS_BLOCKRES_INODE + XFS_DA_NODE_MAXDEPTH + \
712 (XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
713
714 /* amount (in bytes) we zero at the beginning and end of the device to
715 * remove traces of other filesystems, raid superblocks, etc.
716 */
717 #define WHACK_SIZE (128 * 1024)
718
719 static void
720 calc_stripe_factors(
721 int dsu,
722 int dsw,
723 int dsectsz,
724 int lsu,
725 int lsectsz,
726 int *dsunit,
727 int *dswidth,
728 int *lsunit)
729 {
730 /* Handle data sunit/swidth options */
731 if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) {
732 fprintf(stderr,
733 _("both data sunit and data swidth options "
734 "must be specified\n"));
735 usage();
736 }
737
738 if (dsu || dsw) {
739 if ((dsu && !dsw) || (!dsu && dsw)) {
740 fprintf(stderr,
741 _("both data su and data sw options "
742 "must be specified\n"));
743 usage();
744 }
745
746 if (dsu % dsectsz) {
747 fprintf(stderr,
748 _("data su must be a multiple of the "
749 "sector size (%d)\n"), dsectsz);
750 usage();
751 }
752
753 *dsunit = (int)BTOBBT(dsu);
754 *dswidth = *dsunit * dsw;
755 }
756
757 if (*dsunit && (*dswidth % *dsunit != 0)) {
758 fprintf(stderr,
759 _("data stripe width (%d) must be a multiple of the "
760 "data stripe unit (%d)\n"), *dswidth, *dsunit);
761 usage();
762 }
763
764 /* Handle log sunit options */
765
766 if (lsu)
767 *lsunit = (int)BTOBBT(lsu);
768 }
769
770 static void
771 check_device_type(
772 const char *name,
773 int *isfile,
774 bool no_size,
775 bool no_name,
776 int *create,
777 bool force_overwrite,
778 const char *optname)
779 {
780 struct stat64 statbuf;
781
782 if (*isfile && (no_size || no_name)) {
783 fprintf(stderr,
784 _("if -%s file then -%s name and -%s size are required\n"),
785 optname, optname, optname);
786 usage();
787 }
788
789 if (!name) {
790 fprintf(stderr, _("No device name specified\n"));
791 usage();
792 }
793
794 if (stat64(name, &statbuf)) {
795 if (errno == ENOENT && *isfile) {
796 if (create)
797 *create = 1;
798 return;
799 }
800
801 fprintf(stderr,
802 _("Error accessing specified device %s: %s\n"),
803 name, strerror(errno));
804 usage();
805 return;
806 }
807
808 if (!force_overwrite && check_overwrite(name)) {
809 fprintf(stderr,
810 _("%s: Use the -f option to force overwrite.\n"),
811 progname);
812 exit(1);
813 }
814
815 /*
816 * We only want to completely truncate and recreate an existing file if
817 * we were specifically told it was a file. Set the create flag only in
818 * this case to trigger that behaviour.
819 */
820 if (S_ISREG(statbuf.st_mode)) {
821 if (!*isfile)
822 *isfile = 1;
823 else if (create)
824 *create = 1;
825 return;
826 }
827
828 if (S_ISBLK(statbuf.st_mode)) {
829 if (*isfile) {
830 fprintf(stderr,
831 _("specified \"-%s file\" on a block device %s\n"),
832 optname, name);
833 usage();
834 }
835 return;
836 }
837
838 fprintf(stderr,
839 _("specified device %s not a file or block device\n"),
840 name);
841 usage();
842 }
843
844 static void
845 fixup_log_stripe_unit(
846 int lsflag,
847 int sunit,
848 xfs_rfsblock_t *logblocks,
849 int blocklog)
850 {
851 __uint64_t tmp_logblocks;
852
853 /*
854 * Make sure that the log size is a multiple of the stripe unit
855 */
856 if ((*logblocks % sunit) != 0) {
857 if (!lsflag) {
858 tmp_logblocks = ((*logblocks + (sunit - 1))
859 / sunit) * sunit;
860 /*
861 * If the log is too large, round down
862 * instead of round up
863 */
864 if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) ||
865 ((tmp_logblocks << blocklog) > XFS_MAX_LOG_BYTES)) {
866 tmp_logblocks = (*logblocks / sunit) * sunit;
867 }
868 *logblocks = tmp_logblocks;
869 } else {
870 fprintf(stderr, _("log size %lld is not a multiple "
871 "of the log stripe unit %d\n"),
872 (long long) *logblocks, sunit);
873 usage();
874 }
875 }
876 }
877
878 static xfs_fsblock_t
879 fixup_internal_log_stripe(
880 xfs_mount_t *mp,
881 int lsflag,
882 xfs_fsblock_t logstart,
883 __uint64_t agsize,
884 int sunit,
885 xfs_rfsblock_t *logblocks,
886 int blocklog,
887 int *lalign)
888 {
889 if ((logstart % sunit) != 0) {
890 logstart = ((logstart + (sunit - 1))/sunit) * sunit;
891 *lalign = 1;
892 }
893
894 fixup_log_stripe_unit(lsflag, sunit, logblocks, blocklog);
895
896 if (*logblocks > agsize - XFS_FSB_TO_AGBNO(mp, logstart)) {
897 fprintf(stderr,
898 _("Due to stripe alignment, the internal log size "
899 "(%lld) is too large.\n"), (long long) *logblocks);
900 fprintf(stderr, _("Must fit within an allocation group.\n"));
901 usage();
902 }
903 return logstart;
904 }
905
906 void
907 validate_log_size(__uint64_t logblocks, int blocklog, int min_logblocks)
908 {
909 if (logblocks < min_logblocks) {
910 fprintf(stderr,
911 _("log size %lld blocks too small, minimum size is %d blocks\n"),
912 (long long)logblocks, min_logblocks);
913 usage();
914 }
915 if (logblocks > XFS_MAX_LOG_BLOCKS) {
916 fprintf(stderr,
917 _("log size %lld blocks too large, maximum size is %lld blocks\n"),
918 (long long)logblocks, XFS_MAX_LOG_BLOCKS);
919 usage();
920 }
921 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
922 fprintf(stderr,
923 _("log size %lld bytes too large, maximum size is %lld bytes\n"),
924 (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES);
925 usage();
926 }
927 }
928
929 static int
930 calc_default_imaxpct(
931 int blocklog,
932 __uint64_t dblocks)
933 {
934 /*
935 * This returns the % of the disk space that is used for
936 * inodes, it changes relatively to the FS size:
937 * - over 50 TB, use 1%,
938 * - 1TB - 50 TB, use 5%,
939 * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%).
940 */
941
942 if (dblocks < TERABYTES(1, blocklog)) {
943 return XFS_DFL_IMAXIMUM_PCT;
944 } else if (dblocks < TERABYTES(50, blocklog)) {
945 return 5;
946 }
947
948 return 1;
949 }
950
951 static void
952 validate_ag_geometry(
953 int blocklog,
954 __uint64_t dblocks,
955 __uint64_t agsize,
956 __uint64_t agcount)
957 {
958 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
959 fprintf(stderr,
960 _("agsize (%lld blocks) too small, need at least %lld blocks\n"),
961 (long long)agsize,
962 (long long)XFS_AG_MIN_BLOCKS(blocklog));
963 usage();
964 }
965
966 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
967 fprintf(stderr,
968 _("agsize (%lld blocks) too big, maximum is %lld blocks\n"),
969 (long long)agsize,
970 (long long)XFS_AG_MAX_BLOCKS(blocklog));
971 usage();
972 }
973
974 if (agsize > dblocks) {
975 fprintf(stderr,
976 _("agsize (%lld blocks) too big, data area is %lld blocks\n"),
977 (long long)agsize, (long long)dblocks);
978 usage();
979 }
980
981 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
982 fprintf(stderr,
983 _("too many allocation groups for size = %lld\n"),
984 (long long)agsize);
985 fprintf(stderr, _("need at most %lld allocation groups\n"),
986 (long long)(dblocks / XFS_AG_MIN_BLOCKS(blocklog) +
987 (dblocks % XFS_AG_MIN_BLOCKS(blocklog) != 0)));
988 usage();
989 }
990
991 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
992 fprintf(stderr,
993 _("too few allocation groups for size = %lld\n"), (long long)agsize);
994 fprintf(stderr,
995 _("need at least %lld allocation groups\n"),
996 (long long)(dblocks / XFS_AG_MAX_BLOCKS(blocklog) +
997 (dblocks % XFS_AG_MAX_BLOCKS(blocklog) != 0)));
998 usage();
999 }
1000
1001 /*
1002 * If the last AG is too small, reduce the filesystem size
1003 * and drop the blocks.
1004 */
1005 if ( dblocks % agsize != 0 &&
1006 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
1007 fprintf(stderr,
1008 _("last AG size %lld blocks too small, minimum size is %lld blocks\n"),
1009 (long long)(dblocks % agsize),
1010 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1011 usage();
1012 }
1013
1014 /*
1015 * If agcount is too large, make it smaller.
1016 */
1017 if (agcount > XFS_MAX_AGNUMBER + 1) {
1018 fprintf(stderr,
1019 _("%lld allocation groups is too many, maximum is %lld\n"),
1020 (long long)agcount, (long long)XFS_MAX_AGNUMBER + 1);
1021 usage();
1022 }
1023 }
1024
1025 static void
1026 zero_old_xfs_structures(
1027 libxfs_init_t *xi,
1028 xfs_sb_t *new_sb)
1029 {
1030 void *buf;
1031 xfs_sb_t sb;
1032 __uint32_t bsize;
1033 int i;
1034 xfs_off_t off;
1035
1036 /*
1037 * We open regular files with O_TRUNC|O_CREAT. Nothing to do here...
1038 */
1039 if (xi->disfile && xi->dcreat)
1040 return;
1041
1042 /*
1043 * read in existing filesystem superblock, use its geometry
1044 * settings and zero the existing secondary superblocks.
1045 */
1046 buf = memalign(libxfs_device_alignment(), new_sb->sb_sectsize);
1047 if (!buf) {
1048 fprintf(stderr,
1049 _("error reading existing superblock -- failed to memalign buffer\n"));
1050 return;
1051 }
1052 memset(buf, 0, new_sb->sb_sectsize);
1053
1054 /*
1055 * If we are creating an image file, it might be of zero length at this
1056 * point in time. Hence reading the existing superblock is going to
1057 * return zero bytes. It's not a failure we need to warn about in this
1058 * case.
1059 */
1060 off = pread(xi->dfd, buf, new_sb->sb_sectsize, 0);
1061 if (off != new_sb->sb_sectsize) {
1062 if (!xi->disfile)
1063 fprintf(stderr,
1064 _("error reading existing superblock: %s\n"),
1065 strerror(errno));
1066 goto done;
1067 }
1068 libxfs_sb_from_disk(&sb, buf);
1069
1070 /*
1071 * perform same basic superblock validation to make sure we
1072 * actually zero secondary blocks
1073 */
1074 if (sb.sb_magicnum != XFS_SB_MAGIC || sb.sb_blocksize == 0)
1075 goto done;
1076
1077 for (bsize = 1, i = 0; bsize < sb.sb_blocksize &&
1078 i < sizeof(sb.sb_blocksize) * NBBY; i++)
1079 bsize <<= 1;
1080
1081 if (i < XFS_MIN_BLOCKSIZE_LOG || i > XFS_MAX_BLOCKSIZE_LOG ||
1082 i != sb.sb_blocklog)
1083 goto done;
1084
1085 if (sb.sb_dblocks > ((__uint64_t)sb.sb_agcount * sb.sb_agblocks) ||
1086 sb.sb_dblocks < ((__uint64_t)(sb.sb_agcount - 1) *
1087 sb.sb_agblocks + XFS_MIN_AG_BLOCKS))
1088 goto done;
1089
1090 /*
1091 * block size and basic geometry seems alright, zero the secondaries.
1092 */
1093 memset(buf, 0, new_sb->sb_sectsize);
1094 off = 0;
1095 for (i = 1; i < sb.sb_agcount; i++) {
1096 off += sb.sb_agblocks;
1097 if (pwrite64(xi->dfd, buf, new_sb->sb_sectsize,
1098 off << sb.sb_blocklog) == -1)
1099 break;
1100 }
1101 done:
1102 free(buf);
1103 }
1104
1105 static void
1106 discard_blocks(dev_t dev, __uint64_t nsectors)
1107 {
1108 int fd;
1109
1110 /*
1111 * We intentionally ignore errors from the discard ioctl. It is
1112 * not necessary for the mkfs functionality but just an optimization.
1113 */
1114 fd = libxfs_device_to_fd(dev);
1115 if (fd > 0)
1116 platform_discard_blocks(fd, 0, nsectors << 9);
1117 }
1118
1119 struct sb_feat_args {
1120 int log_version;
1121 int attr_version;
1122 int dir_version;
1123 int spinodes;
1124 int finobt;
1125 bool inode_align;
1126 bool nci;
1127 bool lazy_sb_counters;
1128 bool projid16bit;
1129 bool crcs_enabled;
1130 bool dirftype;
1131 bool parent_pointers;
1132 };
1133
1134 static void
1135 sb_set_features(
1136 struct xfs_sb *sbp,
1137 struct sb_feat_args *fp,
1138 int sectsize,
1139 int lsectsize,
1140 int dsunit)
1141 {
1142
1143 sbp->sb_versionnum = XFS_DFL_SB_VERSION_BITS;
1144 if (fp->crcs_enabled)
1145 sbp->sb_versionnum |= XFS_SB_VERSION_5;
1146 else
1147 sbp->sb_versionnum |= XFS_SB_VERSION_4;
1148
1149 if (fp->inode_align)
1150 sbp->sb_versionnum |= XFS_SB_VERSION_ALIGNBIT;
1151 if (dsunit)
1152 sbp->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT;
1153 if (fp->log_version == 2)
1154 sbp->sb_versionnum |= XFS_SB_VERSION_LOGV2BIT;
1155 if (fp->attr_version == 1)
1156 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
1157 if (sectsize > BBSIZE || lsectsize > BBSIZE)
1158 sbp->sb_versionnum |= XFS_SB_VERSION_SECTORBIT;
1159 if (fp->nci)
1160 sbp->sb_versionnum |= XFS_SB_VERSION_BORGBIT;
1161
1162
1163 sbp->sb_features2 = 0;
1164 if (fp->lazy_sb_counters)
1165 sbp->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
1166 if (!fp->projid16bit)
1167 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
1168 if (fp->parent_pointers)
1169 sbp->sb_features2 |= XFS_SB_VERSION2_PARENTBIT;
1170 if (fp->crcs_enabled)
1171 sbp->sb_features2 |= XFS_SB_VERSION2_CRCBIT;
1172 if (fp->attr_version == 2)
1173 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
1174
1175 /* v5 superblocks have their own feature bit for dirftype */
1176 if (fp->dirftype && !fp->crcs_enabled)
1177 sbp->sb_features2 |= XFS_SB_VERSION2_FTYPE;
1178
1179 /* update whether extended features are in use */
1180 if (sbp->sb_features2 != 0)
1181 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
1182
1183 /*
1184 * Due to a structure alignment issue, sb_features2 ended up in one
1185 * of two locations, the second "incorrect" location represented by
1186 * the sb_bad_features2 field. To avoid older kernels mounting
1187 * filesystems they shouldn't, set both field to the same value.
1188 */
1189 sbp->sb_bad_features2 = sbp->sb_features2;
1190
1191 if (!fp->crcs_enabled)
1192 return;
1193
1194 /* default features for v5 filesystems */
1195 sbp->sb_features_compat = 0;
1196 sbp->sb_features_ro_compat = 0;
1197 sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE;
1198 sbp->sb_features_log_incompat = 0;
1199
1200 if (fp->finobt)
1201 sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT;
1202
1203 /*
1204 * Sparse inode chunk support has two main inode alignment requirements.
1205 * First, sparse chunk alignment must match the cluster size. Second,
1206 * full chunk alignment must match the inode chunk size.
1207 *
1208 * Copy the already calculated/scaled inoalignmt to spino_align and
1209 * update the former to the full inode chunk size.
1210 */
1211 if (fp->spinodes) {
1212 sbp->sb_spino_align = sbp->sb_inoalignmt;
1213 sbp->sb_inoalignmt = XFS_INODES_PER_CHUNK *
1214 sbp->sb_inodesize >> sbp->sb_blocklog;
1215 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
1216 }
1217
1218 }
1219
1220 static __attribute__((noreturn)) void
1221 illegal_option(
1222 const char *value,
1223 struct opt_params *opts,
1224 int index,
1225 const char *reason)
1226 {
1227 fprintf(stderr,
1228 _("Illegal value %s for -%c %s option. %s\n"),
1229 value, opts->name, opts->subopts[index],
1230 reason ? reason : "");
1231 usage();
1232 }
1233
1234 /*
1235 * Check for conflicts and option respecification.
1236 */
1237 static void
1238 check_opt(
1239 struct opt_params *opts,
1240 int index,
1241 bool str_seen)
1242 {
1243 struct subopt_param *sp = &opts->subopt_params[index];
1244 int i;
1245
1246 if (sp->index != index) {
1247 fprintf(stderr,
1248 ("Developer screwed up option parsing (%d/%d)! Please report!\n"),
1249 sp->index, index);
1250 reqval(opts->name, (char **)opts->subopts, index);
1251 }
1252
1253 /*
1254 * Check for respecification of the option. This is more complex than it
1255 * seems because some options are parsed twice - once as a string during
1256 * input parsing, then later the string is passed to getnum for
1257 * conversion into a number and bounds checking. Hence the two variables
1258 * used to track the different uses based on the @str parameter passed
1259 * to us.
1260 */
1261 if (!str_seen) {
1262 if (sp->seen)
1263 respec(opts->name, (char **)opts->subopts, index);
1264 sp->seen = true;
1265 } else {
1266 if (sp->str_seen)
1267 respec(opts->name, (char **)opts->subopts, index);
1268 sp->str_seen = true;
1269 }
1270
1271 /* check for conflicts with the option */
1272 for (i = 0; i < MAX_CONFLICTS; i++) {
1273 int conflict_opt = sp->conflicts[i];
1274
1275 if (conflict_opt == LAST_CONFLICT)
1276 break;
1277 if (opts->subopt_params[conflict_opt].seen ||
1278 opts->subopt_params[conflict_opt].str_seen)
1279 conflict(opts->name, (char **)opts->subopts,
1280 conflict_opt, index);
1281 }
1282 }
1283
1284 static long long
1285 getnum(
1286 const char *str,
1287 struct opt_params *opts,
1288 int index)
1289 {
1290 struct subopt_param *sp = &opts->subopt_params[index];
1291 long long c;
1292
1293 check_opt(opts, index, false);
1294 /* empty strings might just return a default value */
1295 if (!str || *str == '\0') {
1296 if (sp->defaultval == SUBOPT_NEEDS_VAL)
1297 reqval(opts->name, (char **)opts->subopts, index);
1298 return sp->defaultval;
1299 }
1300
1301 if (sp->minval == 0 && sp->maxval == 0) {
1302 fprintf(stderr,
1303 _("Option -%c %s has undefined minval/maxval."
1304 "Can't verify value range. This is a bug.\n"),
1305 opts->name, opts->subopts[index]);
1306 exit(1);
1307 }
1308
1309 /*
1310 * Some values are pure numbers, others can have suffixes that define
1311 * the units of the number. Those get passed to cvtnum(), otherwise we
1312 * convert it ourselves to guarantee there is no trailing garbage in the
1313 * number.
1314 */
1315 if (sp->convert)
1316 c = cvtnum(blocksize, sectorsize, str);
1317 else {
1318 char *str_end;
1319
1320 c = strtoll(str, &str_end, 0);
1321 if (c == 0 && str_end == str)
1322 illegal_option(str, opts, index, NULL);
1323 if (*str_end != '\0')
1324 illegal_option(str, opts, index, NULL);
1325 }
1326
1327 /* Validity check the result. */
1328 if (c < sp->minval)
1329 illegal_option(str, opts, index, _("value is too small"));
1330 else if (c > sp->maxval)
1331 illegal_option(str, opts, index, _("value is too large"));
1332 if (sp->is_power_2 && !ispow2(c))
1333 illegal_option(str, opts, index, _("value must be a power of 2"));
1334 return c;
1335 }
1336
1337 /*
1338 * Option is a string - do all the option table work, and check there
1339 * is actually an option string. Otherwise we don't do anything with the string
1340 * here - validation will be done later when the string is converted to a value
1341 * or used as a file/device path.
1342 */
1343 static char *
1344 getstr(
1345 char *str,
1346 struct opt_params *opts,
1347 int index)
1348 {
1349 check_opt(opts, index, true);
1350
1351 /* empty strings for string options are not valid */
1352 if (!str || *str == '\0')
1353 reqval(opts->name, (char **)opts->subopts, index);
1354 return str;
1355 }
1356
1357 int
1358 main(
1359 int argc,
1360 char **argv)
1361 {
1362 __uint64_t agcount;
1363 xfs_agf_t *agf;
1364 xfs_agi_t *agi;
1365 xfs_agnumber_t agno;
1366 __uint64_t agsize;
1367 xfs_alloc_rec_t *arec;
1368 struct xfs_btree_block *block;
1369 int blflag;
1370 int blocklog;
1371 int bsflag;
1372 int bsize;
1373 xfs_buf_t *buf;
1374 int c;
1375 int daflag;
1376 int dasize;
1377 xfs_rfsblock_t dblocks;
1378 char *dfile;
1379 int dirblocklog;
1380 int dirblocksize;
1381 char *dsize;
1382 int dsu;
1383 int dsw;
1384 int dsunit;
1385 int dswidth;
1386 int force_overwrite;
1387 struct fsxattr fsx;
1388 int ilflag;
1389 int imaxpct;
1390 int imflag;
1391 int inodelog;
1392 int inopblock;
1393 int ipflag;
1394 int isflag;
1395 int isize;
1396 char *label = NULL;
1397 int laflag;
1398 int lalign;
1399 int ldflag;
1400 int liflag;
1401 xfs_agnumber_t logagno;
1402 xfs_rfsblock_t logblocks;
1403 char *logfile;
1404 int loginternal;
1405 char *logsize;
1406 xfs_fsblock_t logstart;
1407 int lvflag;
1408 int lsflag;
1409 int lsuflag;
1410 int lsunitflag;
1411 int lsectorlog;
1412 int lsectorsize;
1413 int lslflag;
1414 int lssflag;
1415 int lsu;
1416 int lsunit;
1417 int min_logblocks;
1418 xfs_mount_t *mp;
1419 xfs_mount_t mbuf;
1420 xfs_extlen_t nbmblocks;
1421 int nlflag;
1422 int nodsflag;
1423 int norsflag;
1424 xfs_alloc_rec_t *nrec;
1425 int nsflag;
1426 int nvflag;
1427 int Nflag;
1428 int discard = 1;
1429 char *p;
1430 char *protofile;
1431 char *protostring;
1432 int qflag;
1433 xfs_rfsblock_t rtblocks;
1434 xfs_extlen_t rtextblocks;
1435 xfs_rtblock_t rtextents;
1436 char *rtextsize;
1437 char *rtfile;
1438 char *rtsize;
1439 xfs_sb_t *sbp;
1440 int sectorlog;
1441 __uint64_t sector_mask;
1442 int slflag;
1443 int ssflag;
1444 __uint64_t tmp_agsize;
1445 uuid_t uuid;
1446 int worst_freelist;
1447 libxfs_init_t xi;
1448 struct fs_topology ft;
1449 struct sb_feat_args sb_feat = {
1450 .finobt = 1,
1451 .spinodes = 0,
1452 .log_version = 2,
1453 .attr_version = 2,
1454 .dir_version = XFS_DFL_DIR_VERSION,
1455 .inode_align = XFS_IFLAG_ALIGN,
1456 .nci = false,
1457 .lazy_sb_counters = true,
1458 .projid16bit = false,
1459 .crcs_enabled = true,
1460 .dirftype = true,
1461 .parent_pointers = false,
1462 };
1463
1464 platform_uuid_generate(&uuid);
1465 progname = basename(argv[0]);
1466 setlocale(LC_ALL, "");
1467 bindtextdomain(PACKAGE, LOCALEDIR);
1468 textdomain(PACKAGE);
1469
1470 blflag = bsflag = slflag = ssflag = lslflag = lssflag = 0;
1471 blocklog = blocksize = 0;
1472 sectorlog = lsectorlog = 0;
1473 sectorsize = lsectorsize = 0;
1474 agsize = daflag = dasize = dblocks = 0;
1475 ilflag = imflag = ipflag = isflag = 0;
1476 liflag = laflag = lsflag = lsuflag = lsunitflag = ldflag = lvflag = 0;
1477 loginternal = 1;
1478 logagno = logblocks = rtblocks = rtextblocks = 0;
1479 Nflag = nlflag = nsflag = nvflag = 0;
1480 dirblocklog = dirblocksize = 0;
1481 qflag = 0;
1482 imaxpct = inodelog = inopblock = isize = 0;
1483 dfile = logfile = rtfile = NULL;
1484 dsize = logsize = rtsize = rtextsize = protofile = NULL;
1485 dsu = dsw = dsunit = dswidth = lalign = lsu = lsunit = 0;
1486 nodsflag = norsflag = 0;
1487 force_overwrite = 0;
1488 worst_freelist = 0;
1489 memset(&fsx, 0, sizeof(fsx));
1490
1491 memset(&xi, 0, sizeof(xi));
1492 xi.isdirect = LIBXFS_DIRECT;
1493 xi.isreadonly = LIBXFS_EXCLUSIVELY;
1494
1495 while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
1496 switch (c) {
1497 case 'C':
1498 case 'f':
1499 force_overwrite = 1;
1500 break;
1501 case 'b':
1502 p = optarg;
1503 while (*p != '\0') {
1504 char **subopts = (char **)bopts.subopts;
1505 char *value;
1506
1507 switch (getsubopt(&p, (constpp)subopts,
1508 &value)) {
1509 case B_LOG:
1510 blocklog = getnum(value, &bopts, B_LOG);
1511 blocksize = 1 << blocklog;
1512 blflag = 1;
1513 break;
1514 case B_SIZE:
1515 blocksize = getnum(value, &bopts,
1516 B_SIZE);
1517 blocklog = libxfs_highbit32(blocksize);
1518 bsflag = 1;
1519 break;
1520 default:
1521 unknown('b', value);
1522 }
1523 }
1524 break;
1525 case 'd':
1526 p = optarg;
1527 while (*p != '\0') {
1528 char **subopts = (char **)dopts.subopts;
1529 char *value;
1530
1531 switch (getsubopt(&p, (constpp)subopts,
1532 &value)) {
1533 case D_AGCOUNT:
1534 agcount = getnum(value, &dopts,
1535 D_AGCOUNT);
1536 daflag = 1;
1537 break;
1538 case D_AGSIZE:
1539 agsize = getnum(value, &dopts, D_AGSIZE);
1540 dasize = 1;
1541 break;
1542 case D_FILE:
1543 xi.disfile = getnum(value, &dopts,
1544 D_FILE);
1545 break;
1546 case D_NAME:
1547 xi.dname = getstr(value, &dopts, D_NAME);
1548 break;
1549 case D_SIZE:
1550 dsize = getstr(value, &dopts, D_SIZE);
1551 break;
1552 case D_SUNIT:
1553 dsunit = getnum(value, &dopts, D_SUNIT);
1554 break;
1555 case D_SWIDTH:
1556 dswidth = getnum(value, &dopts,
1557 D_SWIDTH);
1558 break;
1559 case D_SU:
1560 dsu = getnum(value, &dopts, D_SU);
1561 break;
1562 case D_SW:
1563 dsw = getnum(value, &dopts, D_SW);
1564 break;
1565 case D_NOALIGN:
1566 nodsflag = getnum(value, &dopts,
1567 D_NOALIGN);
1568 break;
1569 case D_SECTLOG:
1570 sectorlog = getnum(value, &dopts,
1571 D_SECTLOG);
1572 sectorsize = 1 << sectorlog;
1573 slflag = 1;
1574 break;
1575 case D_SECTSIZE:
1576 sectorsize = getnum(value, &dopts,
1577 D_SECTSIZE);
1578 sectorlog =
1579 libxfs_highbit32(sectorsize);
1580 ssflag = 1;
1581 break;
1582 case D_RTINHERIT:
1583 c = getnum(value, &dopts, D_RTINHERIT);
1584 if (c)
1585 fsx.fsx_xflags |=
1586 XFS_DIFLAG_RTINHERIT;
1587 break;
1588 case D_PROJINHERIT:
1589 fsx.fsx_projid = getnum(value, &dopts,
1590 D_PROJINHERIT);
1591 fsx.fsx_xflags |=
1592 XFS_DIFLAG_PROJINHERIT;
1593 break;
1594 case D_EXTSZINHERIT:
1595 fsx.fsx_extsize = getnum(value, &dopts,
1596 D_EXTSZINHERIT);
1597 fsx.fsx_xflags |=
1598 XFS_DIFLAG_EXTSZINHERIT;
1599 break;
1600 default:
1601 unknown('d', value);
1602 }
1603 }
1604 break;
1605 case 'i':
1606 p = optarg;
1607 while (*p != '\0') {
1608 char **subopts = (char **)iopts.subopts;
1609 char *value;
1610
1611 switch (getsubopt(&p, (constpp)subopts,
1612 &value)) {
1613 case I_ALIGN:
1614 sb_feat.inode_align = getnum(value,
1615 &iopts, I_ALIGN);
1616 break;
1617 case I_LOG:
1618 inodelog = getnum(value, &iopts, I_LOG);
1619 isize = 1 << inodelog;
1620 ilflag = 1;
1621 break;
1622 case I_MAXPCT:
1623 imaxpct = getnum(value, &iopts,
1624 I_MAXPCT);
1625 imflag = 1;
1626 break;
1627 case I_PERBLOCK:
1628 inopblock = getnum(value, &iopts,
1629 I_PERBLOCK);
1630 ipflag = 1;
1631 break;
1632 case I_SIZE:
1633 isize = getnum(value, &iopts, I_SIZE);
1634 inodelog = libxfs_highbit32(isize);
1635 isflag = 1;
1636 break;
1637 case I_ATTR:
1638 sb_feat.attr_version =
1639 getnum(value, &iopts, I_ATTR);
1640 break;
1641 case I_PROJID32BIT:
1642 sb_feat.projid16bit =
1643 !getnum(value, &iopts,
1644 I_PROJID32BIT);
1645 break;
1646 case I_SPINODES:
1647 sb_feat.spinodes = getnum(value,
1648 &iopts, I_SPINODES);
1649 break;
1650 default:
1651 unknown('i', value);
1652 }
1653 }
1654 break;
1655 case 'l':
1656 p = optarg;
1657 while (*p != '\0') {
1658 char **subopts = (char **)lopts.subopts;
1659 char *value;
1660
1661 switch (getsubopt(&p, (constpp)subopts,
1662 &value)) {
1663 case L_AGNUM:
1664 logagno = getnum(value, &lopts, L_AGNUM);
1665 laflag = 1;
1666 break;
1667 case L_FILE:
1668 xi.lisfile = getnum(value, &lopts,
1669 L_FILE);
1670 break;
1671 case L_INTERNAL:
1672 loginternal = getnum(value, &lopts,
1673 L_INTERNAL);
1674 liflag = 1;
1675 break;
1676 case L_SU:
1677 lsu = getnum(value, &lopts, L_SU);
1678 lsuflag = 1;
1679 break;
1680 case L_SUNIT:
1681 lsunit = getnum(value, &lopts, L_SUNIT);
1682 lsunitflag = 1;
1683 break;
1684 case L_NAME:
1685 case L_DEV:
1686 logfile = getstr(value, &lopts, L_NAME);
1687 xi.logname = logfile;
1688 ldflag = 1;
1689 loginternal = 0;
1690 break;
1691 case L_VERSION:
1692 sb_feat.log_version =
1693 getnum(value, &lopts, L_VERSION);
1694 lvflag = 1;
1695 break;
1696 case L_SIZE:
1697 logsize = getstr(value, &lopts, L_SIZE);
1698 break;
1699 case L_SECTLOG:
1700 lsectorlog = getnum(value, &lopts,
1701 L_SECTLOG);
1702 lsectorsize = 1 << lsectorlog;
1703 lslflag = 1;
1704 break;
1705 case L_SECTSIZE:
1706 lsectorsize = getnum(value, &lopts,
1707 L_SECTSIZE);
1708 lsectorlog =
1709 libxfs_highbit32(lsectorsize);
1710 lssflag = 1;
1711 break;
1712 case L_LAZYSBCNTR:
1713 sb_feat.lazy_sb_counters =
1714 getnum(value, &lopts,
1715 L_LAZYSBCNTR);
1716 break;
1717 default:
1718 unknown('l', value);
1719 }
1720 }
1721 break;
1722 case 'L':
1723 if (strlen(optarg) > sizeof(sbp->sb_fname))
1724 illegal(optarg, "L");
1725 label = optarg;
1726 break;
1727 case 'm':
1728 p = optarg;
1729 while (*p != '\0') {
1730 char **subopts = (char **)mopts.subopts;
1731 char *value;
1732
1733 switch (getsubopt(&p, (constpp)subopts,
1734 &value)) {
1735 case M_CRC:
1736 sb_feat.crcs_enabled =
1737 getnum(value, &mopts, M_CRC);
1738 if (sb_feat.crcs_enabled)
1739 sb_feat.dirftype = true;
1740 break;
1741 case M_FINOBT:
1742 sb_feat.finobt = getnum(
1743 value, &mopts, M_FINOBT);
1744 break;
1745 case M_UUID:
1746 if (!value || *value == '\0')
1747 reqval('m', subopts, M_UUID);
1748 if (platform_uuid_parse(value, &uuid))
1749 illegal(optarg, "m uuid");
1750 break;
1751 default:
1752 unknown('m', value);
1753 }
1754 }
1755 break;
1756 case 'n':
1757 p = optarg;
1758 while (*p != '\0') {
1759 char **subopts = (char **)nopts.subopts;
1760 char *value;
1761
1762 switch (getsubopt(&p, (constpp)subopts,
1763 &value)) {
1764 case N_LOG:
1765 dirblocklog = getnum(value, &nopts,
1766 N_LOG);
1767 dirblocksize = 1 << dirblocklog;
1768 nlflag = 1;
1769 break;
1770 case N_SIZE:
1771 dirblocksize = getnum(value, &nopts,
1772 N_SIZE);
1773 dirblocklog =
1774 libxfs_highbit32(dirblocksize);
1775 nsflag = 1;
1776 break;
1777 case N_VERSION:
1778 value = getstr(value, &nopts, N_VERSION);
1779 if (!strcasecmp(value, "ci")) {
1780 /* ASCII CI mode */
1781 sb_feat.nci = true;
1782 } else {
1783 sb_feat.dir_version =
1784 getnum(value, &nopts,
1785 N_VERSION);
1786 }
1787 nvflag = 1;
1788 break;
1789 case N_FTYPE:
1790 sb_feat.dirftype = getnum(value, &nopts,
1791 N_FTYPE);
1792 break;
1793 default:
1794 unknown('n', value);
1795 }
1796 }
1797 break;
1798 case 'N':
1799 Nflag = 1;
1800 break;
1801 case 'K':
1802 discard = 0;
1803 break;
1804 case 'p':
1805 if (protofile)
1806 respec('p', NULL, 0);
1807 protofile = optarg;
1808 break;
1809 case 'q':
1810 qflag = 1;
1811 break;
1812 case 'r':
1813 p = optarg;
1814 while (*p != '\0') {
1815 char **subopts = (char **)ropts.subopts;
1816 char *value;
1817
1818 switch (getsubopt(&p, (constpp)subopts,
1819 &value)) {
1820 case R_EXTSIZE:
1821 rtextsize = getstr(value, &ropts,
1822 R_EXTSIZE);
1823 break;
1824 case R_FILE:
1825 xi.risfile = getnum(value, &ropts,
1826 R_FILE);
1827 break;
1828 case R_NAME:
1829 case R_DEV:
1830 xi.rtname = getstr(value, &ropts,
1831 R_NAME);
1832 break;
1833 case R_SIZE:
1834 rtsize = getstr(value, &ropts, R_SIZE);
1835 break;
1836 case R_NOALIGN:
1837 norsflag = getnum(value, &ropts,
1838 R_NOALIGN);
1839 break;
1840 default:
1841 unknown('r', value);
1842 }
1843 }
1844 break;
1845 case 's':
1846 p = optarg;
1847 while (*p != '\0') {
1848 char **subopts = (char **)sopts.subopts;
1849 char *value;
1850
1851 switch (getsubopt(&p, (constpp)subopts,
1852 &value)) {
1853 case S_LOG:
1854 case S_SECTLOG:
1855 if (lssflag)
1856 conflict('s', subopts,
1857 S_SECTSIZE, S_SECTLOG);
1858 sectorlog = getnum(value, &sopts,
1859 S_SECTLOG);
1860 lsectorlog = sectorlog;
1861 sectorsize = 1 << sectorlog;
1862 lsectorsize = sectorsize;
1863 lslflag = slflag = 1;
1864 break;
1865 case S_SIZE:
1866 case S_SECTSIZE:
1867 if (lslflag)
1868 conflict('s', subopts, S_SECTLOG,
1869 S_SECTSIZE);
1870 sectorsize = getnum(value, &sopts,
1871 S_SECTSIZE);
1872 lsectorsize = sectorsize;
1873 sectorlog =
1874 libxfs_highbit32(sectorsize);
1875 lsectorlog = sectorlog;
1876 lssflag = ssflag = 1;
1877 break;
1878 default:
1879 unknown('s', value);
1880 }
1881 }
1882 break;
1883 case 'V':
1884 printf(_("%s version %s\n"), progname, VERSION);
1885 exit(0);
1886 case '?':
1887 unknown(optopt, "");
1888 }
1889 }
1890 if (argc - optind > 1) {
1891 fprintf(stderr, _("extra arguments\n"));
1892 usage();
1893 } else if (argc - optind == 1) {
1894 dfile = xi.volname = getstr(argv[optind], &dopts, D_NAME);
1895 } else
1896 dfile = xi.dname;
1897
1898 /*
1899 * Blocksize and sectorsize first, other things depend on them
1900 * For RAID4/5/6 we want to align sector size and block size,
1901 * so we need to start with the device geometry extraction too.
1902 */
1903 if (!blflag && !bsflag) {
1904 blocklog = XFS_DFL_BLOCKSIZE_LOG;
1905 blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG;
1906 }
1907 if (blocksize < XFS_MIN_BLOCKSIZE || blocksize > XFS_MAX_BLOCKSIZE) {
1908 fprintf(stderr, _("illegal block size %d\n"), blocksize);
1909 usage();
1910 }
1911 if (sb_feat.crcs_enabled && blocksize < XFS_MIN_CRC_BLOCKSIZE) {
1912 fprintf(stderr,
1913 _("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
1914 XFS_MIN_CRC_BLOCKSIZE);
1915 usage();
1916 }
1917 if (sb_feat.crcs_enabled && !sb_feat.dirftype) {
1918 fprintf(stderr, _("cannot disable ftype with crcs enabled\n"));
1919 usage();
1920 }
1921
1922 if (!slflag && !ssflag) {
1923 sectorlog = XFS_MIN_SECTORSIZE_LOG;
1924 sectorsize = XFS_MIN_SECTORSIZE;
1925 }
1926 if (!lslflag && !lssflag) {
1927 lsectorlog = sectorlog;
1928 lsectorsize = sectorsize;
1929 }
1930
1931 /*
1932 * Before anything else, verify that we are correctly operating on
1933 * files or block devices and set the control parameters correctly.
1934 * Explicitly disable direct IO for image files so we don't error out on
1935 * sector size mismatches between the new filesystem and the underlying
1936 * host filesystem.
1937 */
1938 check_device_type(dfile, &xi.disfile, !dsize, !dfile,
1939 Nflag ? NULL : &xi.dcreat, force_overwrite, "d");
1940 if (!loginternal)
1941 check_device_type(xi.logname, &xi.lisfile, !logsize, !xi.logname,
1942 Nflag ? NULL : &xi.lcreat,
1943 force_overwrite, "l");
1944 if (xi.rtname)
1945 check_device_type(xi.rtname, &xi.risfile, !rtsize, !xi.rtname,
1946 Nflag ? NULL : &xi.rcreat,
1947 force_overwrite, "r");
1948 if (xi.disfile || xi.lisfile || xi.risfile)
1949 xi.isdirect = 0;
1950
1951 memset(&ft, 0, sizeof(ft));
1952 get_topology(&xi, &ft, force_overwrite);
1953
1954 if (!ssflag) {
1955 /*
1956 * Unless specified manually on the command line use the
1957 * advertised sector size of the device. We use the physical
1958 * sector size unless the requested block size is smaller
1959 * than that, then we can use logical, but warn about the
1960 * inefficiency.
1961 */
1962
1963 /* Older kernels may not have physical/logical distinction */
1964 if (!ft.psectorsize)
1965 ft.psectorsize = ft.lsectorsize;
1966
1967 sectorsize = ft.psectorsize ? ft.psectorsize :
1968 XFS_MIN_SECTORSIZE;
1969
1970 if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) {
1971 fprintf(stderr,
1972 _("specified blocksize %d is less than device physical sector size %d\n"),
1973 blocksize, ft.psectorsize);
1974 fprintf(stderr,
1975 _("switching to logical sector size %d\n"),
1976 ft.lsectorsize);
1977 sectorsize = ft.lsectorsize ? ft.lsectorsize :
1978 XFS_MIN_SECTORSIZE;
1979 }
1980 }
1981
1982 if (!ssflag) {
1983 sectorlog = libxfs_highbit32(sectorsize);
1984 if (loginternal) {
1985 lsectorsize = sectorsize;
1986 lsectorlog = sectorlog;
1987 }
1988 }
1989
1990 if (sectorsize < XFS_MIN_SECTORSIZE ||
1991 sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) {
1992 if (ssflag)
1993 fprintf(stderr, _("illegal sector size %d\n"), sectorsize);
1994 else
1995 fprintf(stderr,
1996 _("block size %d cannot be smaller than logical sector size %d\n"),
1997 blocksize, ft.lsectorsize);
1998 usage();
1999 }
2000 if (sectorsize < ft.lsectorsize) {
2001 fprintf(stderr, _("illegal sector size %d; hw sector is %d\n"),
2002 sectorsize, ft.lsectorsize);
2003 usage();
2004 }
2005 if (lsectorsize < XFS_MIN_SECTORSIZE ||
2006 lsectorsize > XFS_MAX_SECTORSIZE || lsectorsize > blocksize) {
2007 fprintf(stderr, _("illegal log sector size %d\n"), lsectorsize);
2008 usage();
2009 } else if (lsectorsize > XFS_MIN_SECTORSIZE && !lsu && !lsunit) {
2010 lsu = blocksize;
2011 sb_feat.log_version = 2;
2012 }
2013
2014 /*
2015 * Now we have blocks and sector sizes set up, check parameters that are
2016 * no longer optional for CRC enabled filesystems. Catch them up front
2017 * here before doing anything else.
2018 */
2019 if (sb_feat.crcs_enabled) {
2020 /* minimum inode size is 512 bytes, ipflag checked later */
2021 if ((isflag || ilflag) && inodelog < XFS_DINODE_DFL_CRC_LOG) {
2022 fprintf(stderr,
2023 _("Minimum inode size for CRCs is %d bytes\n"),
2024 1 << XFS_DINODE_DFL_CRC_LOG);
2025 usage();
2026 }
2027
2028 /* inodes always aligned */
2029 if (!sb_feat.inode_align) {
2030 fprintf(stderr,
2031 _("Inodes always aligned for CRC enabled filesytems\n"));
2032 usage();
2033 }
2034
2035 /* lazy sb counters always on */
2036 if (!sb_feat.lazy_sb_counters) {
2037 fprintf(stderr,
2038 _("Lazy superblock counted always enabled for CRC enabled filesytems\n"));
2039 usage();
2040 }
2041
2042 /* version 2 logs always on */
2043 if (sb_feat.log_version != 2) {
2044 fprintf(stderr,
2045 _("V2 logs always enabled for CRC enabled filesytems\n"));
2046 usage();
2047 }
2048
2049 /* attr2 always on */
2050 if (sb_feat.attr_version != 2) {
2051 fprintf(stderr,
2052 _("V2 attribute format always enabled on CRC enabled filesytems\n"));
2053 usage();
2054 }
2055
2056 /* 32 bit project quota always on */
2057 /* attr2 always on */
2058 if (sb_feat.projid16bit) {
2059 fprintf(stderr,
2060 _("32 bit Project IDs always enabled on CRC enabled filesytems\n"));
2061 usage();
2062 }
2063 } else {
2064 /*
2065 * The kernel doesn't currently support crc=0,finobt=1
2066 * filesystems. If crcs are not enabled and the user has not
2067 * explicitly turned finobt on, then silently turn it off to
2068 * avoid an unnecessary warning.
2069 * If the user explicitly tried to use crc=0,finobt=1,
2070 * then issue an error.
2071 * The same is also for sparse inodes.
2072 */
2073 if (sb_feat.finobt && mopts.subopt_params[M_FINOBT].seen) {
2074 fprintf(stderr,
2075 _("finobt not supported without CRC support\n"));
2076 usage();
2077 }
2078 sb_feat.finobt = 0;
2079
2080 if (sb_feat.spinodes) {
2081 fprintf(stderr,
2082 _("sparse inodes not supported without CRC support\n"));
2083 usage();
2084 }
2085 sb_feat.spinodes = 0;
2086
2087 }
2088
2089 if (nsflag || nlflag) {
2090 if (dirblocksize < blocksize ||
2091 dirblocksize > XFS_MAX_BLOCKSIZE) {
2092 fprintf(stderr, _("illegal directory block size %d\n"),
2093 dirblocksize);
2094 usage();
2095 }
2096 } else {
2097 if (blocksize < (1 << XFS_MIN_REC_DIRSIZE))
2098 dirblocklog = XFS_MIN_REC_DIRSIZE;
2099 else
2100 dirblocklog = blocklog;
2101 dirblocksize = 1 << dirblocklog;
2102 }
2103
2104
2105 if (dsize) {
2106 __uint64_t dbytes;
2107
2108 dbytes = getnum(dsize, &dopts, D_SIZE);
2109 if (dbytes % XFS_MIN_BLOCKSIZE) {
2110 fprintf(stderr,
2111 _("illegal data length %lld, not a multiple of %d\n"),
2112 (long long)dbytes, XFS_MIN_BLOCKSIZE);
2113 usage();
2114 }
2115 dblocks = (xfs_rfsblock_t)(dbytes >> blocklog);
2116 if (dbytes % blocksize)
2117 fprintf(stderr, _("warning: "
2118 "data length %lld not a multiple of %d, truncated to %lld\n"),
2119 (long long)dbytes, blocksize,
2120 (long long)(dblocks << blocklog));
2121 }
2122 if (ipflag) {
2123 inodelog = blocklog - libxfs_highbit32(inopblock);
2124 isize = 1 << inodelog;
2125 } else if (!ilflag && !isflag) {
2126 inodelog = sb_feat.crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
2127 : XFS_DINODE_DFL_LOG;
2128 isize = 1 << inodelog;
2129 }
2130 if (sb_feat.crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
2131 fprintf(stderr,
2132 _("Minimum inode size for CRCs is %d bytes\n"),
2133 1 << XFS_DINODE_DFL_CRC_LOG);
2134 usage();
2135 }
2136
2137 if (logsize) {
2138 __uint64_t logbytes;
2139
2140 logbytes = getnum(logsize, &lopts, L_SIZE);
2141 if (logbytes % XFS_MIN_BLOCKSIZE) {
2142 fprintf(stderr,
2143 _("illegal log length %lld, not a multiple of %d\n"),
2144 (long long)logbytes, XFS_MIN_BLOCKSIZE);
2145 usage();
2146 }
2147 logblocks = (xfs_rfsblock_t)(logbytes >> blocklog);
2148 if (logbytes % blocksize)
2149 fprintf(stderr,
2150 _("warning: log length %lld not a multiple of %d, truncated to %lld\n"),
2151 (long long)logbytes, blocksize,
2152 (long long)(logblocks << blocklog));
2153 }
2154 if (rtsize) {
2155 __uint64_t rtbytes;
2156
2157 rtbytes = getnum(rtsize, &ropts, R_SIZE);
2158 if (rtbytes % XFS_MIN_BLOCKSIZE) {
2159 fprintf(stderr,
2160 _("illegal rt length %lld, not a multiple of %d\n"),
2161 (long long)rtbytes, XFS_MIN_BLOCKSIZE);
2162 usage();
2163 }
2164 rtblocks = (xfs_rfsblock_t)(rtbytes >> blocklog);
2165 if (rtbytes % blocksize)
2166 fprintf(stderr,
2167 _("warning: rt length %lld not a multiple of %d, truncated to %lld\n"),
2168 (long long)rtbytes, blocksize,
2169 (long long)(rtblocks << blocklog));
2170 }
2171 /*
2172 * If specified, check rt extent size against its constraints.
2173 */
2174 if (rtextsize) {
2175 __uint64_t rtextbytes;
2176
2177 rtextbytes = getnum(rtextsize, &ropts, R_EXTSIZE);
2178 if (rtextbytes % blocksize) {
2179 fprintf(stderr,
2180 _("illegal rt extent size %lld, not a multiple of %d\n"),
2181 (long long)rtextbytes, blocksize);
2182 usage();
2183 }
2184 rtextblocks = (xfs_extlen_t)(rtextbytes >> blocklog);
2185 } else {
2186 /*
2187 * If realtime extsize has not been specified by the user,
2188 * and the underlying volume is striped, then set rtextblocks
2189 * to the stripe width.
2190 */
2191 __uint64_t rswidth;
2192 __uint64_t rtextbytes;
2193
2194 if (!norsflag && !xi.risfile && !(!rtsize && xi.disfile))
2195 rswidth = ft.rtswidth;
2196 else
2197 rswidth = 0;
2198
2199 /* check that rswidth is a multiple of fs blocksize */
2200 if (!norsflag && rswidth && !(BBTOB(rswidth) % blocksize)) {
2201 rswidth = DTOBT(rswidth);
2202 rtextbytes = rswidth << blocklog;
2203 if (XFS_MIN_RTEXTSIZE <= rtextbytes &&
2204 (rtextbytes <= XFS_MAX_RTEXTSIZE)) {
2205 rtextblocks = rswidth;
2206 }
2207 }
2208 if (!rtextblocks) {
2209 rtextblocks = (blocksize < XFS_MIN_RTEXTSIZE) ?
2210 XFS_MIN_RTEXTSIZE >> blocklog : 1;
2211 }
2212 }
2213 ASSERT(rtextblocks);
2214
2215 /*
2216 * Check some argument sizes against mins, maxes.
2217 */
2218 if (isize > blocksize / XFS_MIN_INODE_PERBLOCK ||
2219 isize < XFS_DINODE_MIN_SIZE ||
2220 isize > XFS_DINODE_MAX_SIZE) {
2221 int maxsz;
2222
2223 fprintf(stderr, _("illegal inode size %d\n"), isize);
2224 maxsz = MIN(blocksize / XFS_MIN_INODE_PERBLOCK,
2225 XFS_DINODE_MAX_SIZE);
2226 if (XFS_DINODE_MIN_SIZE == maxsz)
2227 fprintf(stderr,
2228 _("allowable inode size with %d byte blocks is %d\n"),
2229 blocksize, XFS_DINODE_MIN_SIZE);
2230 else
2231 fprintf(stderr,
2232 _("allowable inode size with %d byte blocks is between %d and %d\n"),
2233 blocksize, XFS_DINODE_MIN_SIZE, maxsz);
2234 exit(1);
2235 }
2236
2237 /* if lsu or lsunit was specified, automatically use v2 logs */
2238 if ((lsu || lsunit) && sb_feat.log_version == 1) {
2239 fprintf(stderr,
2240 _("log stripe unit specified, using v2 logs\n"));
2241 sb_feat.log_version = 2;
2242 }
2243
2244 calc_stripe_factors(dsu, dsw, sectorsize, lsu, lsectorsize,
2245 &dsunit, &dswidth, &lsunit);
2246
2247 xi.setblksize = sectorsize;
2248
2249 /*
2250 * Initialize. This will open the log and rt devices as well.
2251 */
2252 if (!libxfs_init(&xi))
2253 usage();
2254 if (!xi.ddev) {
2255 fprintf(stderr, _("no device name given in argument list\n"));
2256 usage();
2257 }
2258
2259 /*
2260 * Ok, Linux only has a 1024-byte resolution on device _size_,
2261 * and the sizes below are in basic 512-byte blocks,
2262 * so if we have (size % 2), on any partition, we can't get
2263 * to the last 512 bytes. The same issue exists for larger
2264 * sector sizes - we cannot write past the last sector.
2265 *
2266 * So, we reduce the size (in basic blocks) to a perfect
2267 * multiple of the sector size, or 1024, whichever is larger.
2268 */
2269
2270 sector_mask = (__uint64_t)-1 << (MAX(sectorlog, 10) - BBSHIFT);
2271 xi.dsize &= sector_mask;
2272 xi.rtsize &= sector_mask;
2273 xi.logBBsize &= (__uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
2274
2275
2276 /* don't do discards on print-only runs or on files */
2277 if (discard && !Nflag) {
2278 if (!xi.disfile)
2279 discard_blocks(xi.ddev, xi.dsize);
2280 if (xi.rtdev && !xi.risfile)
2281 discard_blocks(xi.rtdev, xi.rtsize);
2282 if (xi.logdev && xi.logdev != xi.ddev && !xi.lisfile)
2283 discard_blocks(xi.logdev, xi.logBBsize);
2284 }
2285
2286 if (!liflag && !ldflag)
2287 loginternal = xi.logdev == 0;
2288 if (xi.logname)
2289 logfile = xi.logname;
2290 else if (loginternal)
2291 logfile = _("internal log");
2292 else if (xi.volname && xi.logdev)
2293 logfile = _("volume log");
2294 else if (!ldflag) {
2295 fprintf(stderr, _("no log subvolume or internal log\n"));
2296 usage();
2297 }
2298 if (xi.rtname)
2299 rtfile = xi.rtname;
2300 else
2301 if (xi.volname && xi.rtdev)
2302 rtfile = _("volume rt");
2303 else if (!xi.rtdev)
2304 rtfile = _("none");
2305 if (dsize && xi.dsize > 0 && dblocks > DTOBT(xi.dsize)) {
2306 fprintf(stderr,
2307 _("size %s specified for data subvolume is too large, "
2308 "maximum is %lld blocks\n"),
2309 dsize, (long long)DTOBT(xi.dsize));
2310 usage();
2311 } else if (!dsize && xi.dsize > 0)
2312 dblocks = DTOBT(xi.dsize);
2313 else if (!dsize) {
2314 fprintf(stderr, _("can't get size of data subvolume\n"));
2315 usage();
2316 }
2317 if (dblocks < XFS_MIN_DATA_BLOCKS) {
2318 fprintf(stderr,
2319 _("size %lld of data subvolume is too small, minimum %d blocks\n"),
2320 (long long)dblocks, XFS_MIN_DATA_BLOCKS);
2321 usage();
2322 }
2323
2324 if (loginternal && xi.logdev) {
2325 fprintf(stderr,
2326 _("can't have both external and internal logs\n"));
2327 usage();
2328 } else if (loginternal && sectorsize != lsectorsize) {
2329 fprintf(stderr,
2330 _("data and log sector sizes must be equal for internal logs\n"));
2331 usage();
2332 }
2333
2334 if (xi.dbsize > sectorsize) {
2335 fprintf(stderr, _(
2336 "Warning: the data subvolume sector size %u is less than the sector size \n\
2337 reported by the device (%u).\n"),
2338 sectorsize, xi.dbsize);
2339 }
2340 if (!loginternal && xi.lbsize > lsectorsize) {
2341 fprintf(stderr, _(
2342 "Warning: the log subvolume sector size %u is less than the sector size\n\
2343 reported by the device (%u).\n"),
2344 lsectorsize, xi.lbsize);
2345 }
2346 if (rtsize && xi.rtsize > 0 && xi.rtbsize > sectorsize) {
2347 fprintf(stderr, _(
2348 "Warning: the realtime subvolume sector size %u is less than the sector size\n\
2349 reported by the device (%u).\n"),
2350 sectorsize, xi.rtbsize);
2351 }
2352
2353 if (rtsize && xi.rtsize > 0 && rtblocks > DTOBT(xi.rtsize)) {
2354 fprintf(stderr,
2355 _("size %s specified for rt subvolume is too large, "
2356 "maximum is %lld blocks\n"),
2357 rtsize, (long long)DTOBT(xi.rtsize));
2358 usage();
2359 } else if (!rtsize && xi.rtsize > 0)
2360 rtblocks = DTOBT(xi.rtsize);
2361 else if (rtsize && !xi.rtdev) {
2362 fprintf(stderr,
2363 _("size specified for non-existent rt subvolume\n"));
2364 usage();
2365 }
2366 if (xi.rtdev) {
2367 rtextents = rtblocks / rtextblocks;
2368 nbmblocks = (xfs_extlen_t)howmany(rtextents, NBBY * blocksize);
2369 } else {
2370 rtextents = rtblocks = 0;
2371 nbmblocks = 0;
2372 }
2373
2374 if (!nodsflag) {
2375 if (dsunit) {
2376 if (ft.dsunit && ft.dsunit != dsunit) {
2377 fprintf(stderr,
2378 _("%s: Specified data stripe unit %d "
2379 "is not the same as the volume stripe "
2380 "unit %d\n"),
2381 progname, dsunit, ft.dsunit);
2382 }
2383 if (ft.dswidth && ft.dswidth != dswidth) {
2384 fprintf(stderr,
2385 _("%s: Specified data stripe width %d "
2386 "is not the same as the volume stripe "
2387 "width %d\n"),
2388 progname, dswidth, ft.dswidth);
2389 }
2390 } else {
2391 dsunit = ft.dsunit;
2392 dswidth = ft.dswidth;
2393 nodsflag = 1;
2394 }
2395 } /* else dsunit & dswidth can't be set if nodsflag is set */
2396
2397 if (dasize) { /* User-specified AG size */
2398 /*
2399 * Check specified agsize is a multiple of blocksize.
2400 */
2401 if (agsize % blocksize) {
2402 fprintf(stderr,
2403 _("agsize (%lld) not a multiple of fs blk size (%d)\n"),
2404 (long long)agsize, blocksize);
2405 usage();
2406 }
2407 agsize /= blocksize;
2408 agcount = dblocks / agsize + (dblocks % agsize != 0);
2409
2410 } else if (daflag) { /* User-specified AG count */
2411 agsize = dblocks / agcount + (dblocks % agcount != 0);
2412 } else {
2413 calc_default_ag_geometry(blocklog, dblocks,
2414 dsunit | dswidth, &agsize, &agcount);
2415 }
2416
2417 /*
2418 * If dsunit is a multiple of fs blocksize, then check that is a
2419 * multiple of the agsize too
2420 */
2421 if (dsunit && !(BBTOB(dsunit) % blocksize) &&
2422 dswidth && !(BBTOB(dswidth) % blocksize)) {
2423
2424 /* convert from 512 byte blocks to fs blocksize */
2425 dsunit = DTOBT(dsunit);
2426 dswidth = DTOBT(dswidth);
2427
2428 /*
2429 * agsize is not a multiple of dsunit
2430 */
2431 if ((agsize % dsunit) != 0) {
2432 /*
2433 * Round up to stripe unit boundary. Also make sure
2434 * that agsize is still larger than
2435 * XFS_AG_MIN_BLOCKS(blocklog)
2436 */
2437 tmp_agsize = ((agsize + (dsunit - 1))/ dsunit) * dsunit;
2438 /*
2439 * Round down to stripe unit boundary if rounding up
2440 * created an AG size that is larger than the AG max.
2441 */
2442 if (tmp_agsize > XFS_AG_MAX_BLOCKS(blocklog))
2443 tmp_agsize = ((agsize) / dsunit) * dsunit;
2444
2445 if ((tmp_agsize >= XFS_AG_MIN_BLOCKS(blocklog)) &&
2446 (tmp_agsize <= XFS_AG_MAX_BLOCKS(blocklog))) {
2447 agsize = tmp_agsize;
2448 if (!daflag)
2449 agcount = dblocks/agsize +
2450 (dblocks % agsize != 0);
2451 if (dasize)
2452 fprintf(stderr,
2453 _("agsize rounded to %lld, swidth = %d\n"),
2454 (long long)agsize, dswidth);
2455 } else {
2456 if (nodsflag) {
2457 dsunit = dswidth = 0;
2458 } else {
2459 /*
2460 * agsize is out of bounds, this will
2461 * print nice details & exit.
2462 */
2463 validate_ag_geometry(blocklog, dblocks,
2464 agsize, agcount);
2465 exit(1);
2466 }
2467 }
2468 }
2469 if (dswidth && ((agsize % dswidth) == 0) && (agcount > 1)) {
2470 /* This is a non-optimal configuration because all AGs
2471 * start on the same disk in the stripe. Changing
2472 * the AG size by one sunit will guarantee that this
2473 * does not happen.
2474 */
2475 tmp_agsize = agsize - dsunit;
2476 if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
2477 tmp_agsize = agsize + dsunit;
2478 if (dblocks < agsize) {
2479 /* oh well, nothing to do */
2480 tmp_agsize = agsize;
2481 }
2482 }
2483 if (daflag || dasize) {
2484 fprintf(stderr, _(
2485 "Warning: AG size is a multiple of stripe width. This can cause performance\n\
2486 problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
2487 an AG size that is one stripe unit smaller, for example %llu.\n"),
2488 (unsigned long long)tmp_agsize);
2489 } else {
2490 agsize = tmp_agsize;
2491 agcount = dblocks/agsize + (dblocks % agsize != 0);
2492 /*
2493 * If the last AG is too small, reduce the
2494 * filesystem size and drop the blocks.
2495 */
2496 if ( dblocks % agsize != 0 &&
2497 (dblocks % agsize <
2498 XFS_AG_MIN_BLOCKS(blocklog))) {
2499 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
2500 agcount--;
2501 ASSERT(agcount != 0);
2502 }
2503 }
2504 }
2505 } else {
2506 if (nodsflag)
2507 dsunit = dswidth = 0;
2508 else {
2509 fprintf(stderr,
2510 _("%s: Stripe unit(%d) or stripe width(%d) is "
2511 "not a multiple of the block size(%d)\n"),
2512 progname, BBTOB(dsunit), BBTOB(dswidth),
2513 blocksize);
2514 exit(1);
2515 }
2516 }
2517
2518 /*
2519 * If the last AG is too small, reduce the filesystem size
2520 * and drop the blocks.
2521 */
2522 if ( dblocks % agsize != 0 &&
2523 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
2524 ASSERT(!daflag);
2525 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
2526 agcount--;
2527 ASSERT(agcount != 0);
2528 }
2529
2530 validate_ag_geometry(blocklog, dblocks, agsize, agcount);
2531
2532 if (!imflag)
2533 imaxpct = calc_default_imaxpct(blocklog, dblocks);
2534
2535 /*
2536 * check that log sunit is modulo fsblksize or default it to dsunit.
2537 */
2538
2539 if (lsunit) {
2540 if ((BBTOB(lsunit) % blocksize != 0)) {
2541 fprintf(stderr,
2542 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
2543 BBTOB(lsunit), blocksize);
2544 exit(1);
2545 }
2546 /* convert from 512 byte blocks to fs blocks */
2547 lsunit = DTOBT(lsunit);
2548 } else if (sb_feat.log_version == 2 && loginternal && dsunit) {
2549 /* lsunit and dsunit now in fs blocks */
2550 lsunit = dsunit;
2551 }
2552
2553 if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
2554 /* Warn only if specified on commandline */
2555 if (lsuflag || lsunitflag) {
2556 fprintf(stderr,
2557 _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
2558 (lsunit * blocksize));
2559 fprintf(stderr,
2560 _("log stripe unit adjusted to 32KiB\n"));
2561 }
2562 lsunit = (32 * 1024) >> blocklog;
2563 }
2564
2565 min_logblocks = max_trans_res(sb_feat.crcs_enabled, sb_feat.dir_version,
2566 sectorlog, blocklog, inodelog, dirblocklog,
2567 sb_feat.log_version, lsunit, sb_feat.finobt);
2568 ASSERT(min_logblocks);
2569 min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
2570 if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
2571 min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
2572 if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
2573 fprintf(stderr,
2574 _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
2575 logsize, (long long)DTOBT(xi.logBBsize));
2576 usage();
2577 } else if (!logsize && xi.logBBsize > 0) {
2578 logblocks = DTOBT(xi.logBBsize);
2579 } else if (logsize && !xi.logdev && !loginternal) {
2580 fprintf(stderr,
2581 _("size specified for non-existent log subvolume\n"));
2582 usage();
2583 } else if (loginternal && logsize && logblocks >= dblocks) {
2584 fprintf(stderr, _("size %lld too large for internal log\n"),
2585 (long long)logblocks);
2586 usage();
2587 } else if (!loginternal && !xi.logdev) {
2588 logblocks = 0;
2589 } else if (loginternal && !logsize) {
2590
2591 if (dblocks < GIGABYTES(1, blocklog)) {
2592 /* tiny filesystems get minimum sized logs. */
2593 logblocks = min_logblocks;
2594 } else if (dblocks < GIGABYTES(16, blocklog)) {
2595
2596 /*
2597 * For small filesystems, we want to use the
2598 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
2599 * at all possible, ramping up to 128MB at 256GB.
2600 */
2601 logblocks = MIN(XFS_MIN_LOG_BYTES >> blocklog,
2602 min_logblocks * XFS_DFL_LOG_FACTOR);
2603 } else {
2604 /*
2605 * With a 2GB max log size, default to maximum size
2606 * at 4TB. This keeps the same ratio from the older
2607 * max log size of 128M at 256GB fs size. IOWs,
2608 * the ratio of fs size to log size is 2048:1.
2609 */
2610 logblocks = (dblocks << blocklog) / 2048;
2611 logblocks = logblocks >> blocklog;
2612 }
2613
2614 /* Ensure the chosen size meets minimum log size requirements */
2615 logblocks = MAX(min_logblocks, logblocks);
2616
2617 /* make sure the log fits wholly within an AG */
2618 if (logblocks >= agsize)
2619 logblocks = min_logblocks;
2620
2621 /* and now clamp the size to the maximum supported size */
2622 logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
2623 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES)
2624 logblocks = XFS_MAX_LOG_BYTES >> blocklog;
2625
2626 }
2627 validate_log_size(logblocks, blocklog, min_logblocks);
2628
2629 protostring = setup_proto(protofile);
2630 bsize = 1 << (blocklog - BBSHIFT);
2631 mp = &mbuf;
2632 sbp = &mp->m_sb;
2633 memset(mp, 0, sizeof(xfs_mount_t));
2634 sbp->sb_blocklog = (__uint8_t)blocklog;
2635 sbp->sb_sectlog = (__uint8_t)sectorlog;
2636 sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize);
2637 sbp->sb_agblocks = (xfs_agblock_t)agsize;
2638 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
2639 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
2640
2641 /*
2642 * sb_versionnum and finobt flags must be set before we use
2643 * XFS_PREALLOC_BLOCKS().
2644 */
2645 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
2646
2647
2648 if (loginternal) {
2649 /*
2650 * Readjust the log size to fit within an AG if it was sized
2651 * automatically.
2652 */
2653 if (!logsize) {
2654 logblocks = MIN(logblocks,
2655 XFS_ALLOC_AG_MAX_USABLE(mp));
2656
2657 /* revalidate the log size is valid if we changed it */
2658 validate_log_size(logblocks, blocklog, min_logblocks);
2659 }
2660 if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) {
2661 fprintf(stderr,
2662 _("internal log size %lld too large, must fit in allocation group\n"),
2663 (long long)logblocks);
2664 usage();
2665 }
2666
2667 if (laflag) {
2668 if (logagno >= agcount) {
2669 fprintf(stderr,
2670 _("log ag number %d too large, must be less than %lld\n"),
2671 logagno, (long long)agcount);
2672 usage();
2673 }
2674 } else
2675 logagno = (xfs_agnumber_t)(agcount / 2);
2676
2677 logstart = XFS_AGB_TO_FSB(mp, logagno, XFS_PREALLOC_BLOCKS(mp));
2678 /*
2679 * Align the logstart at stripe unit boundary.
2680 */
2681 if (lsunit) {
2682 logstart = fixup_internal_log_stripe(mp,
2683 lsflag, logstart, agsize, lsunit,
2684 &logblocks, blocklog, &lalign);
2685 } else if (dsunit) {
2686 logstart = fixup_internal_log_stripe(mp,
2687 lsflag, logstart, agsize, dsunit,
2688 &logblocks, blocklog, &lalign);
2689 }
2690 } else {
2691 logstart = 0;
2692 if (lsunit)
2693 fixup_log_stripe_unit(lsflag, lsunit,
2694 &logblocks, blocklog);
2695 }
2696 validate_log_size(logblocks, blocklog, min_logblocks);
2697
2698 if (!qflag || Nflag) {
2699 printf(_(
2700 "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
2701 " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
2702 " =%-22s crc=%-8u finobt=%u, sparse=%u\n"
2703 "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
2704 " =%-22s sunit=%-6u swidth=%u blks\n"
2705 "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n"
2706 "log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
2707 " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
2708 "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
2709 dfile, isize, (long long)agcount, (long long)agsize,
2710 "", sectorsize, sb_feat.attr_version,
2711 !sb_feat.projid16bit,
2712 "", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
2713 "", blocksize, (long long)dblocks, imaxpct,
2714 "", dsunit, dswidth,
2715 sb_feat.dir_version, dirblocksize, sb_feat.nci,
2716 sb_feat.dirftype,
2717 logfile, 1 << blocklog, (long long)logblocks,
2718 sb_feat.log_version, "", lsectorsize, lsunit,
2719 sb_feat.lazy_sb_counters,
2720 rtfile, rtextblocks << blocklog,
2721 (long long)rtblocks, (long long)rtextents);
2722 if (Nflag)
2723 exit(0);
2724 }
2725
2726 if (label)
2727 strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname));
2728 sbp->sb_magicnum = XFS_SB_MAGIC;
2729 sbp->sb_blocksize = blocksize;
2730 sbp->sb_dblocks = dblocks;
2731 sbp->sb_rblocks = rtblocks;
2732 sbp->sb_rextents = rtextents;
2733 platform_uuid_copy(&sbp->sb_uuid, &uuid);
2734 /* Only in memory; libxfs expects this as if read from disk */
2735 platform_uuid_copy(&sbp->sb_meta_uuid, &uuid);
2736 sbp->sb_logstart = logstart;
2737 sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
2738 sbp->sb_rextsize = rtextblocks;
2739 sbp->sb_agcount = (xfs_agnumber_t)agcount;
2740 sbp->sb_rbmblocks = nbmblocks;
2741 sbp->sb_logblocks = (xfs_extlen_t)logblocks;
2742 sbp->sb_sectsize = (__uint16_t)sectorsize;
2743 sbp->sb_inodesize = (__uint16_t)isize;
2744 sbp->sb_inopblock = (__uint16_t)(blocksize / isize);
2745 sbp->sb_sectlog = (__uint8_t)sectorlog;
2746 sbp->sb_inodelog = (__uint8_t)inodelog;
2747 sbp->sb_inopblog = (__uint8_t)(blocklog - inodelog);
2748 sbp->sb_rextslog =
2749 (__uint8_t)(rtextents ?
2750 libxfs_highbit32((unsigned int)rtextents) : 0);
2751 sbp->sb_inprogress = 1; /* mkfs is in progress */
2752 sbp->sb_imax_pct = imaxpct;
2753 sbp->sb_icount = 0;
2754 sbp->sb_ifree = 0;
2755 sbp->sb_fdblocks = dblocks - agcount * XFS_PREALLOC_BLOCKS(mp) -
2756 (loginternal ? logblocks : 0);
2757 sbp->sb_frextents = 0; /* will do a free later */
2758 sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
2759 sbp->sb_qflags = 0;
2760 sbp->sb_unit = dsunit;
2761 sbp->sb_width = dswidth;
2762 sbp->sb_dirblklog = dirblocklog - blocklog;
2763 if (sb_feat.log_version == 2) { /* This is stored in bytes */
2764 lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit);
2765 sbp->sb_logsunit = lsunit;
2766 } else
2767 sbp->sb_logsunit = 0;
2768 if (sb_feat.inode_align) {
2769 int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
2770 if (sb_feat.crcs_enabled)
2771 cluster_size *= isize / XFS_DINODE_MIN_SIZE;
2772 sbp->sb_inoalignmt = cluster_size >> blocklog;
2773 sb_feat.inode_align = sbp->sb_inoalignmt != 0;
2774 } else
2775 sbp->sb_inoalignmt = 0;
2776 if (lsectorsize != BBSIZE || sectorsize != BBSIZE) {
2777 sbp->sb_logsectlog = (__uint8_t)lsectorlog;
2778 sbp->sb_logsectsize = (__uint16_t)lsectorsize;
2779 } else {
2780 sbp->sb_logsectlog = 0;
2781 sbp->sb_logsectsize = 0;
2782 }
2783
2784 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
2785
2786 if (force_overwrite)
2787 zero_old_xfs_structures(&xi, sbp);
2788
2789 /*
2790 * Zero out the beginning of the device, to obliterate any old
2791 * filesystem signatures out there. This should take care of
2792 * swap (somewhere around the page size), jfs (32k),
2793 * ext[2,3] and reiserfs (64k) - and hopefully all else.
2794 */
2795 libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
2796 buf = libxfs_getbuf(mp->m_ddev_targp, 0, BTOBB(WHACK_SIZE));
2797 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
2798 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2799 libxfs_purgebuf(buf);
2800
2801 /* OK, now write the superblock */
2802 buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
2803 buf->b_ops = &xfs_sb_buf_ops;
2804 memset(XFS_BUF_PTR(buf), 0, sectorsize);
2805 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
2806 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2807 libxfs_purgebuf(buf);
2808
2809 /*
2810 * If the data area is a file, then grow it out to its final size
2811 * if needed so that the reads for the end of the device in the mount
2812 * code will succeed.
2813 */
2814 if (xi.disfile && xi.dsize * xi.dbsize < dblocks * blocksize) {
2815 if (ftruncate64(xi.dfd, dblocks * blocksize) < 0) {
2816 fprintf(stderr,
2817 _("%s: Growing the data section failed\n"),
2818 progname);
2819 exit(1);
2820 }
2821 }
2822
2823 /*
2824 * Zero out the end of the device, to obliterate any
2825 * old MD RAID (or other) metadata at the end of the device.
2826 * (MD sb is ~64k from the end, take out a wider swath to be sure)
2827 */
2828 if (!xi.disfile) {
2829 buf = libxfs_getbuf(mp->m_ddev_targp,
2830 (xi.dsize - BTOBB(WHACK_SIZE)),
2831 BTOBB(WHACK_SIZE));
2832 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
2833 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2834 libxfs_purgebuf(buf);
2835 }
2836
2837 /*
2838 * Zero the log....
2839 */
2840 libxfs_log_clear(mp->m_logdev_targp, NULL,
2841 XFS_FSB_TO_DADDR(mp, logstart),
2842 (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
2843 &sbp->sb_uuid, sb_feat.log_version, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
2844
2845 mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
2846 if (mp == NULL) {
2847 fprintf(stderr, _("%s: filesystem failed to initialize\n"),
2848 progname);
2849 exit(1);
2850 }
2851
2852 /*
2853 * XXX: this code is effectively shared with the kernel growfs code.
2854 * These initialisations should be pulled into libxfs to keep the
2855 * kernel/userspace header initialisation code the same.
2856 */
2857 for (agno = 0; agno < agcount; agno++) {
2858 struct xfs_agfl *agfl;
2859 int bucket;
2860 struct xfs_perag *pag = xfs_perag_get(mp, agno);
2861
2862 /*
2863 * Superblock.
2864 */
2865 buf = libxfs_getbuf(mp->m_ddev_targp,
2866 XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
2867 XFS_FSS_TO_BB(mp, 1));
2868 buf->b_ops = &xfs_sb_buf_ops;
2869 memset(XFS_BUF_PTR(buf), 0, sectorsize);
2870 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
2871 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2872
2873 /*
2874 * AG header block: freespace
2875 */
2876 buf = libxfs_getbuf(mp->m_ddev_targp,
2877 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
2878 XFS_FSS_TO_BB(mp, 1));
2879 buf->b_ops = &xfs_agf_buf_ops;
2880 agf = XFS_BUF_TO_AGF(buf);
2881 memset(agf, 0, sectorsize);
2882 if (agno == agcount - 1)
2883 agsize = dblocks - (xfs_rfsblock_t)(agno * agsize);
2884 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
2885 agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
2886 agf->agf_seqno = cpu_to_be32(agno);
2887 agf->agf_length = cpu_to_be32(agsize);
2888 agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
2889 agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
2890 agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
2891 agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
2892 pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
2893 pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
2894 agf->agf_flfirst = 0;
2895 agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
2896 agf->agf_flcount = 0;
2897 nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp));
2898 agf->agf_freeblks = cpu_to_be32(nbmblocks);
2899 agf->agf_longest = cpu_to_be32(nbmblocks);
2900 if (xfs_sb_version_hascrc(&mp->m_sb))
2901 platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
2902
2903 if (loginternal && agno == logagno) {
2904 be32_add_cpu(&agf->agf_freeblks, -logblocks);
2905 agf->agf_longest = cpu_to_be32(agsize -
2906 XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
2907 }
2908 if (xfs_alloc_min_freelist(mp, pag) > worst_freelist)
2909 worst_freelist = xfs_alloc_min_freelist(mp, pag);
2910 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2911
2912 /*
2913 * AG freelist header block
2914 */
2915 buf = libxfs_getbuf(mp->m_ddev_targp,
2916 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
2917 XFS_FSS_TO_BB(mp, 1));
2918 buf->b_ops = &xfs_agfl_buf_ops;
2919 agfl = XFS_BUF_TO_AGFL(buf);
2920 /* setting to 0xff results in initialisation to NULLAGBLOCK */
2921 memset(agfl, 0xff, sectorsize);
2922 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2923 agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
2924 agfl->agfl_seqno = cpu_to_be32(agno);
2925 platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
2926 for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
2927 agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
2928 }
2929
2930 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2931
2932 /*
2933 * AG header block: inodes
2934 */
2935 buf = libxfs_getbuf(mp->m_ddev_targp,
2936 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
2937 XFS_FSS_TO_BB(mp, 1));
2938 agi = XFS_BUF_TO_AGI(buf);
2939 buf->b_ops = &xfs_agi_buf_ops;
2940 memset(agi, 0, sectorsize);
2941 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
2942 agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
2943 agi->agi_seqno = cpu_to_be32(agno);
2944 agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize);
2945 agi->agi_count = 0;
2946 agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
2947 agi->agi_level = cpu_to_be32(1);
2948 if (sb_feat.finobt) {
2949 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
2950 agi->agi_free_level = cpu_to_be32(1);
2951 }
2952 agi->agi_freecount = 0;
2953 agi->agi_newino = cpu_to_be32(NULLAGINO);
2954 agi->agi_dirino = cpu_to_be32(NULLAGINO);
2955 if (xfs_sb_version_hascrc(&mp->m_sb))
2956 platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
2957 for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
2958 agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
2959 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2960
2961 /*
2962 * BNO btree root block
2963 */
2964 buf = libxfs_getbuf(mp->m_ddev_targp,
2965 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
2966 bsize);
2967 buf->b_ops = &xfs_allocbt_buf_ops;
2968 block = XFS_BUF_TO_BLOCK(buf);
2969 memset(block, 0, blocksize);
2970 if (xfs_sb_version_hascrc(&mp->m_sb))
2971 xfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1,
2972 agno, XFS_BTREE_CRC_BLOCKS);
2973 else
2974 xfs_btree_init_block(mp, buf, XFS_ABTB_MAGIC, 0, 1,
2975 agno, 0);
2976
2977 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
2978 arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
2979 if (loginternal && agno == logagno) {
2980 if (lalign) {
2981 /*
2982 * Have to insert two records
2983 * Insert pad record for stripe align of log
2984 */
2985 arec->ar_blockcount = cpu_to_be32(
2986 XFS_FSB_TO_AGBNO(mp, logstart) -
2987 be32_to_cpu(arec->ar_startblock));
2988 nrec = arec + 1;
2989 /*
2990 * Insert record at start of internal log
2991 */
2992 nrec->ar_startblock = cpu_to_be32(
2993 be32_to_cpu(arec->ar_startblock) +
2994 be32_to_cpu(arec->ar_blockcount));
2995 arec = nrec;
2996 be16_add_cpu(&block->bb_numrecs, 1);
2997 }
2998 /*
2999 * Change record start to after the internal log
3000 */
3001 be32_add_cpu(&arec->ar_startblock, logblocks);
3002 }
3003 /*
3004 * Calculate the record block count and check for the case where
3005 * the log might have consumed all available space in the AG. If
3006 * so, reset the record count to 0 to avoid exposure of an invalid
3007 * record start block.
3008 */
3009 arec->ar_blockcount = cpu_to_be32(agsize -
3010 be32_to_cpu(arec->ar_startblock));
3011 if (!arec->ar_blockcount)
3012 block->bb_numrecs = 0;
3013
3014 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3015
3016 /*
3017 * CNT btree root block
3018 */
3019 buf = libxfs_getbuf(mp->m_ddev_targp,
3020 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
3021 bsize);
3022 buf->b_ops = &xfs_allocbt_buf_ops;
3023 block = XFS_BUF_TO_BLOCK(buf);
3024 memset(block, 0, blocksize);
3025 if (xfs_sb_version_hascrc(&mp->m_sb))
3026 xfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1,
3027 agno, XFS_BTREE_CRC_BLOCKS);
3028 else
3029 xfs_btree_init_block(mp, buf, XFS_ABTC_MAGIC, 0, 1,
3030 agno, 0);
3031
3032 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3033 arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
3034 if (loginternal && agno == logagno) {
3035 if (lalign) {
3036 arec->ar_blockcount = cpu_to_be32(
3037 XFS_FSB_TO_AGBNO(mp, logstart) -
3038 be32_to_cpu(arec->ar_startblock));
3039 nrec = arec + 1;
3040 nrec->ar_startblock = cpu_to_be32(
3041 be32_to_cpu(arec->ar_startblock) +
3042 be32_to_cpu(arec->ar_blockcount));
3043 arec = nrec;
3044 be16_add_cpu(&block->bb_numrecs, 1);
3045 }
3046 be32_add_cpu(&arec->ar_startblock, logblocks);
3047 }
3048 /*
3049 * Calculate the record block count and check for the case where
3050 * the log might have consumed all available space in the AG. If
3051 * so, reset the record count to 0 to avoid exposure of an invalid
3052 * record start block.
3053 */
3054 arec->ar_blockcount = cpu_to_be32(agsize -
3055 be32_to_cpu(arec->ar_startblock));
3056 if (!arec->ar_blockcount)
3057 block->bb_numrecs = 0;
3058
3059 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3060
3061 /*
3062 * INO btree root block
3063 */
3064 buf = libxfs_getbuf(mp->m_ddev_targp,
3065 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
3066 bsize);
3067 buf->b_ops = &xfs_inobt_buf_ops;
3068 block = XFS_BUF_TO_BLOCK(buf);
3069 memset(block, 0, blocksize);
3070 if (xfs_sb_version_hascrc(&mp->m_sb))
3071 xfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0,
3072 agno, XFS_BTREE_CRC_BLOCKS);
3073 else
3074 xfs_btree_init_block(mp, buf, XFS_IBT_MAGIC, 0, 0,
3075 agno, 0);
3076 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3077
3078 /*
3079 * Free INO btree root block
3080 */
3081 if (!sb_feat.finobt) {
3082 xfs_perag_put(pag);
3083 continue;
3084 }
3085
3086 buf = libxfs_getbuf(mp->m_ddev_targp,
3087 XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
3088 bsize);
3089 buf->b_ops = &xfs_inobt_buf_ops;
3090 block = XFS_BUF_TO_BLOCK(buf);
3091 memset(block, 0, blocksize);
3092 if (xfs_sb_version_hascrc(&mp->m_sb))
3093 xfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0,
3094 agno, XFS_BTREE_CRC_BLOCKS);
3095 else
3096 xfs_btree_init_block(mp, buf, XFS_FIBT_MAGIC, 0, 0,
3097 agno, 0);
3098 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3099 xfs_perag_put(pag);
3100 }
3101
3102 /*
3103 * Touch last block, make fs the right size if it's a file.
3104 */
3105 buf = libxfs_getbuf(mp->m_ddev_targp,
3106 (xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize);
3107 memset(XFS_BUF_PTR(buf), 0, blocksize);
3108 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3109
3110 /*
3111 * Make sure we can write the last block in the realtime area.
3112 */
3113 if (mp->m_rtdev_targp->dev && rtblocks > 0) {
3114 buf = libxfs_getbuf(mp->m_rtdev_targp,
3115 XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
3116 memset(XFS_BUF_PTR(buf), 0, blocksize);
3117 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3118 }
3119
3120 /*
3121 * BNO, CNT free block list
3122 */
3123 for (agno = 0; agno < agcount; agno++) {
3124 xfs_alloc_arg_t args;
3125 xfs_trans_t *tp;
3126 struct xfs_trans_res tres = {0};
3127
3128 memset(&args, 0, sizeof(args));
3129 args.tp = tp = libxfs_trans_alloc(mp, 0);
3130 args.mp = mp;
3131 args.agno = agno;
3132 args.alignment = 1;
3133 args.pag = xfs_perag_get(mp,agno);
3134 c = -libxfs_trans_reserve(tp, &tres, worst_freelist, 0);
3135 if (c)
3136 res_failed(c);
3137
3138 libxfs_alloc_fix_freelist(&args, 0);
3139 xfs_perag_put(args.pag);
3140 libxfs_trans_commit(tp);
3141 }
3142
3143 /*
3144 * Allocate the root inode and anything else in the proto file.
3145 */
3146 parse_proto(mp, &fsx, &protostring);
3147
3148 /*
3149 * Protect ourselves against possible stupidity
3150 */
3151 if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
3152 fprintf(stderr,
3153 _("%s: root inode created in AG %u, not AG 0\n"),
3154 progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
3155 exit(1);
3156 }
3157
3158 /*
3159 * Write out multiple secondary superblocks with rootinode field set
3160 */
3161 if (mp->m_sb.sb_agcount > 1) {
3162 /*
3163 * the last superblock
3164 */
3165 buf = libxfs_readbuf(mp->m_dev,
3166 XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1,
3167 XFS_SB_DADDR),
3168 XFS_FSS_TO_BB(mp, 1),
3169 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3170 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
3171 mp->m_sb.sb_rootino);
3172 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3173 /*
3174 * and one in the middle for luck
3175 */
3176 if (mp->m_sb.sb_agcount > 2) {
3177 buf = libxfs_readbuf(mp->m_dev,
3178 XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2,
3179 XFS_SB_DADDR),
3180 XFS_FSS_TO_BB(mp, 1),
3181 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3182 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
3183 mp->m_sb.sb_rootino);
3184 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3185 }
3186 }
3187
3188 /*
3189 * Dump all inodes and buffers before marking us all done.
3190 * Need to drop references to inodes we still hold, first.
3191 */
3192 libxfs_rtmount_destroy(mp);
3193 libxfs_bcache_purge();
3194
3195 /*
3196 * Mark the filesystem ok.
3197 */
3198 buf = libxfs_getsb(mp, LIBXFS_EXIT_ON_FAILURE);
3199 (XFS_BUF_TO_SBP(buf))->sb_inprogress = 0;
3200 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3201
3202 libxfs_umount(mp);
3203 if (xi.rtdev)
3204 libxfs_device_close(xi.rtdev);
3205 if (xi.logdev && xi.logdev != xi.ddev)
3206 libxfs_device_close(xi.logdev);
3207 libxfs_device_close(xi.ddev);
3208
3209 return 0;
3210 }
3211
3212 static void
3213 conflict(
3214 char opt,
3215 char *tab[],
3216 int oldidx,
3217 int newidx)
3218 {
3219 fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
3220 opt, tab[oldidx], opt, tab[newidx]);
3221 usage();
3222 }
3223
3224
3225 static void
3226 illegal(
3227 const char *value,
3228 const char *opt)
3229 {
3230 fprintf(stderr, _("Illegal value %s for -%s option\n"), value, opt);
3231 usage();
3232 }
3233
3234 static int
3235 ispow2(
3236 unsigned int i)
3237 {
3238 return (i & (i - 1)) == 0;
3239 }
3240
3241 static void __attribute__((noreturn))
3242 reqval(
3243 char opt,
3244 char *tab[],
3245 int idx)
3246 {
3247 fprintf(stderr, _("-%c %s option requires a value\n"), opt, tab[idx]);
3248 usage();
3249 }
3250
3251 static void
3252 respec(
3253 char opt,
3254 char *tab[],
3255 int idx)
3256 {
3257 fprintf(stderr, "-%c ", opt);
3258 if (tab)
3259 fprintf(stderr, "%s ", tab[idx]);
3260 fprintf(stderr, _("option respecified\n"));
3261 usage();
3262 }
3263
3264 static void
3265 unknown(
3266 char opt,
3267 char *s)
3268 {
3269 fprintf(stderr, _("unknown option -%c %s\n"), opt, s);
3270 usage();
3271 }
3272
3273 long long
3274 cvtnum(
3275 unsigned int blksize,
3276 unsigned int sectsize,
3277 const char *s)
3278 {
3279 long long i;
3280 char *sp;
3281 int c;
3282
3283 i = strtoll(s, &sp, 0);
3284 if (i == 0 && sp == s)
3285 return -1LL;
3286 if (*sp == '\0')
3287 return i;
3288
3289 if (sp[1] != '\0')
3290 return -1LL;
3291
3292 if (*sp == 'b')
3293 return i * blksize;
3294 if (*sp == 's')
3295 return i * sectsize;
3296
3297 c = tolower(*sp);
3298 switch (c) {
3299 case 'e':
3300 i *= 1024LL;
3301 /* fall through */
3302 case 'p':
3303 i *= 1024LL;
3304 /* fall through */
3305 case 't':
3306 i *= 1024LL;
3307 /* fall through */
3308 case 'g':
3309 i *= 1024LL;
3310 /* fall through */
3311 case 'm':
3312 i *= 1024LL;
3313 /* fall through */
3314 case 'k':
3315 return i * 1024LL;
3316 default:
3317 break;
3318 }
3319 return -1LL;
3320 }
3321
3322 static void __attribute__((noreturn))
3323 usage( void )
3324 {
3325 fprintf(stderr, _("Usage: %s\n\
3326 /* blocksize */ [-b log=n|size=num]\n\
3327 /* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx]\n\
3328 /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
3329 (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
3330 sectlog=n|sectsize=num\n\
3331 /* force overwrite */ [-f]\n\
3332 /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
3333 projid32bit=0|1,sparse=0|1]\n\
3334 /* no discard */ [-K]\n\
3335 /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
3336 sunit=value|su=num,sectlog=n|sectsize=num,\n\
3337 lazy-count=0|1]\n\
3338 /* label */ [-L label (maximum 12 characters)]\n\
3339 /* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\
3340 /* no-op info only */ [-N]\n\
3341 /* prototype file */ [-p fname]\n\
3342 /* quiet */ [-q]\n\
3343 /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\
3344 /* sectorsize */ [-s log=n|size=num]\n\
3345 /* version */ [-V]\n\
3346 devicename\n\
3347 <devicename> is required unless -d name=xxx is given.\n\
3348 <num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\
3349 xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\
3350 <value> is xxx (512 byte blocks).\n"),
3351 progname);
3352 exit(1);
3353 }