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