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