]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - mkfs/xfs_mkfs.c
mkfs.xfs: Don't stagger AG for a single disk
[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)
2538 && (dswidth != dsunit)
2539 && (agcount > 1)) {
2540 /* This is a non-optimal configuration because all AGs
2541 * start on the same disk in the stripe. Changing
2542 * the AG size by one sunit will guarantee that this
2543 * does not happen.
2544 */
2545 tmp_agsize = agsize - dsunit;
2546 if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
2547 tmp_agsize = agsize + dsunit;
2548 if (dblocks < agsize) {
2549 /* oh well, nothing to do */
2550 tmp_agsize = agsize;
2551 }
2552 }
2553 if (daflag || dasize) {
2554 fprintf(stderr, _(
2555 "Warning: AG size is a multiple of stripe width. This can cause performance\n\
2556 problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
2557 an AG size that is one stripe unit smaller, for example %llu.\n"),
2558 (unsigned long long)tmp_agsize);
2559 } else {
2560 agsize = tmp_agsize;
2561 agcount = dblocks/agsize + (dblocks % agsize != 0);
2562 /*
2563 * If the last AG is too small, reduce the
2564 * filesystem size and drop the blocks.
2565 */
2566 if ( dblocks % agsize != 0 &&
2567 (dblocks % agsize <
2568 XFS_AG_MIN_BLOCKS(blocklog))) {
2569 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
2570 agcount--;
2571 ASSERT(agcount != 0);
2572 }
2573 }
2574 }
2575 } else {
2576 if (nodsflag)
2577 dsunit = dswidth = 0;
2578 else {
2579 fprintf(stderr,
2580 _("%s: Stripe unit(%d) or stripe width(%d) is "
2581 "not a multiple of the block size(%d)\n"),
2582 progname, BBTOB(dsunit), BBTOB(dswidth),
2583 blocksize);
2584 exit(1);
2585 }
2586 }
2587
2588 /*
2589 * If the last AG is too small, reduce the filesystem size
2590 * and drop the blocks.
2591 */
2592 if ( dblocks % agsize != 0 &&
2593 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
2594 ASSERT(!daflag);
2595 dblocks = (xfs_rfsblock_t)((agcount - 1) * agsize);
2596 agcount--;
2597 ASSERT(agcount != 0);
2598 }
2599
2600 validate_ag_geometry(blocklog, dblocks, agsize, agcount);
2601
2602 if (!imflag)
2603 imaxpct = calc_default_imaxpct(blocklog, dblocks);
2604
2605 /*
2606 * check that log sunit is modulo fsblksize or default it to dsunit.
2607 */
2608
2609 if (lsunit) {
2610 /* convert from 512 byte blocks to fs blocks */
2611 lsunit = DTOBT(lsunit);
2612 } else if (sb_feat.log_version == 2 && loginternal && dsunit) {
2613 /* lsunit and dsunit now in fs blocks */
2614 lsunit = dsunit;
2615 }
2616
2617 if (sb_feat.log_version == 2 && (lsunit * blocksize) > 256 * 1024) {
2618 /* Warn only if specified on commandline */
2619 if (lsuflag || lsunitflag) {
2620 fprintf(stderr,
2621 _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"),
2622 (lsunit * blocksize));
2623 fprintf(stderr,
2624 _("log stripe unit adjusted to 32KiB\n"));
2625 }
2626 lsunit = (32 * 1024) >> blocklog;
2627 }
2628
2629 min_logblocks = max_trans_res(agsize,
2630 sb_feat.crcs_enabled, sb_feat.dir_version,
2631 sectorlog, blocklog, inodelog, dirblocklog,
2632 sb_feat.log_version, lsunit, sb_feat.finobt,
2633 sb_feat.rmapbt, sb_feat.reflink,
2634 sb_feat.inode_align);
2635 ASSERT(min_logblocks);
2636 min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks);
2637 if (!logsize && dblocks >= (1024*1024*1024) >> blocklog)
2638 min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog);
2639 if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) {
2640 fprintf(stderr,
2641 _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
2642 logsize, (long long)DTOBT(xi.logBBsize));
2643 usage();
2644 } else if (!logsize && xi.logBBsize > 0) {
2645 logblocks = DTOBT(xi.logBBsize);
2646 } else if (logsize && !xi.logdev && !loginternal) {
2647 fprintf(stderr,
2648 _("size specified for non-existent log subvolume\n"));
2649 usage();
2650 } else if (loginternal && logsize && logblocks >= dblocks) {
2651 fprintf(stderr, _("size %lld too large for internal log\n"),
2652 (long long)logblocks);
2653 usage();
2654 } else if (!loginternal && !xi.logdev) {
2655 logblocks = 0;
2656 } else if (loginternal && !logsize) {
2657
2658 if (dblocks < GIGABYTES(1, blocklog)) {
2659 /* tiny filesystems get minimum sized logs. */
2660 logblocks = min_logblocks;
2661 } else if (dblocks < GIGABYTES(16, blocklog)) {
2662
2663 /*
2664 * For small filesystems, we want to use the
2665 * XFS_MIN_LOG_BYTES for filesystems smaller than 16G if
2666 * at all possible, ramping up to 128MB at 256GB.
2667 */
2668 logblocks = MIN(XFS_MIN_LOG_BYTES >> blocklog,
2669 min_logblocks * XFS_DFL_LOG_FACTOR);
2670 } else {
2671 /*
2672 * With a 2GB max log size, default to maximum size
2673 * at 4TB. This keeps the same ratio from the older
2674 * max log size of 128M at 256GB fs size. IOWs,
2675 * the ratio of fs size to log size is 2048:1.
2676 */
2677 logblocks = (dblocks << blocklog) / 2048;
2678 logblocks = logblocks >> blocklog;
2679 }
2680
2681 /* Ensure the chosen size meets minimum log size requirements */
2682 logblocks = MAX(min_logblocks, logblocks);
2683
2684 /* make sure the log fits wholly within an AG */
2685 if (logblocks >= agsize)
2686 logblocks = min_logblocks;
2687
2688 /* and now clamp the size to the maximum supported size */
2689 logblocks = MIN(logblocks, XFS_MAX_LOG_BLOCKS);
2690 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES)
2691 logblocks = XFS_MAX_LOG_BYTES >> blocklog;
2692
2693 }
2694 validate_log_size(logblocks, blocklog, min_logblocks);
2695
2696 protostring = setup_proto(protofile);
2697 bsize = 1 << (blocklog - BBSHIFT);
2698 mp = &mbuf;
2699 sbp = &mp->m_sb;
2700 memset(mp, 0, sizeof(xfs_mount_t));
2701 sbp->sb_blocklog = (uint8_t)blocklog;
2702 sbp->sb_sectlog = (uint8_t)sectorlog;
2703 sbp->sb_agblklog = (uint8_t)libxfs_log2_roundup((unsigned int)agsize);
2704 sbp->sb_agblocks = (xfs_agblock_t)agsize;
2705 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
2706 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
2707
2708 /*
2709 * sb_versionnum, finobt and rmapbt flags must be set before we use
2710 * libxfs_prealloc_blocks().
2711 */
2712 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
2713
2714
2715 if (loginternal) {
2716 /*
2717 * Readjust the log size to fit within an AG if it was sized
2718 * automatically.
2719 */
2720 if (!logsize) {
2721 logblocks = MIN(logblocks,
2722 libxfs_alloc_ag_max_usable(mp));
2723
2724 /* revalidate the log size is valid if we changed it */
2725 validate_log_size(logblocks, blocklog, min_logblocks);
2726 }
2727 if (logblocks > agsize - libxfs_prealloc_blocks(mp)) {
2728 fprintf(stderr,
2729 _("internal log size %lld too large, must fit in allocation group\n"),
2730 (long long)logblocks);
2731 usage();
2732 }
2733
2734 if (laflag) {
2735 if (logagno >= agcount) {
2736 fprintf(stderr,
2737 _("log ag number %d too large, must be less than %lld\n"),
2738 logagno, (long long)agcount);
2739 usage();
2740 }
2741 } else
2742 logagno = (xfs_agnumber_t)(agcount / 2);
2743
2744 logstart = XFS_AGB_TO_FSB(mp, logagno, libxfs_prealloc_blocks(mp));
2745 /*
2746 * Align the logstart at stripe unit boundary.
2747 */
2748 if (lsunit) {
2749 logstart = fixup_internal_log_stripe(mp,
2750 lsflag, logstart, agsize, lsunit,
2751 &logblocks, blocklog, &lalign);
2752 } else if (dsunit) {
2753 logstart = fixup_internal_log_stripe(mp,
2754 lsflag, logstart, agsize, dsunit,
2755 &logblocks, blocklog, &lalign);
2756 }
2757 } else {
2758 logstart = 0;
2759 if (lsunit)
2760 fixup_log_stripe_unit(lsflag, lsunit,
2761 &logblocks, blocklog);
2762 }
2763 validate_log_size(logblocks, blocklog, min_logblocks);
2764
2765 if (!qflag || Nflag) {
2766 printf(_(
2767 "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
2768 " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
2769 " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u, reflink=%u\n"
2770 "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
2771 " =%-22s sunit=%-6u swidth=%u blks\n"
2772 "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n"
2773 "log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
2774 " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
2775 "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
2776 dfile, isize, (long long)agcount, (long long)agsize,
2777 "", sectorsize, sb_feat.attr_version,
2778 !sb_feat.projid16bit,
2779 "", sb_feat.crcs_enabled, sb_feat.finobt, sb_feat.spinodes,
2780 sb_feat.rmapbt, sb_feat.reflink,
2781 "", blocksize, (long long)dblocks, imaxpct,
2782 "", dsunit, dswidth,
2783 sb_feat.dir_version, dirblocksize, sb_feat.nci,
2784 sb_feat.dirftype,
2785 logfile, 1 << blocklog, (long long)logblocks,
2786 sb_feat.log_version, "", lsectorsize, lsunit,
2787 sb_feat.lazy_sb_counters,
2788 rtfile, rtextblocks << blocklog,
2789 (long long)rtblocks, (long long)rtextents);
2790 if (Nflag)
2791 exit(0);
2792 }
2793
2794 if (label)
2795 strncpy(sbp->sb_fname, label, sizeof(sbp->sb_fname));
2796 sbp->sb_magicnum = XFS_SB_MAGIC;
2797 sbp->sb_blocksize = blocksize;
2798 sbp->sb_dblocks = dblocks;
2799 sbp->sb_rblocks = rtblocks;
2800 sbp->sb_rextents = rtextents;
2801 platform_uuid_copy(&sbp->sb_uuid, &uuid);
2802 /* Only in memory; libxfs expects this as if read from disk */
2803 platform_uuid_copy(&sbp->sb_meta_uuid, &uuid);
2804 sbp->sb_logstart = logstart;
2805 sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
2806 sbp->sb_rextsize = rtextblocks;
2807 sbp->sb_agcount = (xfs_agnumber_t)agcount;
2808 sbp->sb_rbmblocks = nbmblocks;
2809 sbp->sb_logblocks = (xfs_extlen_t)logblocks;
2810 sbp->sb_sectsize = (uint16_t)sectorsize;
2811 sbp->sb_inodesize = (uint16_t)isize;
2812 sbp->sb_inopblock = (uint16_t)(blocksize / isize);
2813 sbp->sb_sectlog = (uint8_t)sectorlog;
2814 sbp->sb_inodelog = (uint8_t)inodelog;
2815 sbp->sb_inopblog = (uint8_t)(blocklog - inodelog);
2816 sbp->sb_rextslog =
2817 (uint8_t)(rtextents ?
2818 libxfs_highbit32((unsigned int)rtextents) : 0);
2819 sbp->sb_inprogress = 1; /* mkfs is in progress */
2820 sbp->sb_imax_pct = imaxpct;
2821 sbp->sb_icount = 0;
2822 sbp->sb_ifree = 0;
2823 sbp->sb_fdblocks = dblocks - agcount * libxfs_prealloc_blocks(mp) -
2824 (loginternal ? logblocks : 0);
2825 sbp->sb_frextents = 0; /* will do a free later */
2826 sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
2827 sbp->sb_qflags = 0;
2828 sbp->sb_unit = dsunit;
2829 sbp->sb_width = dswidth;
2830 sbp->sb_dirblklog = dirblocklog - blocklog;
2831 if (sb_feat.log_version == 2) { /* This is stored in bytes */
2832 lsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit);
2833 sbp->sb_logsunit = lsunit;
2834 } else
2835 sbp->sb_logsunit = 0;
2836 if (sb_feat.inode_align) {
2837 int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
2838 if (sb_feat.crcs_enabled)
2839 cluster_size *= isize / XFS_DINODE_MIN_SIZE;
2840 sbp->sb_inoalignmt = cluster_size >> blocklog;
2841 sb_feat.inode_align = sbp->sb_inoalignmt != 0;
2842 } else
2843 sbp->sb_inoalignmt = 0;
2844 if (lsectorsize != BBSIZE || sectorsize != BBSIZE) {
2845 sbp->sb_logsectlog = (uint8_t)lsectorlog;
2846 sbp->sb_logsectsize = (uint16_t)lsectorsize;
2847 } else {
2848 sbp->sb_logsectlog = 0;
2849 sbp->sb_logsectsize = 0;
2850 }
2851
2852 sb_set_features(&mp->m_sb, &sb_feat, sectorsize, lsectorsize, dsunit);
2853
2854 if (force_overwrite)
2855 zero_old_xfs_structures(&xi, sbp);
2856
2857 /*
2858 * Zero out the beginning of the device, to obliterate any old
2859 * filesystem signatures out there. This should take care of
2860 * swap (somewhere around the page size), jfs (32k),
2861 * ext[2,3] and reiserfs (64k) - and hopefully all else.
2862 */
2863 libxfs_buftarg_init(mp, xi.ddev, xi.logdev, xi.rtdev);
2864 buf = libxfs_getbuf(mp->m_ddev_targp, 0, BTOBB(WHACK_SIZE));
2865 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
2866 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2867 libxfs_purgebuf(buf);
2868
2869 /* OK, now write the superblock */
2870 buf = libxfs_getbuf(mp->m_ddev_targp, XFS_SB_DADDR, XFS_FSS_TO_BB(mp, 1));
2871 buf->b_ops = &xfs_sb_buf_ops;
2872 memset(XFS_BUF_PTR(buf), 0, sectorsize);
2873 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
2874 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2875 libxfs_purgebuf(buf);
2876
2877 /*
2878 * If the data area is a file, then grow it out to its final size
2879 * if needed so that the reads for the end of the device in the mount
2880 * code will succeed.
2881 */
2882 if (xi.disfile && xi.dsize * xi.dbsize < dblocks * blocksize) {
2883 if (ftruncate(xi.dfd, dblocks * blocksize) < 0) {
2884 fprintf(stderr,
2885 _("%s: Growing the data section failed\n"),
2886 progname);
2887 exit(1);
2888 }
2889 }
2890
2891 /*
2892 * Zero out the end of the device, to obliterate any
2893 * old MD RAID (or other) metadata at the end of the device.
2894 * (MD sb is ~64k from the end, take out a wider swath to be sure)
2895 */
2896 if (!xi.disfile) {
2897 buf = libxfs_getbuf(mp->m_ddev_targp,
2898 (xi.dsize - BTOBB(WHACK_SIZE)),
2899 BTOBB(WHACK_SIZE));
2900 memset(XFS_BUF_PTR(buf), 0, WHACK_SIZE);
2901 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2902 libxfs_purgebuf(buf);
2903 }
2904
2905 /*
2906 * Zero the log....
2907 */
2908 libxfs_log_clear(mp->m_logdev_targp, NULL,
2909 XFS_FSB_TO_DADDR(mp, logstart),
2910 (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks),
2911 &sbp->sb_uuid, sb_feat.log_version, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
2912
2913 mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0);
2914 if (mp == NULL) {
2915 fprintf(stderr, _("%s: filesystem failed to initialize\n"),
2916 progname);
2917 exit(1);
2918 }
2919
2920 /*
2921 * XXX: this code is effectively shared with the kernel growfs code.
2922 * These initialisations should be pulled into libxfs to keep the
2923 * kernel/userspace header initialisation code the same.
2924 */
2925 for (agno = 0; agno < agcount; agno++) {
2926 struct xfs_agfl *agfl;
2927 int bucket;
2928 struct xfs_perag *pag = libxfs_perag_get(mp, agno);
2929
2930 /*
2931 * Superblock.
2932 */
2933 buf = libxfs_getbuf(mp->m_ddev_targp,
2934 XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
2935 XFS_FSS_TO_BB(mp, 1));
2936 buf->b_ops = &xfs_sb_buf_ops;
2937 memset(XFS_BUF_PTR(buf), 0, sectorsize);
2938 libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
2939 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2940
2941 /*
2942 * AG header block: freespace
2943 */
2944 buf = libxfs_getbuf(mp->m_ddev_targp,
2945 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
2946 XFS_FSS_TO_BB(mp, 1));
2947 buf->b_ops = &xfs_agf_buf_ops;
2948 agf = XFS_BUF_TO_AGF(buf);
2949 memset(agf, 0, sectorsize);
2950 if (agno == agcount - 1)
2951 agsize = dblocks - (xfs_rfsblock_t)(agno * agsize);
2952 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
2953 agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
2954 agf->agf_seqno = cpu_to_be32(agno);
2955 agf->agf_length = cpu_to_be32(agsize);
2956 agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
2957 agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
2958 agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
2959 agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
2960 pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
2961 pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
2962 if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
2963 agf->agf_roots[XFS_BTNUM_RMAPi] =
2964 cpu_to_be32(XFS_RMAP_BLOCK(mp));
2965 agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
2966 agf->agf_rmap_blocks = cpu_to_be32(1);
2967 }
2968 if (xfs_sb_version_hasreflink(&mp->m_sb)) {
2969 agf->agf_refcount_root = cpu_to_be32(
2970 libxfs_refc_block(mp));
2971 agf->agf_refcount_level = cpu_to_be32(1);
2972 agf->agf_refcount_blocks = cpu_to_be32(1);
2973 }
2974 agf->agf_flfirst = 0;
2975 agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
2976 agf->agf_flcount = 0;
2977 nbmblocks = (xfs_extlen_t)(agsize - libxfs_prealloc_blocks(mp));
2978 agf->agf_freeblks = cpu_to_be32(nbmblocks);
2979 agf->agf_longest = cpu_to_be32(nbmblocks);
2980 if (xfs_sb_version_hascrc(&mp->m_sb))
2981 platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
2982
2983 if (loginternal && agno == logagno) {
2984 be32_add_cpu(&agf->agf_freeblks, -logblocks);
2985 agf->agf_longest = cpu_to_be32(agsize -
2986 XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
2987 }
2988 if (libxfs_alloc_min_freelist(mp, pag) > worst_freelist)
2989 worst_freelist = libxfs_alloc_min_freelist(mp, pag);
2990 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
2991
2992 /*
2993 * AG freelist header block
2994 */
2995 buf = libxfs_getbuf(mp->m_ddev_targp,
2996 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
2997 XFS_FSS_TO_BB(mp, 1));
2998 buf->b_ops = &xfs_agfl_buf_ops;
2999 agfl = XFS_BUF_TO_AGFL(buf);
3000 /* setting to 0xff results in initialisation to NULLAGBLOCK */
3001 memset(agfl, 0xff, sectorsize);
3002 if (xfs_sb_version_hascrc(&mp->m_sb)) {
3003 agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
3004 agfl->agfl_seqno = cpu_to_be32(agno);
3005 platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
3006 for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
3007 agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
3008 }
3009
3010 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3011
3012 /*
3013 * AG header block: inodes
3014 */
3015 buf = libxfs_getbuf(mp->m_ddev_targp,
3016 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
3017 XFS_FSS_TO_BB(mp, 1));
3018 agi = XFS_BUF_TO_AGI(buf);
3019 buf->b_ops = &xfs_agi_buf_ops;
3020 memset(agi, 0, sectorsize);
3021 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
3022 agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
3023 agi->agi_seqno = cpu_to_be32(agno);
3024 agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize);
3025 agi->agi_count = 0;
3026 agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
3027 agi->agi_level = cpu_to_be32(1);
3028 if (sb_feat.finobt) {
3029 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
3030 agi->agi_free_level = cpu_to_be32(1);
3031 }
3032 agi->agi_freecount = 0;
3033 agi->agi_newino = cpu_to_be32(NULLAGINO);
3034 agi->agi_dirino = cpu_to_be32(NULLAGINO);
3035 if (xfs_sb_version_hascrc(&mp->m_sb))
3036 platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
3037 for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
3038 agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
3039 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3040
3041 /*
3042 * BNO btree root block
3043 */
3044 buf = libxfs_getbuf(mp->m_ddev_targp,
3045 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
3046 bsize);
3047 buf->b_ops = &xfs_allocbt_buf_ops;
3048 block = XFS_BUF_TO_BLOCK(buf);
3049 memset(block, 0, blocksize);
3050 libxfs_btree_init_block(mp, buf, XFS_BTNUM_BNO, 0, 1, agno, 0);
3051
3052 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3053 arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
3054 if (loginternal && agno == logagno) {
3055 if (lalign) {
3056 /*
3057 * Have to insert two records
3058 * Insert pad record for stripe align of log
3059 */
3060 arec->ar_blockcount = cpu_to_be32(
3061 XFS_FSB_TO_AGBNO(mp, logstart) -
3062 be32_to_cpu(arec->ar_startblock));
3063 nrec = arec + 1;
3064 /*
3065 * Insert record at start of internal log
3066 */
3067 nrec->ar_startblock = cpu_to_be32(
3068 be32_to_cpu(arec->ar_startblock) +
3069 be32_to_cpu(arec->ar_blockcount));
3070 arec = nrec;
3071 be16_add_cpu(&block->bb_numrecs, 1);
3072 }
3073 /*
3074 * Change record start to after the internal log
3075 */
3076 be32_add_cpu(&arec->ar_startblock, logblocks);
3077 }
3078 /*
3079 * Calculate the record block count and check for the case where
3080 * the log might have consumed all available space in the AG. If
3081 * so, reset the record count to 0 to avoid exposure of an invalid
3082 * record start block.
3083 */
3084 arec->ar_blockcount = cpu_to_be32(agsize -
3085 be32_to_cpu(arec->ar_startblock));
3086 if (!arec->ar_blockcount)
3087 block->bb_numrecs = 0;
3088
3089 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3090
3091 /*
3092 * CNT btree root block
3093 */
3094 buf = libxfs_getbuf(mp->m_ddev_targp,
3095 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
3096 bsize);
3097 buf->b_ops = &xfs_allocbt_buf_ops;
3098 block = XFS_BUF_TO_BLOCK(buf);
3099 memset(block, 0, blocksize);
3100 libxfs_btree_init_block(mp, buf, XFS_BTNUM_CNT, 0, 1, agno, 0);
3101
3102 arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
3103 arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
3104 if (loginternal && agno == logagno) {
3105 if (lalign) {
3106 arec->ar_blockcount = cpu_to_be32(
3107 XFS_FSB_TO_AGBNO(mp, logstart) -
3108 be32_to_cpu(arec->ar_startblock));
3109 nrec = arec + 1;
3110 nrec->ar_startblock = cpu_to_be32(
3111 be32_to_cpu(arec->ar_startblock) +
3112 be32_to_cpu(arec->ar_blockcount));
3113 arec = nrec;
3114 be16_add_cpu(&block->bb_numrecs, 1);
3115 }
3116 be32_add_cpu(&arec->ar_startblock, logblocks);
3117 }
3118 /*
3119 * Calculate the record block count and check for the case where
3120 * the log might have consumed all available space in the AG. If
3121 * so, reset the record count to 0 to avoid exposure of an invalid
3122 * record start block.
3123 */
3124 arec->ar_blockcount = cpu_to_be32(agsize -
3125 be32_to_cpu(arec->ar_startblock));
3126 if (!arec->ar_blockcount)
3127 block->bb_numrecs = 0;
3128
3129 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3130
3131 /*
3132 * refcount btree root block
3133 */
3134 if (xfs_sb_version_hasreflink(&mp->m_sb)) {
3135 buf = libxfs_getbuf(mp->m_ddev_targp,
3136 XFS_AGB_TO_DADDR(mp, agno,
3137 libxfs_refc_block(mp)),
3138 bsize);
3139 buf->b_ops = &xfs_refcountbt_buf_ops;
3140
3141 block = XFS_BUF_TO_BLOCK(buf);
3142 memset(block, 0, blocksize);
3143 libxfs_btree_init_block(mp, buf, XFS_BTNUM_REFC, 0,
3144 0, agno, 0);
3145
3146 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3147 }
3148
3149 /*
3150 * INO btree root block
3151 */
3152 buf = libxfs_getbuf(mp->m_ddev_targp,
3153 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
3154 bsize);
3155 buf->b_ops = &xfs_inobt_buf_ops;
3156 block = XFS_BUF_TO_BLOCK(buf);
3157 memset(block, 0, blocksize);
3158 libxfs_btree_init_block(mp, buf, XFS_BTNUM_INO, 0, 0, agno, 0);
3159 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3160
3161 /*
3162 * Free INO btree root block
3163 */
3164 if (sb_feat.finobt) {
3165 buf = libxfs_getbuf(mp->m_ddev_targp,
3166 XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
3167 bsize);
3168 buf->b_ops = &xfs_inobt_buf_ops;
3169 block = XFS_BUF_TO_BLOCK(buf);
3170 memset(block, 0, blocksize);
3171 libxfs_btree_init_block(mp, buf, XFS_BTNUM_FINO, 0, 0, agno, 0);
3172 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3173 }
3174
3175 /* RMAP btree root block */
3176 if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
3177 struct xfs_rmap_rec *rrec;
3178
3179 buf = libxfs_getbuf(mp->m_ddev_targp,
3180 XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)),
3181 bsize);
3182 buf->b_ops = &xfs_rmapbt_buf_ops;
3183 block = XFS_BUF_TO_BLOCK(buf);
3184 memset(block, 0, blocksize);
3185
3186 libxfs_btree_init_block(mp, buf, XFS_BTNUM_RMAP, 0, 0, agno, 0);
3187
3188 /*
3189 * mark the AG header regions as static metadata
3190 * The BNO btree block is the first block after the
3191 * headers, so it's location defines the size of region
3192 * the static metadata consumes.
3193 */
3194 rrec = XFS_RMAP_REC_ADDR(block, 1);
3195 rrec->rm_startblock = 0;
3196 rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
3197 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
3198 rrec->rm_offset = 0;
3199 be16_add_cpu(&block->bb_numrecs, 1);
3200
3201 /* account freespace btree root blocks */
3202 rrec = XFS_RMAP_REC_ADDR(block, 2);
3203 rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
3204 rrec->rm_blockcount = cpu_to_be32(2);
3205 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
3206 rrec->rm_offset = 0;
3207 be16_add_cpu(&block->bb_numrecs, 1);
3208
3209 /* account inode btree root blocks */
3210 rrec = XFS_RMAP_REC_ADDR(block, 3);
3211 rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
3212 rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
3213 XFS_IBT_BLOCK(mp));
3214 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
3215 rrec->rm_offset = 0;
3216 be16_add_cpu(&block->bb_numrecs, 1);
3217
3218 /* account for rmap btree root */
3219 rrec = XFS_RMAP_REC_ADDR(block, 4);
3220 rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
3221 rrec->rm_blockcount = cpu_to_be32(1);
3222 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
3223 rrec->rm_offset = 0;
3224 be16_add_cpu(&block->bb_numrecs, 1);
3225
3226 /* account for refcount btree root */
3227 if (xfs_sb_version_hasreflink(&mp->m_sb)) {
3228 rrec = XFS_RMAP_REC_ADDR(block, 5);
3229 rrec->rm_startblock = cpu_to_be32(
3230 libxfs_refc_block(mp));
3231 rrec->rm_blockcount = cpu_to_be32(1);
3232 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
3233 rrec->rm_offset = 0;
3234 be16_add_cpu(&block->bb_numrecs, 1);
3235 }
3236
3237 /* account for the log space */
3238 if (loginternal && agno == logagno) {
3239 rrec = XFS_RMAP_REC_ADDR(block,
3240 be16_to_cpu(block->bb_numrecs) + 1);
3241 rrec->rm_startblock = cpu_to_be32(
3242 XFS_FSB_TO_AGBNO(mp, logstart));
3243 rrec->rm_blockcount = cpu_to_be32(logblocks);
3244 rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
3245 rrec->rm_offset = 0;
3246 be16_add_cpu(&block->bb_numrecs, 1);
3247 }
3248
3249 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3250 }
3251
3252 libxfs_perag_put(pag);
3253 }
3254
3255 /*
3256 * Touch last block, make fs the right size if it's a file.
3257 */
3258 buf = libxfs_getbuf(mp->m_ddev_targp,
3259 (xfs_daddr_t)XFS_FSB_TO_BB(mp, dblocks - 1LL), bsize);
3260 memset(XFS_BUF_PTR(buf), 0, blocksize);
3261 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3262
3263 /*
3264 * Make sure we can write the last block in the realtime area.
3265 */
3266 if (mp->m_rtdev_targp->dev && rtblocks > 0) {
3267 buf = libxfs_getbuf(mp->m_rtdev_targp,
3268 XFS_FSB_TO_BB(mp, rtblocks - 1LL), bsize);
3269 memset(XFS_BUF_PTR(buf), 0, blocksize);
3270 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3271 }
3272
3273 /*
3274 * BNO, CNT free block list
3275 */
3276 for (agno = 0; agno < agcount; agno++) {
3277 xfs_alloc_arg_t args;
3278 xfs_trans_t *tp;
3279 struct xfs_trans_res tres = {0};
3280
3281 c = libxfs_trans_alloc(mp, &tres, worst_freelist, 0, 0, &tp);
3282 if (c)
3283 res_failed(c);
3284
3285 memset(&args, 0, sizeof(args));
3286 args.tp = tp;
3287 args.mp = mp;
3288 args.agno = agno;
3289 args.alignment = 1;
3290 args.pag = libxfs_perag_get(mp,agno);
3291
3292 libxfs_alloc_fix_freelist(&args, 0);
3293 libxfs_perag_put(args.pag);
3294 libxfs_trans_commit(tp);
3295 }
3296
3297 /*
3298 * Allocate the root inode and anything else in the proto file.
3299 */
3300 parse_proto(mp, &fsx, &protostring);
3301
3302 /*
3303 * Protect ourselves against possible stupidity
3304 */
3305 if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
3306 fprintf(stderr,
3307 _("%s: root inode created in AG %u, not AG 0\n"),
3308 progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
3309 exit(1);
3310 }
3311
3312 /*
3313 * Write out multiple secondary superblocks with rootinode field set
3314 */
3315 if (mp->m_sb.sb_agcount > 1) {
3316 /*
3317 * the last superblock
3318 */
3319 buf = libxfs_readbuf(mp->m_dev,
3320 XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount-1,
3321 XFS_SB_DADDR),
3322 XFS_FSS_TO_BB(mp, 1),
3323 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3324 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
3325 mp->m_sb.sb_rootino);
3326 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3327 /*
3328 * and one in the middle for luck
3329 */
3330 if (mp->m_sb.sb_agcount > 2) {
3331 buf = libxfs_readbuf(mp->m_dev,
3332 XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount-1)/2,
3333 XFS_SB_DADDR),
3334 XFS_FSS_TO_BB(mp, 1),
3335 LIBXFS_EXIT_ON_FAILURE, &xfs_sb_buf_ops);
3336 XFS_BUF_TO_SBP(buf)->sb_rootino = cpu_to_be64(
3337 mp->m_sb.sb_rootino);
3338 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3339 }
3340 }
3341
3342 /*
3343 * Dump all inodes and buffers before marking us all done.
3344 * Need to drop references to inodes we still hold, first.
3345 */
3346 libxfs_rtmount_destroy(mp);
3347 libxfs_bcache_purge();
3348
3349 /*
3350 * Mark the filesystem ok.
3351 */
3352 buf = libxfs_getsb(mp, LIBXFS_EXIT_ON_FAILURE);
3353 (XFS_BUF_TO_SBP(buf))->sb_inprogress = 0;
3354 libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
3355
3356 libxfs_umount(mp);
3357 if (xi.rtdev)
3358 libxfs_device_close(xi.rtdev);
3359 if (xi.logdev && xi.logdev != xi.ddev)
3360 libxfs_device_close(xi.logdev);
3361 libxfs_device_close(xi.ddev);
3362
3363 return 0;
3364 }
3365
3366 static void
3367 conflict(
3368 char opt,
3369 char *tab[],
3370 int oldidx,
3371 int newidx)
3372 {
3373 fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
3374 opt, tab[oldidx], opt, tab[newidx]);
3375 usage();
3376 }
3377
3378
3379 static void
3380 illegal(
3381 const char *value,
3382 const char *opt)
3383 {
3384 fprintf(stderr, _("Illegal value %s for -%s option\n"), value, opt);
3385 usage();
3386 }
3387
3388 static int
3389 ispow2(
3390 unsigned int i)
3391 {
3392 return (i & (i - 1)) == 0;
3393 }
3394
3395 static void __attribute__((noreturn))
3396 reqval(
3397 char opt,
3398 char *tab[],
3399 int idx)
3400 {
3401 fprintf(stderr, _("-%c %s option requires a value\n"), opt, tab[idx]);
3402 usage();
3403 }
3404
3405 static void
3406 respec(
3407 char opt,
3408 char *tab[],
3409 int idx)
3410 {
3411 fprintf(stderr, "-%c ", opt);
3412 if (tab)
3413 fprintf(stderr, "%s ", tab[idx]);
3414 fprintf(stderr, _("option respecified\n"));
3415 usage();
3416 }
3417
3418 static void
3419 unknown(
3420 char opt,
3421 char *s)
3422 {
3423 fprintf(stderr, _("unknown option -%c %s\n"), opt, s);
3424 usage();
3425 }
3426
3427 long long
3428 cvtnum(
3429 unsigned int blksize,
3430 unsigned int sectsize,
3431 const char *s)
3432 {
3433 long long i;
3434 char *sp;
3435 int c;
3436
3437 i = strtoll(s, &sp, 0);
3438 if (i == 0 && sp == s)
3439 return -1LL;
3440 if (*sp == '\0')
3441 return i;
3442
3443 if (sp[1] != '\0')
3444 return -1LL;
3445
3446 if (*sp == 'b') {
3447 if (!blksize) {
3448 fprintf(stderr,
3449 _("Blocksize must be provided prior to using 'b' suffix.\n"));
3450 usage();
3451 } else {
3452 return i * blksize;
3453 }
3454 }
3455 if (*sp == 's') {
3456 if (!sectsize) {
3457 fprintf(stderr,
3458 _("Sectorsize must be specified prior to using 's' suffix.\n"));
3459 usage();
3460 } else {
3461 return i * sectsize;
3462 }
3463 }
3464
3465 c = tolower(*sp);
3466 switch (c) {
3467 case 'e':
3468 i *= 1024LL;
3469 /* fall through */
3470 case 'p':
3471 i *= 1024LL;
3472 /* fall through */
3473 case 't':
3474 i *= 1024LL;
3475 /* fall through */
3476 case 'g':
3477 i *= 1024LL;
3478 /* fall through */
3479 case 'm':
3480 i *= 1024LL;
3481 /* fall through */
3482 case 'k':
3483 return i * 1024LL;
3484 default:
3485 break;
3486 }
3487 return -1LL;
3488 }
3489
3490 static void __attribute__((noreturn))
3491 usage( void )
3492 {
3493 fprintf(stderr, _("Usage: %s\n\
3494 /* blocksize */ [-b log=n|size=num]\n\
3495 /* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n\
3496 /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
3497 (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
3498 sectlog=n|sectsize=num\n\
3499 /* force overwrite */ [-f]\n\
3500 /* inode size */ [-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
3501 projid32bit=0|1,sparse=0|1]\n\
3502 /* no discard */ [-K]\n\
3503 /* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
3504 sunit=value|su=num,sectlog=n|sectsize=num,\n\
3505 lazy-count=0|1]\n\
3506 /* label */ [-L label (maximum 12 characters)]\n\
3507 /* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\
3508 /* no-op info only */ [-N]\n\
3509 /* prototype file */ [-p fname]\n\
3510 /* quiet */ [-q]\n\
3511 /* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\
3512 /* sectorsize */ [-s log=n|size=num]\n\
3513 /* version */ [-V]\n\
3514 devicename\n\
3515 <devicename> is required unless -d name=xxx is given.\n\
3516 <num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\
3517 xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\
3518 <value> is xxx (512 byte blocks).\n"),
3519 progname);
3520 exit(1);
3521 }