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