]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - mkfs/xfs_mkfs.c
libxfs: pass a struct libxfs_init to libxfs_alloc_buftarg
[thirdparty/xfsprogs-dev.git] / mkfs / xfs_mkfs.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18 5 */
660b5d96 6#include "libfrog/util.h"
6b803e5a 7#include "libxfs.h"
e4da9941 8#include <ctype.h>
4a32b9e9 9#include "xfs_multidisk.h"
82c3a179 10#include "libxcmd.h"
fee68490 11#include "libfrog/fsgeom.h"
105041e6 12#include "libfrog/convert.h"
ca14a570 13#include "libfrog/crc32cselftest.h"
b9d29568 14#include "libfrog/dahashselftest.h"
ec4e15fd 15#include "proto.h"
33c62516 16#include <ini.h>
4eee66c5
DC
17
18#define TERABYTES(count, blog) ((uint64_t)(count) << (40 - (blog)))
19#define GIGABYTES(count, blog) ((uint64_t)(count) << (30 - (blog)))
20#define MEGABYTES(count, blog) ((uint64_t)(count) << (20 - (blog)))
21
cdfa467e
ES
22/*
23 * Realistically, the log should never be smaller than 64MB. Studies by the
24 * kernel maintainer in early 2022 have shown a dramatic reduction in long tail
25 * latency of the xlog grant head waitqueue when running a heavy metadata
26 * update workload when the log size is at least 64MB.
27 */
28#define XFS_MIN_REALISTIC_LOG_BLOCKS(blog) (MEGABYTES(64, (blog)))
29
4eee66c5
DC
30/*
31 * Use this macro before we have superblock and mount structure to
32 * convert from basic blocks to filesystem blocks.
33 */
34#define DTOBT(d, bl) ((xfs_rfsblock_t)((d) >> ((bl) - BBSHIFT)))
35
36/*
37 * amount (in bytes) we zero at the beginning and end of the device to
38 * remove traces of other filesystems, raid superblocks, etc.
39 */
40#define WHACK_SIZE (128 * 1024)
41
627e74fd 42/*
b449c79e
DC
43 * XXX: The configured block and sector sizes are defined as global variables so
44 * that they don't need to be passed to getnum/cvtnum().
627e74fd 45 */
00ff2b10
ES
46static unsigned int blocksize;
47static unsigned int sectorsize;
627e74fd 48
64e924dd
DC
49/*
50 * Enums for each CLI parameter type are declared first so we can calculate the
51 * maximum array size needed to hold them automatically.
52 */
53enum {
2cf637cf 54 B_SIZE = 0,
64e924dd
DC
55 B_MAX_OPTS,
56};
57
33c62516
DC
58enum {
59 C_OPTFILE = 0,
60 C_MAX_OPTS,
61};
62
64e924dd
DC
63enum {
64 D_AGCOUNT = 0,
65 D_FILE,
66 D_NAME,
67 D_SIZE,
68 D_SUNIT,
69 D_SWIDTH,
70 D_AGSIZE,
71 D_SU,
72 D_SW,
64e924dd
DC
73 D_SECTSIZE,
74 D_NOALIGN,
75 D_RTINHERIT,
76 D_PROJINHERIT,
77 D_EXTSZINHERIT,
78 D_COWEXTSIZE,
64989ff3 79 D_DAXINHERIT,
64e924dd
DC
80 D_MAX_OPTS,
81};
82
83enum {
84 I_ALIGN = 0,
64e924dd
DC
85 I_MAXPCT,
86 I_PERBLOCK,
87 I_SIZE,
88 I_ATTR,
89 I_PROJID32BIT,
90 I_SPINODES,
69e72722 91 I_NREXT64,
64e924dd
DC
92 I_MAX_OPTS,
93};
94
95enum {
96 L_AGNUM = 0,
97 L_INTERNAL,
98 L_SIZE,
99 L_VERSION,
100 L_SUNIT,
101 L_SU,
102 L_DEV,
64e924dd
DC
103 L_SECTSIZE,
104 L_FILE,
105 L_NAME,
106 L_LAZYSBCNTR,
107 L_MAX_OPTS,
108};
109
110enum {
2cf637cf 111 N_SIZE = 0,
64e924dd
DC
112 N_VERSION,
113 N_FTYPE,
114 N_MAX_OPTS,
115};
116
fb22e1b1
DW
117enum {
118 P_FILE = 0,
e0aeb058 119 P_SLASHES,
fb22e1b1
DW
120 P_MAX_OPTS,
121};
122
64e924dd
DC
123enum {
124 R_EXTSIZE = 0,
125 R_SIZE,
126 R_DEV,
127 R_FILE,
128 R_NAME,
129 R_NOALIGN,
130 R_MAX_OPTS,
131};
132
133enum {
2cf637cf 134 S_SIZE = 0,
64e924dd
DC
135 S_SECTSIZE,
136 S_MAX_OPTS,
137};
138
139enum {
140 M_CRC = 0,
141 M_FINOBT,
142 M_UUID,
143 M_RMAPBT,
144 M_REFLINK,
9eb0d6eb 145 M_INOBTCNT,
e9601810 146 M_BIGTIME,
64e924dd
DC
147 M_MAX_OPTS,
148};
149
50dba818
DW
150/*
151 * Just define the max options array size manually to the largest
152 * enum right now, leaving room for a NULL terminator at the end
153 */
154#define MAX_SUBOPTS (D_MAX_OPTS + 1)
64e924dd 155
56e4d368 156#define SUBOPT_NEEDS_VAL (-1LL)
3ec1956a
DC
157#define MAX_CONFLICTS 8
158#define LAST_CONFLICT (-1)
159
2bd0ea18 160/*
a9dad670
DC
161 * Table for parsing mkfs parameters.
162 *
163 * Description of the structure members follows:
164 *
165 * name MANDATORY
166 * Name is a single char, e.g., for '-d file', name is 'd'.
167 *
ab2eef12
DC
168 * ini_section MANDATORY
169 * This field is required to connect each opt_params (that is to say, each
170 * option class) to a section in the config file. The only option class this
171 * is not required for is the config file specification class itself.
172 * The section name is a string, not longer than MAX_INI_NAME_LEN.
173 *
a9dad670
DC
174 * subopts MANDATORY
175 * Subopts is a list of strings naming suboptions. In the example above,
176 * it would contain "file". The last entry of this list has to be NULL.
177 *
178 * subopt_params MANDATORY
179 * This is a list of structs tied with subopts. For each entry in subopts,
180 * a corresponding entry has to be defined:
181 *
182 * subopt_params struct:
183 * index MANDATORY
184 * This number, starting from zero, denotes which item in subopt_params
185 * it is. The index has to be the same as is the order in subopts list,
186 * so we can access the right item both in subopt_param and subopts.
187 *
9090e187
DC
188 * seen INTERNAL
189 * Do not set this flag when definning a subopt. It is used to remeber that
190 * this subopt was already seen, for example for conflicts detection.
191 *
27ae3a59
DC
192 * str_seen INTERNAL
193 * Do not set. It is used internally for respecification, when some options
194 * has to be parsed twice - at first as a string, then later as a number.
195 *
627e74fd
DC
196 * convert OPTIONAL
197 * A flag signalling whether the user-given value can use suffixes.
198 * If you want to allow the use of user-friendly values like 13k, 42G,
199 * set it to true.
200 *
201 * is_power_2 OPTIONAL
202 * An optional flag for subopts where the given value has to be a power
203 * of two.
204 *
3ec1956a
DC
205 * conflicts MANDATORY
206 * If your subopt is in a conflict with some other option, specify it.
207 * Accepts the .index values of the conflicting subopts and the last
208 * member of this list has to be LAST_CONFLICT.
209 *
a9dad670
DC
210 * minval, maxval OPTIONAL
211 * These options are used for automatic range check and they have to be
212 * always used together in pair. If you don't want to limit the max value,
213 * use something like UINT_MAX. If no value is given, then you must either
214 * supply your own validation, or refuse any value in the 'case
215 * X_SOMETHING' block. If you forget to define the min and max value, but
216 * call a standard function for validating user's value, it will cause an
217 * error message notifying you about this issue.
218 *
219 * (Said in another way, you can't have minval and maxval both equal
220 * to zero. But if one value is different: minval=0 and maxval=1,
221 * then it is OK.)
56e4d368
DC
222 *
223 * defaultval MANDATORY
224 * The value used if user specifies the subopt, but no value.
225 * If the subopt accepts some values (-d file=[1|0]), then this
226 * sets what is used with simple specifying the subopt (-d file).
227 * A special SUBOPT_NEEDS_VAL can be used to require a user-given
228 * value in any case.
2bd0ea18 229 */
a9dad670
DC
230struct opt_params {
231 const char name;
ab2eef12
DC
232#define MAX_INI_NAME_LEN 32
233 const char ini_section[MAX_INI_NAME_LEN];
a9dad670 234 const char *subopts[MAX_SUBOPTS];
9090e187 235
a9dad670
DC
236 struct subopt_param {
237 int index;
9090e187 238 bool seen;
27ae3a59 239 bool str_seen;
627e74fd
DC
240 bool convert;
241 bool is_power_2;
cedf1c43
DC
242 struct _conflict {
243 struct opt_params *opts;
244 int subopt;
245 } conflicts[MAX_CONFLICTS];
a9dad670
DC
246 long long minval;
247 long long maxval;
56e4d368 248 long long defaultval;
a9dad670
DC
249 } subopt_params[MAX_SUBOPTS];
250};
251
6c75555e
DC
252/*
253 * The two dimensional conflict array requires some initialisations to know
254 * about tables that haven't yet been defined. Work around this ordering
255 * issue with extern definitions here.
256 */
00ff2b10 257static struct opt_params sopts;
6c75555e 258
00ff2b10 259static struct opt_params bopts = {
a9dad670 260 .name = 'b',
ab2eef12 261 .ini_section = "block",
a9dad670 262 .subopts = {
64e924dd 263 [B_SIZE] = "size",
50dba818 264 [B_MAX_OPTS] = NULL,
a9dad670
DC
265 },
266 .subopt_params = {
a9dad670 267 { .index = B_SIZE,
627e74fd
DC
268 .convert = true,
269 .is_power_2 = true,
2cf637cf 270 .conflicts = { { NULL, LAST_CONFLICT } },
a9dad670
DC
271 .minval = XFS_MIN_BLOCKSIZE,
272 .maxval = XFS_MAX_BLOCKSIZE,
56e4d368 273 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
274 },
275 },
2bd0ea18
NS
276};
277
33c62516
DC
278/*
279 * Config file specification. Usage is:
280 *
281 * mkfs.xfs -c options=<name>
282 *
283 * A subopt is used for the filename so in future we can extend the behaviour
284 * of the config file (e.g. specified defaults rather than options) if we ever
285 * have a need to do that sort of thing.
286 */
287static struct opt_params copts = {
288 .name = 'c',
289 .subopts = {
290 [C_OPTFILE] = "options",
50dba818 291 [C_MAX_OPTS] = NULL,
33c62516
DC
292 },
293 .subopt_params = {
294 { .index = C_OPTFILE,
295 .conflicts = { { NULL, LAST_CONFLICT } },
296 .defaultval = SUBOPT_NEEDS_VAL,
297 },
298 },
299};
300
00ff2b10 301static struct opt_params dopts = {
a9dad670 302 .name = 'd',
ab2eef12 303 .ini_section = "data",
a9dad670 304 .subopts = {
64e924dd
DC
305 [D_AGCOUNT] = "agcount",
306 [D_FILE] = "file",
307 [D_NAME] = "name",
308 [D_SIZE] = "size",
309 [D_SUNIT] = "sunit",
310 [D_SWIDTH] = "swidth",
311 [D_AGSIZE] = "agsize",
312 [D_SU] = "su",
313 [D_SW] = "sw",
64e924dd
DC
314 [D_SECTSIZE] = "sectsize",
315 [D_NOALIGN] = "noalign",
316 [D_RTINHERIT] = "rtinherit",
317 [D_PROJINHERIT] = "projinherit",
318 [D_EXTSZINHERIT] = "extszinherit",
319 [D_COWEXTSIZE] = "cowextsize",
64989ff3 320 [D_DAXINHERIT] = "daxinherit",
50dba818 321 [D_MAX_OPTS] = NULL,
a9dad670
DC
322 },
323 .subopt_params = {
324 { .index = D_AGCOUNT,
cedf1c43
DC
325 .conflicts = { { &dopts, D_AGSIZE },
326 { NULL, LAST_CONFLICT } },
1974d3f1
DC
327 .minval = 1,
328 .maxval = XFS_MAX_AGNUMBER,
56e4d368 329 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
330 },
331 { .index = D_FILE,
cedf1c43 332 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
333 .minval = 0,
334 .maxval = 1,
335 .defaultval = 1,
a9dad670
DC
336 },
337 { .index = D_NAME,
cedf1c43 338 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368 339 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
340 },
341 { .index = D_SIZE,
cedf1c43 342 .conflicts = { { NULL, LAST_CONFLICT } },
627e74fd
DC
343 .convert = true,
344 .minval = XFS_AG_MIN_BYTES,
345 .maxval = LLONG_MAX,
56e4d368 346 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
347 },
348 { .index = D_SUNIT,
cedf1c43
DC
349 .conflicts = { { &dopts, D_NOALIGN },
350 { &dopts, D_SU },
351 { &dopts, D_SW },
352 { NULL, LAST_CONFLICT } },
1974d3f1
DC
353 .minval = 0,
354 .maxval = UINT_MAX,
56e4d368 355 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
356 },
357 { .index = D_SWIDTH,
cedf1c43
DC
358 .conflicts = { { &dopts, D_NOALIGN },
359 { &dopts, D_SU },
360 { &dopts, D_SW },
361 { NULL, LAST_CONFLICT } },
1974d3f1
DC
362 .minval = 0,
363 .maxval = UINT_MAX,
56e4d368 364 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
365 },
366 { .index = D_AGSIZE,
cedf1c43
DC
367 .conflicts = { { &dopts, D_AGCOUNT },
368 { NULL, LAST_CONFLICT } },
627e74fd 369 .convert = true,
1974d3f1
DC
370 .minval = XFS_AG_MIN_BYTES,
371 .maxval = XFS_AG_MAX_BYTES,
56e4d368 372 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
373 },
374 { .index = D_SU,
cedf1c43
DC
375 .conflicts = { { &dopts, D_NOALIGN },
376 { &dopts, D_SUNIT },
377 { &dopts, D_SWIDTH },
378 { NULL, LAST_CONFLICT } },
627e74fd
DC
379 .convert = true,
380 .minval = 0,
381 .maxval = UINT_MAX,
56e4d368 382 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
383 },
384 { .index = D_SW,
cedf1c43
DC
385 .conflicts = { { &dopts, D_NOALIGN },
386 { &dopts, D_SUNIT },
387 { &dopts, D_SWIDTH },
388 { NULL, LAST_CONFLICT } },
1974d3f1
DC
389 .minval = 0,
390 .maxval = UINT_MAX,
56e4d368 391 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670 392 },
a9dad670 393 { .index = D_SECTSIZE,
2cf637cf 394 .conflicts = { { &sopts, S_SIZE },
6c75555e 395 { &sopts, S_SECTSIZE },
cedf1c43 396 { NULL, LAST_CONFLICT } },
627e74fd
DC
397 .convert = true,
398 .is_power_2 = true,
a9dad670
DC
399 .minval = XFS_MIN_SECTORSIZE,
400 .maxval = XFS_MAX_SECTORSIZE,
56e4d368 401 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
402 },
403 { .index = D_NOALIGN,
cedf1c43
DC
404 .conflicts = { { &dopts, D_SU },
405 { &dopts, D_SW },
406 { &dopts, D_SUNIT },
407 { &dopts, D_SWIDTH },
408 { NULL, LAST_CONFLICT } },
56e4d368
DC
409 .minval = 0,
410 .maxval = 1,
411 .defaultval = 1,
a9dad670
DC
412 },
413 { .index = D_RTINHERIT,
cedf1c43 414 .conflicts = { { NULL, LAST_CONFLICT } },
9c7e941b 415 .minval = 0,
1974d3f1
DC
416 .maxval = 1,
417 .defaultval = 1,
a9dad670
DC
418 },
419 { .index = D_PROJINHERIT,
cedf1c43 420 .conflicts = { { NULL, LAST_CONFLICT } },
1974d3f1
DC
421 .minval = 0,
422 .maxval = UINT_MAX,
56e4d368 423 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
424 },
425 { .index = D_EXTSZINHERIT,
cedf1c43 426 .conflicts = { { NULL, LAST_CONFLICT } },
1974d3f1
DC
427 .minval = 0,
428 .maxval = UINT_MAX,
56e4d368 429 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670 430 },
06b80354 431 { .index = D_COWEXTSIZE,
cedf1c43 432 .conflicts = { { NULL, LAST_CONFLICT } },
06b80354
DW
433 .minval = 0,
434 .maxval = UINT_MAX,
435 .defaultval = SUBOPT_NEEDS_VAL,
436 },
64989ff3
DW
437 { .index = D_DAXINHERIT,
438 .conflicts = { { NULL, LAST_CONFLICT } },
439 .minval = 0,
440 .maxval = 1,
441 .defaultval = 1,
442 },
a9dad670 443 },
2bd0ea18
NS
444};
445
a9dad670 446
00ff2b10 447static struct opt_params iopts = {
a9dad670 448 .name = 'i',
ab2eef12 449 .ini_section = "inode",
a9dad670 450 .subopts = {
64e924dd 451 [I_ALIGN] = "align",
64e924dd
DC
452 [I_MAXPCT] = "maxpct",
453 [I_PERBLOCK] = "perblock",
454 [I_SIZE] = "size",
455 [I_ATTR] = "attr",
456 [I_PROJID32BIT] = "projid32bit",
457 [I_SPINODES] = "sparse",
69e72722 458 [I_NREXT64] = "nrext64",
50dba818 459 [I_MAX_OPTS] = NULL,
a9dad670
DC
460 },
461 .subopt_params = {
462 { .index = I_ALIGN,
cedf1c43 463 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
464 .minval = 0,
465 .maxval = 1,
466 .defaultval = 1,
a9dad670 467 },
a9dad670 468 { .index = I_MAXPCT,
cedf1c43 469 .conflicts = { { NULL, LAST_CONFLICT } },
1974d3f1
DC
470 .minval = 0,
471 .maxval = 100,
56e4d368 472 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
473 },
474 { .index = I_PERBLOCK,
2cf637cf 475 .conflicts = { { &iopts, I_SIZE },
cedf1c43 476 { NULL, LAST_CONFLICT } },
627e74fd 477 .is_power_2 = true,
1974d3f1
DC
478 .minval = XFS_MIN_INODE_PERBLOCK,
479 .maxval = XFS_MAX_BLOCKSIZE / XFS_DINODE_MIN_SIZE,
56e4d368 480 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
481 },
482 { .index = I_SIZE,
cedf1c43 483 .conflicts = { { &iopts, I_PERBLOCK },
cedf1c43 484 { NULL, LAST_CONFLICT } },
627e74fd 485 .is_power_2 = true,
1974d3f1
DC
486 .minval = XFS_DINODE_MIN_SIZE,
487 .maxval = XFS_DINODE_MAX_SIZE,
56e4d368 488 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
489 },
490 { .index = I_ATTR,
cedf1c43 491 .conflicts = { { NULL, LAST_CONFLICT } },
1974d3f1
DC
492 .minval = 0,
493 .maxval = 2,
56e4d368 494 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
495 },
496 { .index = I_PROJID32BIT,
cedf1c43 497 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
498 .minval = 0,
499 .maxval = 1,
500 .defaultval = 1,
a9dad670
DC
501 },
502 { .index = I_SPINODES,
cedf1c43 503 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
504 .minval = 0,
505 .maxval = 1,
506 .defaultval = 1,
a9dad670 507 },
69e72722
CB
508 { .index = I_NREXT64,
509 .conflicts = { { NULL, LAST_CONFLICT } },
510 .minval = 0,
511 .maxval = 1,
512 .defaultval = 1,
513 }
a9dad670 514 },
2bd0ea18
NS
515};
516
00ff2b10 517static struct opt_params lopts = {
a9dad670 518 .name = 'l',
ab2eef12 519 .ini_section = "log",
a9dad670 520 .subopts = {
64e924dd
DC
521 [L_AGNUM] = "agnum",
522 [L_INTERNAL] = "internal",
523 [L_SIZE] = "size",
524 [L_VERSION] = "version",
525 [L_SUNIT] = "sunit",
526 [L_SU] = "su",
527 [L_DEV] = "logdev",
64e924dd
DC
528 [L_SECTSIZE] = "sectsize",
529 [L_FILE] = "file",
530 [L_NAME] = "name",
531 [L_LAZYSBCNTR] = "lazy-count",
50dba818 532 [L_MAX_OPTS] = NULL,
a9dad670
DC
533 },
534 .subopt_params = {
535 { .index = L_AGNUM,
cedf1c43
DC
536 .conflicts = { { &lopts, L_DEV },
537 { NULL, LAST_CONFLICT } },
1974d3f1
DC
538 .minval = 0,
539 .maxval = UINT_MAX,
56e4d368 540 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
541 },
542 { .index = L_INTERNAL,
cedf1c43
DC
543 .conflicts = { { &lopts, L_FILE },
544 { &lopts, L_DEV },
cedf1c43
DC
545 { &lopts, L_SECTSIZE },
546 { NULL, LAST_CONFLICT } },
56e4d368
DC
547 .minval = 0,
548 .maxval = 1,
549 .defaultval = 1,
a9dad670
DC
550 },
551 { .index = L_SIZE,
cedf1c43 552 .conflicts = { { NULL, LAST_CONFLICT } },
627e74fd
DC
553 .convert = true,
554 .minval = 2 * 1024 * 1024LL, /* XXX: XFS_MIN_LOG_BYTES */
555 .maxval = XFS_MAX_LOG_BYTES,
56e4d368 556 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
557 },
558 { .index = L_VERSION,
cedf1c43 559 .conflicts = { { NULL, LAST_CONFLICT } },
1974d3f1
DC
560 .minval = 1,
561 .maxval = 2,
56e4d368 562 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
563 },
564 { .index = L_SUNIT,
cedf1c43
DC
565 .conflicts = { { &lopts, L_SU },
566 { NULL, LAST_CONFLICT } },
2942ff49 567 .minval = 1,
1974d3f1 568 .maxval = BTOBB(XLOG_MAX_RECORD_BSIZE),
56e4d368 569 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
570 },
571 { .index = L_SU,
cedf1c43
DC
572 .conflicts = { { &lopts, L_SUNIT },
573 { NULL, LAST_CONFLICT } },
627e74fd 574 .convert = true,
2942ff49 575 .minval = BBTOB(1),
627e74fd 576 .maxval = XLOG_MAX_RECORD_BSIZE,
56e4d368 577 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
578 },
579 { .index = L_DEV,
cedf1c43 580 .conflicts = { { &lopts, L_AGNUM },
9502da21 581 { &lopts, L_NAME },
cedf1c43
DC
582 { &lopts, L_INTERNAL },
583 { NULL, LAST_CONFLICT } },
56e4d368 584 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670 585 },
a9dad670 586 { .index = L_SECTSIZE,
2cf637cf 587 .conflicts = { { &lopts, L_INTERNAL },
cedf1c43 588 { NULL, LAST_CONFLICT } },
627e74fd
DC
589 .convert = true,
590 .is_power_2 = true,
a9dad670
DC
591 .minval = XFS_MIN_SECTORSIZE,
592 .maxval = XFS_MAX_SECTORSIZE,
56e4d368 593 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
594 },
595 { .index = L_FILE,
cedf1c43
DC
596 .conflicts = { { &lopts, L_INTERNAL },
597 { NULL, LAST_CONFLICT } },
56e4d368
DC
598 .minval = 0,
599 .maxval = 1,
600 .defaultval = 1,
a9dad670
DC
601 },
602 { .index = L_NAME,
cedf1c43 603 .conflicts = { { &lopts, L_AGNUM },
9502da21 604 { &lopts, L_DEV },
cedf1c43
DC
605 { &lopts, L_INTERNAL },
606 { NULL, LAST_CONFLICT } },
56e4d368 607 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
608 },
609 { .index = L_LAZYSBCNTR,
cedf1c43 610 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
611 .minval = 0,
612 .maxval = 1,
613 .defaultval = 1,
a9dad670
DC
614 },
615 },
2bd0ea18
NS
616};
617
00ff2b10 618static struct opt_params nopts = {
a9dad670 619 .name = 'n',
ab2eef12 620 .ini_section = "naming",
a9dad670 621 .subopts = {
64e924dd
DC
622 [N_SIZE] = "size",
623 [N_VERSION] = "version",
624 [N_FTYPE] = "ftype",
50dba818 625 [N_MAX_OPTS] = NULL,
a9dad670
DC
626 },
627 .subopt_params = {
a9dad670 628 { .index = N_SIZE,
2cf637cf 629 .conflicts = { { NULL, LAST_CONFLICT } },
627e74fd
DC
630 .convert = true,
631 .is_power_2 = true,
a9dad670
DC
632 .minval = 1 << XFS_MIN_REC_DIRSIZE,
633 .maxval = XFS_MAX_BLOCKSIZE,
56e4d368 634 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
635 },
636 { .index = N_VERSION,
cedf1c43 637 .conflicts = { { NULL, LAST_CONFLICT } },
1974d3f1
DC
638 .minval = 2,
639 .maxval = 2,
56e4d368 640 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
641 },
642 { .index = N_FTYPE,
cedf1c43 643 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
644 .minval = 0,
645 .maxval = 1,
646 .defaultval = 1,
a9dad670
DC
647 },
648 },
2bd0ea18
NS
649};
650
fb22e1b1
DW
651static struct opt_params popts = {
652 .name = 'p',
653 .ini_section = "proto",
654 .subopts = {
655 [P_FILE] = "file",
e0aeb058 656 [P_SLASHES] = "slashes_are_spaces",
fb22e1b1
DW
657 [P_MAX_OPTS] = NULL,
658 },
659 .subopt_params = {
660 { .index = P_FILE,
661 .conflicts = { { NULL, LAST_CONFLICT } },
662 .defaultval = SUBOPT_NEEDS_VAL,
663 },
e0aeb058
DW
664 { .index = P_SLASHES,
665 .conflicts = { { NULL, LAST_CONFLICT } },
666 .minval = 0,
667 .maxval = 1,
668 .defaultval = 1,
669 },
fb22e1b1
DW
670 },
671};
672
00ff2b10 673static struct opt_params ropts = {
a9dad670 674 .name = 'r',
ab2eef12 675 .ini_section = "realtime",
a9dad670 676 .subopts = {
64e924dd
DC
677 [R_EXTSIZE] = "extsize",
678 [R_SIZE] = "size",
679 [R_DEV] = "rtdev",
680 [R_FILE] = "file",
681 [R_NAME] = "name",
682 [R_NOALIGN] = "noalign",
50dba818 683 [R_MAX_OPTS] = NULL,
a9dad670
DC
684 },
685 .subopt_params = {
686 { .index = R_EXTSIZE,
cedf1c43 687 .conflicts = { { NULL, LAST_CONFLICT } },
627e74fd
DC
688 .convert = true,
689 .minval = XFS_MIN_RTEXTSIZE,
690 .maxval = XFS_MAX_RTEXTSIZE,
56e4d368 691 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
692 },
693 { .index = R_SIZE,
cedf1c43 694 .conflicts = { { NULL, LAST_CONFLICT } },
627e74fd
DC
695 .convert = true,
696 .minval = 0,
697 .maxval = LLONG_MAX,
56e4d368 698 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
699 },
700 { .index = R_DEV,
9502da21
ES
701 .conflicts = { { &ropts, R_NAME },
702 { NULL, LAST_CONFLICT } },
56e4d368 703 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
704 },
705 { .index = R_FILE,
56e4d368
DC
706 .minval = 0,
707 .maxval = 1,
708 .defaultval = 1,
cedf1c43 709 .conflicts = { { NULL, LAST_CONFLICT } },
a9dad670
DC
710 },
711 { .index = R_NAME,
9502da21
ES
712 .conflicts = { { &ropts, R_DEV },
713 { NULL, LAST_CONFLICT } },
56e4d368 714 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
715 },
716 { .index = R_NOALIGN,
56e4d368
DC
717 .minval = 0,
718 .maxval = 1,
719 .defaultval = 1,
cedf1c43 720 .conflicts = { { NULL, LAST_CONFLICT } },
a9dad670
DC
721 },
722 },
2bd0ea18
NS
723};
724
00ff2b10 725static struct opt_params sopts = {
a9dad670 726 .name = 's',
ab2eef12 727 .ini_section = "sector",
a9dad670 728 .subopts = {
64e924dd
DC
729 [S_SIZE] = "size",
730 [S_SECTSIZE] = "sectsize",
50dba818 731 [S_MAX_OPTS] = NULL,
a9dad670
DC
732 },
733 .subopt_params = {
a9dad670 734 { .index = S_SIZE,
2cf637cf 735 .conflicts = { { &sopts, S_SECTSIZE },
6c75555e 736 { &dopts, D_SECTSIZE },
cedf1c43 737 { NULL, LAST_CONFLICT } },
627e74fd
DC
738 .convert = true,
739 .is_power_2 = true,
a9dad670
DC
740 .minval = XFS_MIN_SECTORSIZE,
741 .maxval = XFS_MAX_SECTORSIZE,
56e4d368 742 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
743 },
744 { .index = S_SECTSIZE,
2cf637cf 745 .conflicts = { { &sopts, S_SIZE },
6c75555e 746 { &dopts, D_SECTSIZE },
cedf1c43 747 { NULL, LAST_CONFLICT } },
627e74fd
DC
748 .convert = true,
749 .is_power_2 = true,
a9dad670
DC
750 .minval = XFS_MIN_SECTORSIZE,
751 .maxval = XFS_MAX_SECTORSIZE,
56e4d368 752 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670
DC
753 },
754 },
2bd0ea18
NS
755};
756
00ff2b10 757static struct opt_params mopts = {
a9dad670 758 .name = 'm',
ab2eef12 759 .ini_section = "metadata",
a9dad670 760 .subopts = {
64e924dd
DC
761 [M_CRC] = "crc",
762 [M_FINOBT] = "finobt",
763 [M_UUID] = "uuid",
764 [M_RMAPBT] = "rmapbt",
765 [M_REFLINK] = "reflink",
9eb0d6eb 766 [M_INOBTCNT] = "inobtcount",
e9601810 767 [M_BIGTIME] = "bigtime",
50dba818 768 [M_MAX_OPTS] = NULL,
a9dad670
DC
769 },
770 .subopt_params = {
771 { .index = M_CRC,
cedf1c43 772 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
773 .minval = 0,
774 .maxval = 1,
775 .defaultval = 1,
776 },
777 { .index = M_FINOBT,
cedf1c43 778 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368
DC
779 .minval = 0,
780 .maxval = 1,
781 .defaultval = 1,
782 },
783 { .index = M_UUID,
cedf1c43 784 .conflicts = { { NULL, LAST_CONFLICT } },
56e4d368 785 .defaultval = SUBOPT_NEEDS_VAL,
a9dad670 786 },
c563396a 787 { .index = M_RMAPBT,
cedf1c43 788 .conflicts = { { NULL, LAST_CONFLICT } },
c563396a
DW
789 .minval = 0,
790 .maxval = 1,
23069a93 791 .defaultval = 1,
c563396a 792 },
a5132d9b 793 { .index = M_REFLINK,
cedf1c43 794 .conflicts = { { NULL, LAST_CONFLICT } },
a5132d9b
DW
795 .minval = 0,
796 .maxval = 1,
23069a93 797 .defaultval = 1,
a5132d9b 798 },
9eb0d6eb
DW
799 { .index = M_INOBTCNT,
800 .conflicts = { { NULL, LAST_CONFLICT } },
801 .minval = 0,
802 .maxval = 1,
803 .defaultval = 1,
804 },
e9601810
DW
805 { .index = M_BIGTIME,
806 .conflicts = { { NULL, LAST_CONFLICT } },
807 .minval = 0,
808 .maxval = 1,
809 .defaultval = 1,
810 },
a9dad670 811 },
f7b80291
DC
812};
813
cf627f3c
DC
814/* quick way of checking if a parameter was set on the CLI */
815static bool
816cli_opt_set(
817 struct opt_params *opts,
818 int subopt)
819{
820 return opts->subopt_params[subopt].seen ||
821 opts->subopt_params[subopt].str_seen;
822}
823
824/*
825 * Options configured on the command line.
826 *
827 * This stores all the specific config parameters the user sets on the command
828 * line. We do not use these values directly - they are inputs to the mkfs
829 * geometry validation and override any default configuration value we have.
830 *
831 * We don't keep flags to indicate what parameters are set - if we need to check
4ab08e3b 832 * if an option was set on the command line, we check the relevant entry in the
cf627f3c
DC
833 * option table which records whether it was specified in the .seen and
834 * .str_seen variables in the table.
835 *
836 * Some parameters are stored as strings for post-parsing after their dependent
837 * options have been resolved (e.g. block size and sector size have been parsed
838 * and validated).
839 *
840 * This allows us to check that values have been set without needing separate
841 * flags for each value, and hence avoids needing to record and check for each
842 * specific option that can set the value later on in the code. In the cases
843 * where we don't have a cli_params structure around, the above cli_opt_set()
844 * function can be used.
845 */
846struct sb_feat_args {
847 int log_version;
848 int attr_version;
849 int dir_version;
852b3258
ES
850 bool inode_align; /* XFS_SB_VERSION_ALIGNBIT */
851 bool nci; /* XFS_SB_VERSION_BORGBIT */
852 bool lazy_sb_counters; /* XFS_SB_VERSION2_LAZYSBCOUNTBIT */
853 bool parent_pointers; /* XFS_SB_VERSION2_PARENTBIT */
854 bool projid32bit; /* XFS_SB_VERSION2_PROJID32BIT */
855 bool crcs_enabled; /* XFS_SB_VERSION2_CRCBIT */
856 bool dirftype; /* XFS_SB_VERSION2_FTYPE */
857 bool finobt; /* XFS_SB_FEAT_RO_COMPAT_FINOBT */
858 bool spinodes; /* XFS_SB_FEAT_INCOMPAT_SPINODES */
859 bool rmapbt; /* XFS_SB_FEAT_RO_COMPAT_RMAPBT */
860 bool reflink; /* XFS_SB_FEAT_RO_COMPAT_REFLINK */
9eb0d6eb 861 bool inobtcnt; /* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */
e9601810 862 bool bigtime; /* XFS_SB_FEAT_INCOMPAT_BIGTIME */
cf627f3c
DC
863 bool nodalign;
864 bool nortalign;
69e72722 865 bool nrext64;
cf627f3c
DC
866};
867
868struct cli_params {
869 int sectorsize;
870 int blocksize;
871
33c62516 872 char *cfgfile;
fb22e1b1 873 char *protofile;
33c62516 874
cf627f3c
DC
875 /* parameters that depend on sector/block size being validated. */
876 char *dsize;
877 char *agsize;
878 char *dsu;
879 char *dirblocksize;
880 char *logsize;
881 char *lsu;
882 char *rtextsize;
883 char *rtsize;
884
885 /* parameters where 0 is a valid CLI value */
886 int dsunit;
887 int dswidth;
888 int dsw;
889 int64_t logagno;
890 int loginternal;
891 int lsunit;
6e0ed3d1 892 int is_supported;
e0aeb058 893 int proto_slashes_are_spaces;
cf627f3c
DC
894
895 /* parameters where 0 is not a valid value */
896 int64_t agcount;
cf627f3c
DC
897 int inodesize;
898 int inopblock;
899 int imaxpct;
900 int lsectorsize;
901 uuid_t uuid;
902
903 /* feature flags that are set */
904 struct sb_feat_args sb_feat;
905
906 /* root inode characteristics */
907 struct fsxattr fsx;
908
909 /* libxfs device setup */
01dcfd9e 910 struct libxfs_init *xi;
cf627f3c
DC
911};
912
4ab08e3b
DC
913/*
914 * Calculated filesystem feature and geometry information.
915 *
916 * This structure contains the information we will use to create the on-disk
917 * filesystem from. The validation and calculation code uses it to store all the
918 * temporary and final config state for the filesystem.
919 *
920 * The information in this structure will contain a mix of validated CLI input
921 * variables, default feature state and calculated values that are needed to
922 * construct the superblock and other on disk features. These are all in one
923 * place so that we don't have to pass handfuls of seemingly arbitrary variables
924 * around to different functions to do the work we need to do.
925 */
926struct mkfs_params {
927 int blocksize;
928 int blocklog;
929 int sectorsize;
930 int sectorlog;
931 int lsectorsize;
932 int lsectorlog;
933 int dirblocksize;
934 int dirblocklog;
935 int inodesize;
936 int inodelog;
937 int inopblock;
938
939 uint64_t dblocks;
940 uint64_t logblocks;
941 uint64_t rtblocks;
942 uint64_t rtextblocks;
943 uint64_t rtextents;
944 uint64_t rtbmblocks; /* rt bitmap blocks */
945
946 int dsunit; /* in FSBs */
947 int dswidth; /* in FSBs */
948 int lsunit; /* in FSBs */
949
950 uint64_t agsize;
951 uint64_t agcount;
952
953 int imaxpct;
954
955 bool loginternal;
956 uint64_t logstart;
957 uint64_t logagno;
958
959 uuid_t uuid;
960 char *label;
961
962 struct sb_feat_args sb_feat;
963};
964
68344ba0
DC
965/*
966 * Default filesystem features and configuration values
967 *
968 * This structure contains the default mkfs values that are to be used when
969 * a user does not specify the option on the command line. We do not use these
970 * values directly - they are inputs to the mkfs geometry validation and
971 * calculations.
972 */
973struct mkfs_default_params {
974 char *source; /* where the defaults came from */
975
976 int sectorsize;
977 int blocksize;
978
979 /* feature flags that are set */
980 struct sb_feat_args sb_feat;
981
982 /* root inode characteristics */
983 struct fsxattr fsx;
984};
985
dafb318d
DC
986static void __attribute__((noreturn))
987usage( void )
988{
989 fprintf(stderr, _("Usage: %s\n\
c66bd30e 990/* blocksize */ [-b size=num]\n\
33c62516 991/* config file */ [-c options=xxx]\n\
9eb0d6eb 992/* metadata */ [-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
2c40c5a7 993 inobtcount=0|1,bigtime=0|1]\n\
dafb318d
DC
994/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
995 (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
c66bd30e 996 sectsize=num\n\
dafb318d 997/* force overwrite */ [-f]\n\
b68e2558 998/* inode size */ [-i perblock=n|size=num,maxpct=n,attr=0|1|2,\n\
42efbb99 999 projid32bit=0|1,sparse=0|1,nrext64=0|1]\n\
dafb318d
DC
1000/* no discard */ [-K]\n\
1001/* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
c66bd30e 1002 sunit=value|su=num,sectsize=num,lazy-count=0|1]\n\
dafb318d 1003/* label */ [-L label (maximum 12 characters)]\n\
c66bd30e 1004/* naming */ [-n size=num,version=2|ci,ftype=0|1]\n\
dafb318d
DC
1005/* no-op info only */ [-N]\n\
1006/* prototype file */ [-p fname]\n\
1007/* quiet */ [-q]\n\
1008/* realtime subvol */ [-r extsize=num,size=num,rtdev=xxx]\n\
c66bd30e 1009/* sectorsize */ [-s size=num]\n\
dafb318d
DC
1010/* version */ [-V]\n\
1011 devicename\n\
1012<devicename> is required unless -d name=xxx is given.\n\
1013<num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n\
1014 xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n\
1015<value> is xxx (512 byte blocks).\n"),
1016 progname);
1017 exit(1);
1018}
1019
1020static void
1021conflict(
cedf1c43
DC
1022 struct opt_params *opts,
1023 int option,
1024 struct opt_params *con_opts,
1025 int conflict)
dafb318d
DC
1026{
1027 fprintf(stderr, _("Cannot specify both -%c %s and -%c %s\n"),
6c75555e
DC
1028 con_opts->name, con_opts->subopts[conflict],
1029 opts->name, opts->subopts[option]);
dafb318d
DC
1030 usage();
1031}
1032
1033
1034static void
1035illegal(
1036 const char *value,
1037 const char *opt)
1038{
0b1cf8bb 1039 fprintf(stderr, _("Invalid value %s for -%s option\n"), value, opt);
dafb318d
DC
1040 usage();
1041}
1042
1043static int
1044ispow2(
1045 unsigned int i)
1046{
1047 return (i & (i - 1)) == 0;
1048}
1049
1050static void __attribute__((noreturn))
1051reqval(
1052 char opt,
1053 const char *tab[],
1054 int idx)
1055{
1056 fprintf(stderr, _("-%c %s option requires a value\n"), opt, tab[idx]);
1057 usage();
1058}
1059
1060static void
1061respec(
1062 char opt,
1063 const char *tab[],
1064 int idx)
1065{
1066 fprintf(stderr, "-%c ", opt);
1067 if (tab)
1068 fprintf(stderr, "%s ", tab[idx]);
1069 fprintf(stderr, _("option respecified\n"));
1070 usage();
1071}
1072
1073static void
1074unknown(
9c2b30c8
DC
1075 const char opt,
1076 const char *s)
dafb318d
DC
1077{
1078 fprintf(stderr, _("unknown option -%c %s\n"), opt, s);
1079 usage();
1080}
1081
ab2eef12
DC
1082static void
1083invalid_cfgfile_opt(
1084 const char *filename,
1085 const char *section,
1086 const char *name,
1087 const char *value)
1088{
1089 fprintf(stderr, _("%s: invalid config file option: [%s]: %s=%s\n"),
1090 filename, section, name, value);
1091}
1092
06ac92fd
DC
1093static void
1094check_device_type(
1095 const char *name,
1096 int *isfile,
1097 bool no_size,
1098 bool no_name,
1099 int *create,
06ac92fd
DC
1100 const char *optname)
1101{
f594a0d1 1102 struct stat statbuf;
06ac92fd
DC
1103
1104 if (*isfile && (no_size || no_name)) {
1105 fprintf(stderr,
1106 _("if -%s file then -%s name and -%s size are required\n"),
1107 optname, optname, optname);
1108 usage();
1109 }
1110
1111 if (!name) {
1112 fprintf(stderr, _("No device name specified\n"));
1113 usage();
1114 }
1115
f594a0d1 1116 if (stat(name, &statbuf)) {
06ac92fd
DC
1117 if (errno == ENOENT && *isfile) {
1118 if (create)
1119 *create = 1;
1120 return;
1121 }
1122
1123 fprintf(stderr,
1124 _("Error accessing specified device %s: %s\n"),
1125 name, strerror(errno));
1126 usage();
1127 return;
1128 }
1129
06ac92fd
DC
1130 /*
1131 * We only want to completely truncate and recreate an existing file if
1132 * we were specifically told it was a file. Set the create flag only in
1133 * this case to trigger that behaviour.
1134 */
1135 if (S_ISREG(statbuf.st_mode)) {
1136 if (!*isfile)
1137 *isfile = 1;
1138 else if (create)
1139 *create = 1;
1140 return;
1141 }
1142
1143 if (S_ISBLK(statbuf.st_mode)) {
1144 if (*isfile) {
1145 fprintf(stderr,
1146 _("specified \"-%s file\" on a block device %s\n"),
1147 optname, name);
1148 usage();
1149 }
1150 return;
1151 }
1152
1153 fprintf(stderr,
1154 _("specified device %s not a file or block device\n"),
1155 name);
1156 usage();
1157}
1158
cb46aab2
JT
1159static void
1160validate_overwrite(
1161 const char *name,
1162 bool force_overwrite)
1163{
1164 if (!force_overwrite && check_overwrite(name)) {
1165 fprintf(stderr,
1166 _("%s: Use the -f option to force overwrite.\n"),
1167 progname);
1168 exit(1);
1169 }
1170
1171}
1172
1f1b8be7
NS
1173static void
1174validate_ag_geometry(
1175 int blocklog,
14f8b681
DW
1176 uint64_t dblocks,
1177 uint64_t agsize,
1178 uint64_t agcount)
1f1b8be7
NS
1179{
1180 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
1181 fprintf(stderr,
ddf12ea5 1182 _("agsize (%lld blocks) too small, need at least %lld blocks\n"),
1f1b8be7
NS
1183 (long long)agsize,
1184 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1185 usage();
1186 }
1187
1188 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
1189 fprintf(stderr,
ddf12ea5 1190 _("agsize (%lld blocks) too big, maximum is %lld blocks\n"),
1f1b8be7
NS
1191 (long long)agsize,
1192 (long long)XFS_AG_MAX_BLOCKS(blocklog));
1193 usage();
1194 }
1195
1196 if (agsize > dblocks) {
1197 fprintf(stderr,
ddf12ea5 1198 _("agsize (%lld blocks) too big, data area is %lld blocks\n"),
1f1b8be7
NS
1199 (long long)agsize, (long long)dblocks);
1200 usage();
1201 }
1202
1203 if (agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
1204 fprintf(stderr,
1205 _("too many allocation groups for size = %lld\n"),
1206 (long long)agsize);
1207 fprintf(stderr, _("need at most %lld allocation groups\n"),
1208 (long long)(dblocks / XFS_AG_MIN_BLOCKS(blocklog) +
1209 (dblocks % XFS_AG_MIN_BLOCKS(blocklog) != 0)));
1210 usage();
1211 }
1212
1213 if (agsize > XFS_AG_MAX_BLOCKS(blocklog)) {
1214 fprintf(stderr,
1215 _("too few allocation groups for size = %lld\n"), (long long)agsize);
1216 fprintf(stderr,
1217 _("need at least %lld allocation groups\n"),
1e945ba2 1218 (long long)(dblocks / XFS_AG_MAX_BLOCKS(blocklog) +
1f1b8be7
NS
1219 (dblocks % XFS_AG_MAX_BLOCKS(blocklog) != 0)));
1220 usage();
1221 }
1222
1223 /*
1224 * If the last AG is too small, reduce the filesystem size
1225 * and drop the blocks.
1226 */
1227 if ( dblocks % agsize != 0 &&
1228 (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
1229 fprintf(stderr,
1230 _("last AG size %lld blocks too small, minimum size is %lld blocks\n"),
1231 (long long)(dblocks % agsize),
1232 (long long)XFS_AG_MIN_BLOCKS(blocklog));
1233 usage();
1234 }
1235
1236 /*
1237 * If agcount is too large, make it smaller.
1238 */
1239 if (agcount > XFS_MAX_AGNUMBER + 1) {
1240 fprintf(stderr,
1241 _("%lld allocation groups is too many, maximum is %lld\n"),
1242 (long long)agcount, (long long)XFS_MAX_AGNUMBER + 1);
1243 usage();
1244 }
1245}
1246
1e945ba2
BN
1247static void
1248zero_old_xfs_structures(
01dcfd9e 1249 struct libxfs_init *xi,
1e945ba2
BN
1250 xfs_sb_t *new_sb)
1251{
1252 void *buf;
1253 xfs_sb_t sb;
14f8b681 1254 uint32_t bsize;
1e945ba2
BN
1255 int i;
1256 xfs_off_t off;
31daa90b
BF
1257
1258 /*
1259 * We open regular files with O_TRUNC|O_CREAT. Nothing to do here...
1260 */
1261 if (xi->disfile && xi->dcreat)
1262 return;
1e945ba2
BN
1263
1264 /*
ff1f79a7 1265 * read in existing filesystem superblock, use its geometry
1e945ba2
BN
1266 * settings and zero the existing secondary superblocks.
1267 */
1268 buf = memalign(libxfs_device_alignment(), new_sb->sb_sectsize);
1269 if (!buf) {
1270 fprintf(stderr,
1271 _("error reading existing superblock -- failed to memalign buffer\n"));
1272 return;
1273 }
dab9b8d6 1274 memset(buf, 0, new_sb->sb_sectsize);
1e945ba2 1275
06ac92fd
DC
1276 /*
1277 * If we are creating an image file, it might be of zero length at this
1278 * point in time. Hence reading the existing superblock is going to
1279 * return zero bytes. It's not a failure we need to warn about in this
1280 * case.
1281 */
1282 off = pread(xi->dfd, buf, new_sb->sb_sectsize, 0);
1283 if (off != new_sb->sb_sectsize) {
1284 if (!xi->disfile)
1285 fprintf(stderr,
1286 _("error reading existing superblock: %s\n"),
1287 strerror(errno));
31daa90b 1288 goto done;
1e945ba2 1289 }
5e656dbb 1290 libxfs_sb_from_disk(&sb, buf);
1e945ba2
BN
1291
1292 /*
1293 * perform same basic superblock validation to make sure we
1294 * actually zero secondary blocks
1295 */
1296 if (sb.sb_magicnum != XFS_SB_MAGIC || sb.sb_blocksize == 0)
1297 goto done;
1298
1299 for (bsize = 1, i = 0; bsize < sb.sb_blocksize &&
1300 i < sizeof(sb.sb_blocksize) * NBBY; i++)
1301 bsize <<= 1;
1302
1303 if (i < XFS_MIN_BLOCKSIZE_LOG || i > XFS_MAX_BLOCKSIZE_LOG ||
1304 i != sb.sb_blocklog)
1305 goto done;
1306
14f8b681
DW
1307 if (sb.sb_dblocks > ((uint64_t)sb.sb_agcount * sb.sb_agblocks) ||
1308 sb.sb_dblocks < ((uint64_t)(sb.sb_agcount - 1) *
1e945ba2
BN
1309 sb.sb_agblocks + XFS_MIN_AG_BLOCKS))
1310 goto done;
1311
1312 /*
c93b0a22 1313 * block size and basic geometry seems alright, zero the secondaries.
1e945ba2 1314 */
dab9b8d6 1315 memset(buf, 0, new_sb->sb_sectsize);
1e945ba2
BN
1316 off = 0;
1317 for (i = 1; i < sb.sb_agcount; i++) {
1318 off += sb.sb_agblocks;
2f9a125c 1319 if (pwrite(xi->dfd, buf, new_sb->sb_sectsize,
1e945ba2
BN
1320 off << sb.sb_blocklog) == -1)
1321 break;
1322 }
1323done:
1324 free(buf);
1325}
1326
ad136b33 1327static void
7e8a6edb 1328discard_blocks(dev_t dev, uint64_t nsectors, int quiet)
ad136b33 1329{
7e8a6edb
PR
1330 int fd;
1331 uint64_t offset = 0;
1332 /* Discard the device 2G at a time */
1333 const uint64_t step = 2ULL << 30;
1334 const uint64_t count = BBTOB(nsectors);
ad136b33 1335
ad136b33 1336 fd = libxfs_device_to_fd(dev);
7e8a6edb
PR
1337 if (fd <= 0)
1338 return;
7e8a6edb
PR
1339
1340 /* The block discarding happens in smaller batches so it can be
1341 * interrupted prematurely
1342 */
1343 while (offset < count) {
1344 uint64_t tmp_step = min(step, count - offset);
1345
1346 /*
1347 * We intentionally ignore errors from the discard ioctl. It is
1348 * not necessary for the mkfs functionality but just an
1349 * optimization. However we should stop on error.
1350 */
2383d7c5
ES
1351 if (platform_discard_blocks(fd, offset, tmp_step) == 0) {
1352 if (offset == 0 && !quiet) {
1353 printf("Discarding blocks...");
1354 fflush(stdout);
1355 }
1356 } else {
1357 if (offset > 0 && !quiet)
1358 printf("\n");
7e8a6edb 1359 return;
2383d7c5 1360 }
7e8a6edb
PR
1361
1362 offset += tmp_step;
1363 }
2383d7c5 1364 if (offset > 0 && !quiet)
7e8a6edb 1365 printf("Done.\n");
ad136b33
CH
1366}
1367
a9dad670
DC
1368static __attribute__((noreturn)) void
1369illegal_option(
aa3034d4 1370 const char *value,
a9dad670 1371 struct opt_params *opts,
aa3034d4
JT
1372 int index,
1373 const char *reason)
a9dad670
DC
1374{
1375 fprintf(stderr,
0b1cf8bb 1376 _("Invalid value %s for -%c %s option. %s\n"),
aa3034d4 1377 value, opts->name, opts->subopts[index],
7d25f65f 1378 reason);
a9dad670
DC
1379 usage();
1380}
1381
27ae3a59
DC
1382/*
1383 * Check for conflicts and option respecification.
1384 */
1385static void
1386check_opt(
a9dad670 1387 struct opt_params *opts,
27ae3a59
DC
1388 int index,
1389 bool str_seen)
147e0f31 1390{
27ae3a59
DC
1391 struct subopt_param *sp = &opts->subopt_params[index];
1392 int i;
147e0f31 1393
56e4d368
DC
1394 if (sp->index != index) {
1395 fprintf(stderr,
02c3e106 1396 _("Developer screwed up option parsing (%d/%d)! Please report!\n"),
56e4d368 1397 sp->index, index);
05abf43d 1398 reqval(opts->name, opts->subopts, index);
56e4d368
DC
1399 }
1400
27ae3a59
DC
1401 /*
1402 * Check for respecification of the option. This is more complex than it
1403 * seems because some options are parsed twice - once as a string during
1404 * input parsing, then later the string is passed to getnum for
1405 * conversion into a number and bounds checking. Hence the two variables
1406 * used to track the different uses based on the @str parameter passed
1407 * to us.
1408 */
1409 if (!str_seen) {
1410 if (sp->seen)
05abf43d 1411 respec(opts->name, opts->subopts, index);
27ae3a59
DC
1412 sp->seen = true;
1413 } else {
1414 if (sp->str_seen)
05abf43d 1415 respec(opts->name, opts->subopts, index);
27ae3a59
DC
1416 sp->str_seen = true;
1417 }
9090e187 1418
3ec1956a 1419 /* check for conflicts with the option */
27ae3a59 1420 for (i = 0; i < MAX_CONFLICTS; i++) {
cedf1c43 1421 struct _conflict *con = &sp->conflicts[i];
3ec1956a 1422
cedf1c43 1423 if (con->subopt == LAST_CONFLICT)
3ec1956a 1424 break;
cedf1c43
DC
1425 if (con->opts->subopt_params[con->subopt].seen ||
1426 con->opts->subopt_params[con->subopt].str_seen)
1427 conflict(opts, index, con->opts, con->subopt);
3ec1956a 1428 }
27ae3a59 1429}
3ec1956a 1430
27ae3a59
DC
1431static long long
1432getnum(
1433 const char *str,
1434 struct opt_params *opts,
1435 int index)
1436{
1437 struct subopt_param *sp = &opts->subopt_params[index];
1438 long long c;
1439
1440 check_opt(opts, index, false);
6c855628 1441 /* empty strings might just return a default value */
56e4d368
DC
1442 if (!str || *str == '\0') {
1443 if (sp->defaultval == SUBOPT_NEEDS_VAL)
05abf43d 1444 reqval(opts->name, opts->subopts, index);
56e4d368
DC
1445 return sp->defaultval;
1446 }
a9dad670 1447
56e4d368 1448 if (sp->minval == 0 && sp->maxval == 0) {
a9dad670
DC
1449 fprintf(stderr,
1450 _("Option -%c %s has undefined minval/maxval."
1451 "Can't verify value range. This is a bug.\n"),
1452 opts->name, opts->subopts[index]);
1453 exit(1);
1454 }
147e0f31 1455
6c855628
DC
1456 /*
1457 * Some values are pure numbers, others can have suffixes that define
1458 * the units of the number. Those get passed to cvtnum(), otherwise we
1459 * convert it ourselves to guarantee there is no trailing garbage in the
1460 * number.
1461 */
105041e6 1462 if (sp->convert) {
6c855628 1463 c = cvtnum(blocksize, sectorsize, str);
105041e6
DC
1464 if (c == -1LL) {
1465 illegal_option(str, opts, index,
1466 _("Not a valid value or illegal suffix"));
1467 }
1468 } else {
6c855628
DC
1469 char *str_end;
1470
1471 c = strtoll(str, &str_end, 0);
1472 if (c == 0 && str_end == str)
7d25f65f
DW
1473 illegal_option(str, opts, index,
1474 _("Value not recognized as number."));
6c855628 1475 if (*str_end != '\0')
7d25f65f
DW
1476 illegal_option(str, opts, index,
1477 _("Unit suffixes are not allowed."));
6c855628
DC
1478 }
1479
1480 /* Validity check the result. */
aa3034d4 1481 if (c < sp->minval)
7d25f65f 1482 illegal_option(str, opts, index, _("Value is too small."));
aa3034d4 1483 else if (c > sp->maxval)
7d25f65f 1484 illegal_option(str, opts, index, _("Value is too large."));
627e74fd 1485 if (sp->is_power_2 && !ispow2(c))
7d25f65f 1486 illegal_option(str, opts, index, _("Value must be a power of 2."));
147e0f31
DC
1487 return c;
1488}
1489
27ae3a59
DC
1490/*
1491 * Option is a string - do all the option table work, and check there
1492 * is actually an option string. Otherwise we don't do anything with the string
1493 * here - validation will be done later when the string is converted to a value
1494 * or used as a file/device path.
1495 */
1496static char *
1497getstr(
9c2b30c8 1498 const char *str,
27ae3a59
DC
1499 struct opt_params *opts,
1500 int index)
1501{
99c78777
DW
1502 char *ret;
1503
27ae3a59
DC
1504 check_opt(opts, index, true);
1505
1506 /* empty strings for string options are not valid */
1507 if (!str || *str == '\0')
05abf43d 1508 reqval(opts->name, opts->subopts, index);
99c78777
DW
1509
1510 ret = strdup(str);
1511 if (!ret) {
1512 fprintf(stderr, _("Out of memory while saving suboptions.\n"));
1513 exit(1);
1514 }
1515
1516 return ret;
27ae3a59
DC
1517}
1518
a350bbc1
DC
1519static int
1520block_opts_parser(
1521 struct opt_params *opts,
1522 int subopt,
9c2b30c8 1523 const char *value,
a350bbc1
DC
1524 struct cli_params *cli)
1525{
85d6f03d 1526 switch (subopt) {
85d6f03d 1527 case B_SIZE:
e5e612ae 1528 cli->blocksize = getnum(value, opts, subopt);
85d6f03d
DC
1529 break;
1530 default:
1531 return -EINVAL;
1532 }
a350bbc1
DC
1533 return 0;
1534}
1535
33c62516
DC
1536static int
1537cfgfile_opts_parser(
1538 struct opt_params *opts,
1539 int subopt,
9c2b30c8 1540 const char *value,
33c62516
DC
1541 struct cli_params *cli)
1542{
1543 switch (subopt) {
1544 case C_OPTFILE:
1545 cli->cfgfile = getstr(value, opts, subopt);
1546 break;
1547 default:
1548 return -EINVAL;
1549 }
1550 return 0;
1551}
1552
a350bbc1
DC
1553static int
1554data_opts_parser(
1555 struct opt_params *opts,
1556 int subopt,
9c2b30c8 1557 const char *value,
a350bbc1
DC
1558 struct cli_params *cli)
1559{
a1273b7c
DC
1560 switch (subopt) {
1561 case D_AGCOUNT:
e5e612ae 1562 cli->agcount = getnum(value, opts, subopt);
a1273b7c
DC
1563 break;
1564 case D_AGSIZE:
e5e612ae 1565 cli->agsize = getstr(value, opts, subopt);
a1273b7c
DC
1566 break;
1567 case D_FILE:
e5e612ae 1568 cli->xi->disfile = getnum(value, opts, subopt);
a1273b7c
DC
1569 break;
1570 case D_NAME:
e5e612ae 1571 cli->xi->dname = getstr(value, opts, subopt);
a1273b7c
DC
1572 break;
1573 case D_SIZE:
e5e612ae 1574 cli->dsize = getstr(value, opts, subopt);
a1273b7c
DC
1575 break;
1576 case D_SUNIT:
e5e612ae 1577 cli->dsunit = getnum(value, opts, subopt);
a1273b7c
DC
1578 break;
1579 case D_SWIDTH:
e5e612ae 1580 cli->dswidth = getnum(value, opts, subopt);
a1273b7c
DC
1581 break;
1582 case D_SU:
e5e612ae 1583 cli->dsu = getstr(value, opts, subopt);
a1273b7c
DC
1584 break;
1585 case D_SW:
e5e612ae 1586 cli->dsw = getnum(value, opts, subopt);
a1273b7c
DC
1587 break;
1588 case D_NOALIGN:
e5e612ae 1589 cli->sb_feat.nodalign = getnum(value, opts, subopt);
a1273b7c 1590 break;
a1273b7c 1591 case D_SECTSIZE:
e5e612ae 1592 cli->sectorsize = getnum(value, opts, subopt);
a1273b7c
DC
1593 break;
1594 case D_RTINHERIT:
e5e612ae 1595 if (getnum(value, opts, subopt))
00d139f1 1596 cli->fsx.fsx_xflags |= FS_XFLAG_RTINHERIT;
9c7e941b
DW
1597 else
1598 cli->fsx.fsx_xflags &= ~FS_XFLAG_RTINHERIT;
a1273b7c
DC
1599 break;
1600 case D_PROJINHERIT:
e5e612ae 1601 cli->fsx.fsx_projid = getnum(value, opts, subopt);
00d139f1 1602 cli->fsx.fsx_xflags |= FS_XFLAG_PROJINHERIT;
a1273b7c
DC
1603 break;
1604 case D_EXTSZINHERIT:
e5e612ae 1605 cli->fsx.fsx_extsize = getnum(value, opts, subopt);
dc2cfca7
DW
1606 if (cli->fsx.fsx_extsize)
1607 cli->fsx.fsx_xflags |= FS_XFLAG_EXTSZINHERIT;
1608 else
1609 cli->fsx.fsx_xflags &= ~FS_XFLAG_EXTSZINHERIT;
a1273b7c
DC
1610 break;
1611 case D_COWEXTSIZE:
e5e612ae 1612 cli->fsx.fsx_cowextsize = getnum(value, opts, subopt);
dc2cfca7
DW
1613 if (cli->fsx.fsx_cowextsize)
1614 cli->fsx.fsx_xflags |= FS_XFLAG_COWEXTSIZE;
1615 else
1616 cli->fsx.fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
a1273b7c 1617 break;
64989ff3
DW
1618 case D_DAXINHERIT:
1619 if (getnum(value, opts, subopt))
1620 cli->fsx.fsx_xflags |= FS_XFLAG_DAX;
1621 else
1622 cli->fsx.fsx_xflags &= ~FS_XFLAG_DAX;
1623 break;
a1273b7c
DC
1624 default:
1625 return -EINVAL;
1626 }
a350bbc1
DC
1627 return 0;
1628}
1629
1630static int
1631inode_opts_parser(
1632 struct opt_params *opts,
1633 int subopt,
9c2b30c8 1634 const char *value,
a350bbc1
DC
1635 struct cli_params *cli)
1636{
a3ac5af1
DC
1637 switch (subopt) {
1638 case I_ALIGN:
e5e612ae 1639 cli->sb_feat.inode_align = getnum(value, opts, subopt);
a3ac5af1 1640 break;
a3ac5af1 1641 case I_MAXPCT:
e5e612ae 1642 cli->imaxpct = getnum(value, opts, subopt);
a3ac5af1
DC
1643 break;
1644 case I_PERBLOCK:
e5e612ae 1645 cli->inopblock = getnum(value, opts, subopt);
a3ac5af1
DC
1646 break;
1647 case I_SIZE:
e5e612ae 1648 cli->inodesize = getnum(value, opts, subopt);
a3ac5af1
DC
1649 break;
1650 case I_ATTR:
e5e612ae 1651 cli->sb_feat.attr_version = getnum(value, opts, subopt);
a3ac5af1
DC
1652 break;
1653 case I_PROJID32BIT:
e5e612ae 1654 cli->sb_feat.projid32bit = getnum(value, opts, subopt);
a3ac5af1
DC
1655 break;
1656 case I_SPINODES:
e5e612ae 1657 cli->sb_feat.spinodes = getnum(value, opts, subopt);
a3ac5af1 1658 break;
69e72722
CB
1659 case I_NREXT64:
1660 cli->sb_feat.nrext64 = getnum(value, opts, subopt);
1661 break;
a3ac5af1
DC
1662 default:
1663 return -EINVAL;
1664 }
a350bbc1
DC
1665 return 0;
1666}
1667
1668static int
1669log_opts_parser(
1670 struct opt_params *opts,
1671 int subopt,
9c2b30c8 1672 const char *value,
a350bbc1
DC
1673 struct cli_params *cli)
1674{
f3bc91a4
DC
1675 switch (subopt) {
1676 case L_AGNUM:
e5e612ae 1677 cli->logagno = getnum(value, opts, subopt);
f3bc91a4
DC
1678 break;
1679 case L_FILE:
e5e612ae 1680 cli->xi->lisfile = getnum(value, opts, subopt);
f3bc91a4
DC
1681 break;
1682 case L_INTERNAL:
e5e612ae 1683 cli->loginternal = getnum(value, opts, subopt);
f3bc91a4
DC
1684 break;
1685 case L_SU:
e5e612ae 1686 cli->lsu = getstr(value, opts, subopt);
f3bc91a4
DC
1687 break;
1688 case L_SUNIT:
e5e612ae 1689 cli->lsunit = getnum(value, opts, subopt);
f3bc91a4
DC
1690 break;
1691 case L_NAME:
1692 case L_DEV:
e5e612ae 1693 cli->xi->logname = getstr(value, opts, subopt);
f3bc91a4
DC
1694 cli->loginternal = 0;
1695 break;
1696 case L_VERSION:
e5e612ae 1697 cli->sb_feat.log_version = getnum(value, opts, subopt);
f3bc91a4
DC
1698 break;
1699 case L_SIZE:
e5e612ae 1700 cli->logsize = getstr(value, opts, subopt);
f3bc91a4 1701 break;
f3bc91a4 1702 case L_SECTSIZE:
e5e612ae 1703 cli->lsectorsize = getnum(value, opts, subopt);
f3bc91a4
DC
1704 break;
1705 case L_LAZYSBCNTR:
e5e612ae 1706 cli->sb_feat.lazy_sb_counters = getnum(value, opts, subopt);
f3bc91a4
DC
1707 break;
1708 default:
1709 return -EINVAL;
1710 }
a350bbc1
DC
1711 return 0;
1712}
1713
1714static int
1715meta_opts_parser(
1716 struct opt_params *opts,
1717 int subopt,
9c2b30c8 1718 const char *value,
a350bbc1
DC
1719 struct cli_params *cli)
1720{
997136c6
DC
1721 switch (subopt) {
1722 case M_CRC:
e5e612ae 1723 cli->sb_feat.crcs_enabled = getnum(value, opts, subopt);
997136c6
DC
1724 if (cli->sb_feat.crcs_enabled)
1725 cli->sb_feat.dirftype = true;
1726 break;
1727 case M_FINOBT:
e5e612ae 1728 cli->sb_feat.finobt = getnum(value, opts, subopt);
997136c6
DC
1729 break;
1730 case M_UUID:
1731 if (!value || *value == '\0')
e5e612ae 1732 reqval('m', opts->subopts, subopt);
997136c6
DC
1733 if (platform_uuid_parse(value, &cli->uuid))
1734 illegal(value, "m uuid");
1735 break;
1736 case M_RMAPBT:
e5e612ae 1737 cli->sb_feat.rmapbt = getnum(value, opts, subopt);
997136c6
DC
1738 break;
1739 case M_REFLINK:
e5e612ae 1740 cli->sb_feat.reflink = getnum(value, opts, subopt);
997136c6 1741 break;
9eb0d6eb
DW
1742 case M_INOBTCNT:
1743 cli->sb_feat.inobtcnt = getnum(value, opts, subopt);
1744 break;
e9601810
DW
1745 case M_BIGTIME:
1746 cli->sb_feat.bigtime = getnum(value, opts, subopt);
1747 break;
997136c6
DC
1748 default:
1749 return -EINVAL;
1750 }
a350bbc1
DC
1751 return 0;
1752}
1753
1754static int
1755naming_opts_parser(
1756 struct opt_params *opts,
1757 int subopt,
9c2b30c8 1758 const char *value,
a350bbc1
DC
1759 struct cli_params *cli)
1760{
98d40922 1761 switch (subopt) {
98d40922 1762 case N_SIZE:
e5e612ae 1763 cli->dirblocksize = getstr(value, opts, subopt);
98d40922
DC
1764 break;
1765 case N_VERSION:
e5e612ae 1766 value = getstr(value, &nopts, subopt);
98d40922
DC
1767 if (!strcasecmp(value, "ci")) {
1768 /* ASCII CI mode */
1769 cli->sb_feat.nci = true;
1770 } else {
e5e612ae 1771 cli->sb_feat.dir_version = getnum(value, opts, subopt);
98d40922 1772 }
8b4002e0 1773 free((char *)value);
98d40922
DC
1774 break;
1775 case N_FTYPE:
e5e612ae 1776 cli->sb_feat.dirftype = getnum(value, opts, subopt);
98d40922
DC
1777 break;
1778 default:
1779 return -EINVAL;
1780 }
a350bbc1
DC
1781 return 0;
1782}
1783
fb22e1b1
DW
1784static int
1785proto_opts_parser(
1786 struct opt_params *opts,
1787 int subopt,
1788 const char *value,
1789 struct cli_params *cli)
1790{
1791 switch (subopt) {
e0aeb058
DW
1792 case P_SLASHES:
1793 cli->proto_slashes_are_spaces = getnum(value, opts, subopt);
1794 break;
fb22e1b1
DW
1795 case P_FILE:
1796 fallthrough;
1797 default:
1798 if (cli->protofile) {
1799 if (subopt < 0)
1800 subopt = P_FILE;
1801 respec(opts->name, opts->subopts, subopt);
1802 }
1803 cli->protofile = strdup(value);
1804 if (!cli->protofile) {
1805 fprintf(stderr,
1806 _("Out of memory while saving protofile option.\n"));
1807 exit(1);
1808 }
1809 break;
1810 }
1811 return 0;
1812}
1813
a350bbc1
DC
1814static int
1815rtdev_opts_parser(
1816 struct opt_params *opts,
1817 int subopt,
9c2b30c8 1818 const char *value,
a350bbc1
DC
1819 struct cli_params *cli)
1820{
d145f69d
DC
1821 switch (subopt) {
1822 case R_EXTSIZE:
e5e612ae 1823 cli->rtextsize = getstr(value, opts, subopt);
d145f69d
DC
1824 break;
1825 case R_FILE:
e5e612ae 1826 cli->xi->risfile = getnum(value, opts, subopt);
d145f69d
DC
1827 break;
1828 case R_NAME:
1829 case R_DEV:
e5e612ae 1830 cli->xi->rtname = getstr(value, opts, subopt);
d145f69d
DC
1831 break;
1832 case R_SIZE:
e5e612ae 1833 cli->rtsize = getstr(value, opts, subopt);
d145f69d
DC
1834 break;
1835 case R_NOALIGN:
e5e612ae 1836 cli->sb_feat.nortalign = getnum(value, opts, subopt);
d145f69d
DC
1837 break;
1838 default:
1839 return -EINVAL;
1840 }
a350bbc1
DC
1841 return 0;
1842}
1843
1844static int
1845sector_opts_parser(
1846 struct opt_params *opts,
1847 int subopt,
9c2b30c8 1848 const char *value,
a350bbc1
DC
1849 struct cli_params *cli)
1850{
f948f00a 1851 switch (subopt) {
f948f00a
DC
1852 case S_SIZE:
1853 case S_SECTSIZE:
6c75555e 1854 cli->sectorsize = getnum(value, opts, subopt);
f948f00a
DC
1855 cli->lsectorsize = cli->sectorsize;
1856 break;
1857 default:
1858 return -EINVAL;
1859 }
a350bbc1
DC
1860 return 0;
1861}
1862
00ff2b10 1863static struct subopts {
a350bbc1 1864 struct opt_params *opts;
33dc45c6
ES
1865 int (*parser)(struct opt_params *opts,
1866 int subopt,
9c2b30c8 1867 const char *value,
33dc45c6 1868 struct cli_params *cli);
a350bbc1 1869} subopt_tab[] = {
ab2eef12
DC
1870 { &bopts, block_opts_parser },
1871 { &copts, cfgfile_opts_parser },
1872 { &dopts, data_opts_parser },
1873 { &iopts, inode_opts_parser },
1874 { &lopts, log_opts_parser },
1875 { &mopts, meta_opts_parser },
1876 { &nopts, naming_opts_parser },
fb22e1b1 1877 { &popts, proto_opts_parser },
ab2eef12
DC
1878 { &ropts, rtdev_opts_parser },
1879 { &sopts, sector_opts_parser },
1880 { NULL, NULL },
a350bbc1
DC
1881};
1882
1883static void
1884parse_subopts(
1885 char opt,
1886 char *arg,
1887 struct cli_params *cli)
1888{
1889 struct subopts *sop = &subopt_tab[0];
1890 char *p;
1891 int ret = 0;
1892
1893 while (sop->opts) {
ab2eef12 1894 if (sop->opts->name == opt)
a350bbc1
DC
1895 break;
1896 sop++;
1897 }
1898
1899 /* should never happen */
1900 if (!sop->opts)
1901 return;
1902
1903 p = arg;
1904 while (*p != '\0') {
1905 char **subopts = (char **)sop->opts->subopts;
1906 char *value;
1907 int subopt;
1908
1909 subopt = getsubopt(&p, subopts, &value);
1910
1911 ret = (sop->parser)(sop->opts, subopt, value, cli);
1912 if (ret)
1913 unknown(opt, value);
1914 }
1915}
1916
ab2eef12
DC
1917static bool
1918parse_cfgopt(
1919 const char *section,
1920 const char *name,
1921 const char *value,
1922 struct cli_params *cli)
1923{
1924 struct subopts *sop = &subopt_tab[0];
1925 char **subopts;
1926 int ret = 0;
1927 int i;
1928
1929 while (sop->opts) {
1930 if (sop->opts->ini_section[0] != '\0' &&
1931 strcasecmp(section, sop->opts->ini_section) == 0)
1932 break;
1933 sop++;
1934 }
1935
1936 /* Config files with unknown sections get caught here. */
1937 if (!sop->opts)
1938 goto invalid_opt;
1939
1940 subopts = (char **)sop->opts->subopts;
1941 for (i = 0; i < MAX_SUBOPTS; i++) {
1942 if (!subopts[i])
1943 break;
1944 if (strcasecmp(name, subopts[i]) == 0) {
1945 ret = (sop->parser)(sop->opts, i, value, cli);
1946 if (ret)
1947 goto invalid_opt;
1948 return true;
1949 }
1950 }
1951invalid_opt:
1952 invalid_cfgfile_opt(cli->cfgfile, section, name, value);
1953 return false;
1954}
1955
585f41bb
DC
1956static void
1957validate_sectorsize(
1958 struct mkfs_params *cfg,
1959 struct cli_params *cli,
1960 struct mkfs_default_params *dft,
1961 struct fs_topology *ft,
585f41bb
DC
1962 int dry_run,
1963 int force_overwrite)
1964{
585f41bb
DC
1965 /*
1966 * Before anything else, verify that we are correctly operating on
1967 * files or block devices and set the control parameters correctly.
1968 */
732f5b90
CH
1969 check_device_type(cli->xi->dname, &cli->xi->disfile,
1970 !cli->dsize, !cli->xi->dname,
cb46aab2 1971 dry_run ? NULL : &cli->xi->dcreat, "d");
585f41bb
DC
1972 if (!cli->loginternal)
1973 check_device_type(cli->xi->logname, &cli->xi->lisfile,
1974 !cli->logsize, !cli->xi->logname,
cb46aab2 1975 dry_run ? NULL : &cli->xi->lcreat, "l");
585f41bb
DC
1976 if (cli->xi->rtname)
1977 check_device_type(cli->xi->rtname, &cli->xi->risfile,
1978 !cli->rtsize, !cli->xi->rtname,
cb46aab2 1979 dry_run ? NULL : &cli->xi->rcreat, "r");
585f41bb
DC
1980
1981 /*
1982 * Explicitly disable direct IO for image files so we don't error out on
1983 * sector size mismatches between the new filesystem and the underlying
1984 * host filesystem.
1985 */
1986 if (cli->xi->disfile || cli->xi->lisfile || cli->xi->risfile)
1987 cli->xi->isdirect = 0;
1988
1989 memset(ft, 0, sizeof(*ft));
1990 get_topology(cli->xi, ft, force_overwrite);
1991
9f9ee751 1992 /* set configured sector sizes in preparation for checks */
585f41bb
DC
1993 if (!cli->sectorsize) {
1994 /*
1995 * Unless specified manually on the command line use the
1996 * advertised sector size of the device. We use the physical
1997 * sector size unless the requested block size is smaller
1998 * than that, then we can use logical, but warn about the
1999 * inefficiency.
2000 *
2001 * Set the topology sectors if they were not probed to the
2002 * minimum supported sector size.
2003 */
585f41bb 2004 if (!ft->lsectorsize)
9f9ee751 2005 ft->lsectorsize = dft->sectorsize;
585f41bb 2006
92abc149
JM
2007 /*
2008 * Older kernels may not have physical/logical distinction.
2009 *
2010 * Some architectures have a page size > XFS_MAX_SECTORSIZE.
2011 * In that case, a ramdisk or persistent memory device may
2012 * advertise a physical sector size that is too big to use.
2013 */
2014 if (!ft->psectorsize || ft->psectorsize > XFS_MAX_SECTORSIZE)
585f41bb
DC
2015 ft->psectorsize = ft->lsectorsize;
2016
2017 cfg->sectorsize = ft->psectorsize;
2018 if (cfg->blocksize < cfg->sectorsize &&
2019 cfg->blocksize >= ft->lsectorsize) {
2020 fprintf(stderr,
2021_("specified blocksize %d is less than device physical sector size %d\n"
2022 "switching to logical sector size %d\n"),
2023 cfg->blocksize, ft->psectorsize,
2024 ft->lsectorsize);
2025 cfg->sectorsize = ft->lsectorsize;
2026 }
9f9ee751
KX
2027 } else
2028 cfg->sectorsize = cli->sectorsize;
585f41bb 2029
9f9ee751 2030 cfg->sectorlog = libxfs_highbit32(cfg->sectorsize);
585f41bb
DC
2031
2032 /* validate specified/probed sector size */
2033 if (cfg->sectorsize < XFS_MIN_SECTORSIZE ||
2034 cfg->sectorsize > XFS_MAX_SECTORSIZE) {
2035 fprintf(stderr, _("illegal sector size %d\n"), cfg->sectorsize);
2036 usage();
2037 }
2038
2039 if (cfg->blocksize < cfg->sectorsize) {
2040 fprintf(stderr,
2041_("block size %d cannot be smaller than sector size %d\n"),
2042 cfg->blocksize, cfg->sectorsize);
2043 usage();
2044 }
2045
2046 if (cfg->sectorsize < ft->lsectorsize) {
2047 fprintf(stderr, _("illegal sector size %d; hw sector is %d\n"),
2048 cfg->sectorsize, ft->lsectorsize);
2049 usage();
2050 }
2051}
2052
b1b8e54e
DC
2053static void
2054validate_blocksize(
2055 struct mkfs_params *cfg,
2056 struct cli_params *cli,
2057 struct mkfs_default_params *dft)
2058{
2059 /*
2060 * Blocksize and sectorsize first, other things depend on them
2061 * For RAID4/5/6 we want to align sector size and block size,
2062 * so we need to start with the device geometry extraction too.
2063 */
2064 if (!cli->blocksize)
2065 cfg->blocksize = dft->blocksize;
2066 else
2067 cfg->blocksize = cli->blocksize;
2068 cfg->blocklog = libxfs_highbit32(cfg->blocksize);
2069
2070 /* validate block sizes are in range */
2071 if (cfg->blocksize < XFS_MIN_BLOCKSIZE ||
2072 cfg->blocksize > XFS_MAX_BLOCKSIZE) {
2073 fprintf(stderr, _("illegal block size %d\n"), cfg->blocksize);
2074 usage();
2075 }
2076
2077 if (cli->sb_feat.crcs_enabled &&
2078 cfg->blocksize < XFS_MIN_CRC_BLOCKSIZE) {
2079 fprintf(stderr,
2080_("Minimum block size for CRC enabled filesystems is %d bytes.\n"),
2081 XFS_MIN_CRC_BLOCKSIZE);
2082 usage();
2083 }
2084
2085}
2086
22319b56
DC
2087/*
2088 * Grab log sector size and validate.
2089 *
2090 * XXX: should we probe sector size on external log device rather than using
2091 * the data device sector size?
2092 */
2093static void
2094validate_log_sectorsize(
2095 struct mkfs_params *cfg,
2096 struct cli_params *cli,
2097 struct mkfs_default_params *dft)
2098{
2099
2100 if (cli->loginternal && cli->lsectorsize &&
2101 cli->lsectorsize != cfg->sectorsize) {
2102 fprintf(stderr,
2103_("Can't change sector size on internal log!\n"));
2104 usage();
2105 }
2106
2107 if (cli->lsectorsize)
2108 cfg->lsectorsize = cli->lsectorsize;
2109 else if (cli->loginternal)
2110 cfg->lsectorsize = cfg->sectorsize;
2111 else
2112 cfg->lsectorsize = dft->sectorsize;
2113 cfg->lsectorlog = libxfs_highbit32(cfg->lsectorsize);
2114
2115 if (cfg->lsectorsize < XFS_MIN_SECTORSIZE ||
2116 cfg->lsectorsize > XFS_MAX_SECTORSIZE ||
2117 cfg->lsectorsize > cfg->blocksize) {
2118 fprintf(stderr, _("illegal log sector size %d\n"),
2119 cfg->lsectorsize);
2120 usage();
2121 }
2122 if (cfg->lsectorsize > XFS_MIN_SECTORSIZE) {
2123 if (cli->sb_feat.log_version < 2) {
2124 /* user specified non-default log version */
2125 fprintf(stderr,
2126_("Version 1 logs do not support sector size %d\n"),
2127 cfg->lsectorsize);
2128 usage();
2129 }
2130 }
2131
2132 /* if lsu or lsunit was specified, automatically use v2 logs */
2133 if ((cli_opt_set(&lopts, L_SU) || cli_opt_set(&lopts, L_SUNIT)) &&
2134 cli->sb_feat.log_version == 1) {
2135 fprintf(stderr,
2136_("log stripe unit specified, using v2 logs\n"));
2137 cli->sb_feat.log_version = 2;
2138 }
2139
2140}
2141
a43e656b
DC
2142/*
2143 * Check that the incoming features make sense. The CLI structure was
2144 * initialised with the default values before parsing, so we can just
2145 * check it and copy it straight across to the cfg structure if it
2146 * checks out.
2147 */
2148static void
2149validate_sb_features(
2150 struct mkfs_params *cfg,
2151 struct cli_params *cli)
2152{
6a5285ec
DW
2153 if (cli->sb_feat.nci) {
2154 /*
2155 * The ascii-ci feature is deprecated in the upstream Linux
2156 * kernel. In September 2025 it will be turned off by default
2157 * in the kernel and in September 2030 support will be removed
2158 * entirely.
2159 */
2160 fprintf(stdout,
2161_("ascii-ci filesystems are deprecated and will not be supported by future versions.\n"));
2162 }
2163
a43e656b
DC
2164 /*
2165 * Now we have blocks and sector sizes set up, check parameters that are
2166 * no longer optional for CRC enabled filesystems. Catch them up front
2167 * here before doing anything else.
2168 */
2169 if (cli->sb_feat.crcs_enabled) {
2170 /* minimum inode size is 512 bytes, rest checked later */
2171 if (cli->inodesize &&
2172 cli->inodesize < (1 << XFS_DINODE_DFL_CRC_LOG)) {
2173 fprintf(stderr,
2174_("Minimum inode size for CRCs is %d bytes\n"),
2175 1 << XFS_DINODE_DFL_CRC_LOG);
2176 usage();
2177 }
2178
2179 /* inodes always aligned */
2180 if (!cli->sb_feat.inode_align) {
2181 fprintf(stderr,
9ae168bb 2182_("Inodes always aligned for CRC enabled filesystems\n"));
a43e656b
DC
2183 usage();
2184 }
2185
2186 /* lazy sb counters always on */
2187 if (!cli->sb_feat.lazy_sb_counters) {
2188 fprintf(stderr,
9393ba67 2189_("Lazy superblock counters always enabled for CRC enabled filesystems\n"));
a43e656b
DC
2190 usage();
2191 }
2192
2193 /* version 2 logs always on */
2194 if (cli->sb_feat.log_version != 2) {
2195 fprintf(stderr,
9ae168bb 2196_("V2 logs always enabled for CRC enabled filesystems\n"));
a43e656b
DC
2197 usage();
2198 }
2199
2200 /* attr2 always on */
2201 if (cli->sb_feat.attr_version != 2) {
2202 fprintf(stderr,
9ae168bb 2203_("V2 attribute format always enabled on CRC enabled filesystems\n"));
a43e656b
DC
2204 usage();
2205 }
2206
2207 /* 32 bit project quota always on */
2208 /* attr2 always on */
639d0b0b 2209 if (!cli->sb_feat.projid32bit) {
a43e656b 2210 fprintf(stderr,
9ae168bb 2211_("32 bit Project IDs always enabled on CRC enabled filesystems\n"));
a43e656b
DC
2212 usage();
2213 }
2214
2215 /* ftype always on */
2216 if (!cli->sb_feat.dirftype) {
2217 fprintf(stderr,
9ae168bb 2218_("Directory ftype field always enabled on CRC enabled filesystems\n"));
a43e656b
DC
2219 usage();
2220 }
2221
ec1b42e6 2222 } else { /* !crcs_enabled */
fc239bcb
DW
2223 /*
2224 * The V4 filesystem format is deprecated in the upstream Linux
2225 * kernel. In September 2025 it will be turned off by default
2226 * in the kernel and in September 2030 support will be removed
2227 * entirely.
2228 */
2229 fprintf(stdout,
2230_("V4 filesystems are deprecated and will not be supported by future versions.\n"));
2231
a43e656b 2232 /*
ec1b42e6
DW
2233 * The kernel doesn't support crc=0,finobt=1 filesystems.
2234 * If crcs are not enabled and the user has not explicitly
2235 * turned finobt on, then silently turn it off to avoid an
2236 * unnecessary warning.
a43e656b
DC
2237 * If the user explicitly tried to use crc=0,finobt=1,
2238 * then issue an error.
ec1b42e6 2239 * The same is also true for sparse inodes and reflink.
a43e656b
DC
2240 */
2241 if (cli->sb_feat.finobt && cli_opt_set(&mopts, M_FINOBT)) {
2242 fprintf(stderr,
2243_("finobt not supported without CRC support\n"));
2244 usage();
2245 }
2246 cli->sb_feat.finobt = false;
2247
9cf846b5 2248 if (cli->sb_feat.spinodes && cli_opt_set(&iopts, I_SPINODES)) {
a43e656b
DC
2249 fprintf(stderr,
2250_("sparse inodes not supported without CRC support\n"));
2251 usage();
2252 }
2253 cli->sb_feat.spinodes = false;
2254
4e568074 2255 if (cli->sb_feat.rmapbt && cli_opt_set(&mopts, M_RMAPBT)) {
a43e656b
DC
2256 fprintf(stderr,
2257_("rmapbt not supported without CRC support\n"));
2258 usage();
2259 }
2260 cli->sb_feat.rmapbt = false;
2261
ec1b42e6 2262 if (cli->sb_feat.reflink && cli_opt_set(&mopts, M_REFLINK)) {
a43e656b
DC
2263 fprintf(stderr,
2264_("reflink not supported without CRC support\n"));
2265 usage();
2266 }
2267 cli->sb_feat.reflink = false;
9eb0d6eb
DW
2268
2269 if (cli->sb_feat.inobtcnt && cli_opt_set(&mopts, M_INOBTCNT)) {
2270 fprintf(stderr,
2271_("inode btree counters not supported without CRC support\n"));
2272 usage();
2273 }
2274 cli->sb_feat.inobtcnt = false;
e9601810
DW
2275
2276 if (cli->sb_feat.bigtime && cli_opt_set(&mopts, M_BIGTIME)) {
2277 fprintf(stderr,
2278_("timestamps later than 2038 not supported without CRC support\n"));
2279 usage();
2280 }
2281 cli->sb_feat.bigtime = false;
69e72722
CB
2282
2283 if (cli->sb_feat.nrext64 &&
2284 cli_opt_set(&iopts, I_NREXT64)) {
2285 fprintf(stderr,
2286_("64 bit extent count not supported without CRC support\n"));
2287 usage();
2288 }
2289 cli->sb_feat.nrext64 = false;
9eb0d6eb
DW
2290 }
2291
2292 if (!cli->sb_feat.finobt) {
2293 if (cli->sb_feat.inobtcnt && cli_opt_set(&mopts, M_INOBTCNT)) {
2294 fprintf(stderr,
2295_("inode btree counters not supported without finobt support\n"));
2296 usage();
2297 }
2298 cli->sb_feat.inobtcnt = false;
a43e656b
DC
2299 }
2300
4e568074
DW
2301 if (cli->xi->rtname) {
2302 if (cli->sb_feat.reflink && cli_opt_set(&mopts, M_REFLINK)) {
2303 fprintf(stderr,
bfa66ecd 2304_("reflink not supported with realtime devices\n"));
4e568074
DW
2305 usage();
2306 }
bfa66ecd 2307 cli->sb_feat.reflink = false;
bfa66ecd 2308
4e568074
DW
2309 if (cli->sb_feat.rmapbt && cli_opt_set(&mopts, M_RMAPBT)) {
2310 fprintf(stderr,
a43e656b 2311_("rmapbt not supported with realtime devices\n"));
4e568074
DW
2312 usage();
2313 }
a43e656b
DC
2314 cli->sb_feat.rmapbt = false;
2315 }
2316
28927ccb
DW
2317 if ((cli->fsx.fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
2318 !cli->sb_feat.reflink) {
2319 fprintf(stderr,
2320_("cowextsize not supported without reflink support\n"));
2321 usage();
2322 }
2323
a43e656b
DC
2324 /*
2325 * Copy features across to config structure now.
2326 */
2327 cfg->sb_feat = cli->sb_feat;
2328 if (!platform_uuid_is_null(&cli->uuid))
2329 platform_uuid_copy(&cfg->uuid, &cli->uuid);
2330}
2331
fdea8fbc
DC
2332static void
2333validate_dirblocksize(
2334 struct mkfs_params *cfg,
2335 struct cli_params *cli)
2336{
2337
2338 if (cli->dirblocksize)
2339 cfg->dirblocksize = getnum(cli->dirblocksize, &nopts, N_SIZE);
fdea8fbc
DC
2340
2341 if (cfg->dirblocksize) {
2342 if (cfg->dirblocksize < cfg->blocksize ||
2343 cfg->dirblocksize > XFS_MAX_BLOCKSIZE) {
2344 fprintf(stderr, _("illegal directory block size %d\n"),
2345 cfg->dirblocksize);
2346 usage();
2347 }
2348 cfg->dirblocklog = libxfs_highbit32(cfg->dirblocksize);
2349 return;
2350 }
2351
2352 /* use default size based on current block size */
2353 if (cfg->blocksize < (1 << XFS_MIN_REC_DIRSIZE))
2354 cfg->dirblocklog = XFS_MIN_REC_DIRSIZE;
2355 else
2356 cfg->dirblocklog = cfg->blocklog;
2357 cfg->dirblocksize = 1 << cfg->dirblocklog;
2358}
2359
8fe29028
DC
2360static void
2361validate_inodesize(
2362 struct mkfs_params *cfg,
2363 struct cli_params *cli)
2364{
2365
2366 if (cli->inopblock)
2367 cfg->inodelog = cfg->blocklog - libxfs_highbit32(cli->inopblock);
2368 else if (cli->inodesize)
2369 cfg->inodelog = libxfs_highbit32(cli->inodesize);
2370 else if (cfg->sb_feat.crcs_enabled)
2371 cfg->inodelog = XFS_DINODE_DFL_CRC_LOG;
2372 else
2373 cfg->inodelog = XFS_DINODE_DFL_LOG;
2374
2375 cfg->inodesize = 1 << cfg->inodelog;
2376 cfg->inopblock = cfg->blocksize / cfg->inodesize;
2377
2378 /* input parsing has already validated non-crc inode size range */
2379 if (cfg->sb_feat.crcs_enabled &&
2380 cfg->inodelog < XFS_DINODE_DFL_CRC_LOG) {
2381 fprintf(stderr,
2382 _("Minimum inode size for CRCs is %d bytes\n"),
2383 1 << XFS_DINODE_DFL_CRC_LOG);
2384 usage();
2385 }
2386
2387 if (cfg->inodesize > cfg->blocksize / XFS_MIN_INODE_PERBLOCK ||
2388 cfg->inopblock < XFS_MIN_INODE_PERBLOCK ||
2389 cfg->inodesize < XFS_DINODE_MIN_SIZE ||
2390 cfg->inodesize > XFS_DINODE_MAX_SIZE) {
2391 int maxsz;
2392
2393 fprintf(stderr, _("illegal inode size %d\n"), cfg->inodesize);
68d16907 2394 maxsz = min(cfg->blocksize / XFS_MIN_INODE_PERBLOCK,
8fe29028
DC
2395 XFS_DINODE_MAX_SIZE);
2396 if (XFS_DINODE_MIN_SIZE == maxsz)
2397 fprintf(stderr,
2398 _("allowable inode size with %d byte blocks is %d\n"),
2399 cfg->blocksize, XFS_DINODE_MIN_SIZE);
2400 else
2401 fprintf(stderr,
2402 _("allowable inode size with %d byte blocks is between %d and %d\n"),
2403 cfg->blocksize, XFS_DINODE_MIN_SIZE, maxsz);
2404 exit(1);
2405 }
2406}
2407
e24dfa22
DC
2408static xfs_rfsblock_t
2409calc_dev_size(
2410 char *size,
2411 struct mkfs_params *cfg,
2412 struct opt_params *opts,
2413 int sizeopt,
2414 char *type)
2415{
2416 uint64_t dbytes;
2417 xfs_rfsblock_t dblocks;
2418
2419 if (!size)
2420 return 0;
2421
2422 dbytes = getnum(size, opts, sizeopt);
2423 if (dbytes % XFS_MIN_BLOCKSIZE) {
2424 fprintf(stderr,
2425 _("illegal %s length %lld, not a multiple of %d\n"),
2426 type, (long long)dbytes, XFS_MIN_BLOCKSIZE);
2427 usage();
2428 }
2429 dblocks = (xfs_rfsblock_t)(dbytes >> cfg->blocklog);
2430 if (dbytes % cfg->blocksize) {
2431 fprintf(stderr,
2432_("warning: %s length %lld not a multiple of %d, truncated to %lld\n"),
2433 type, (long long)dbytes, cfg->blocksize,
2434 (long long)(dblocks << cfg->blocklog));
2435 }
2436 return dblocks;
2437}
2438
80b154f7
DC
2439static void
2440validate_rtextsize(
2441 struct mkfs_params *cfg,
2442 struct cli_params *cli,
2443 struct fs_topology *ft)
2444{
2445 uint64_t rtextbytes;
2446
2447 /*
2448 * If specified, check rt extent size against its constraints.
2449 */
2450 if (cli->rtextsize) {
2451
2452 rtextbytes = getnum(cli->rtextsize, &ropts, R_EXTSIZE);
2453 if (rtextbytes % cfg->blocksize) {
2454 fprintf(stderr,
2455 _("illegal rt extent size %lld, not a multiple of %d\n"),
2456 (long long)rtextbytes, cfg->blocksize);
2457 usage();
2458 }
2459 cfg->rtextblocks = (xfs_extlen_t)(rtextbytes >> cfg->blocklog);
2460 } else {
2461 /*
2462 * If realtime extsize has not been specified by the user,
2463 * and the underlying volume is striped, then set rtextblocks
2464 * to the stripe width.
2465 */
2466 uint64_t rswidth;
2467
2468 if (!cfg->sb_feat.nortalign && !cli->xi->risfile &&
2469 !(!cli->rtsize && cli->xi->disfile))
2470 rswidth = ft->rtswidth;
2471 else
2472 rswidth = 0;
2473
2474 /* check that rswidth is a multiple of fs blocksize */
2475 if (!cfg->sb_feat.nortalign && rswidth &&
2476 !(BBTOB(rswidth) % cfg->blocksize)) {
2477 rswidth = DTOBT(rswidth, cfg->blocklog);
2478 rtextbytes = rswidth << cfg->blocklog;
2479 if (rtextbytes > XFS_MIN_RTEXTSIZE &&
2480 rtextbytes <= XFS_MAX_RTEXTSIZE) {
2481 cfg->rtextblocks = rswidth;
2482 }
2483 }
2484 if (!cfg->rtextblocks) {
2485 cfg->rtextblocks = (cfg->blocksize < XFS_MIN_RTEXTSIZE)
2486 ? XFS_MIN_RTEXTSIZE >> cfg->blocklog
2487 : 1;
2488 }
2489 }
2490 ASSERT(cfg->rtextblocks);
2491}
2492
9cfe71ba
DW
2493/* Validate the incoming extsize hint. */
2494static void
2495validate_extsize_hint(
2496 struct xfs_mount *mp,
2497 struct cli_params *cli)
2498{
2499 xfs_failaddr_t fa;
2500 uint16_t flags = 0;
2501
2502 /*
2503 * First we validate the extent size inherit hint on a directory so
2504 * that we know that we'll be propagating a correct hint and flag to
2505 * new files on the data device.
2506 */
00d139f1 2507 if (cli->fsx.fsx_xflags & FS_XFLAG_EXTSZINHERIT)
9cfe71ba
DW
2508 flags |= XFS_DIFLAG_EXTSZINHERIT;
2509
2510 fa = libxfs_inode_validate_extsize(mp, cli->fsx.fsx_extsize, S_IFDIR,
2511 flags);
2512 if (fa) {
2513 fprintf(stderr,
2514_("illegal extent size hint %lld, must be less than %u.\n"),
2515 (long long)cli->fsx.fsx_extsize,
d3e0c71f 2516 min(XFS_MAX_BMBT_EXTLEN, mp->m_sb.sb_agblocks / 2));
9cfe71ba
DW
2517 usage();
2518 }
2519
2520 /*
1e8afffb
DW
2521 * If the value is to be passed on to realtime files, revalidate with
2522 * a realtime file so that we know the hint and flag that get passed on
2523 * to realtime files will be correct.
9cfe71ba 2524 */
1e8afffb 2525 if (!(cli->fsx.fsx_xflags & FS_XFLAG_RTINHERIT))
9cfe71ba
DW
2526 return;
2527
2528 flags = XFS_DIFLAG_REALTIME;
00d139f1 2529 if (cli->fsx.fsx_xflags & FS_XFLAG_EXTSZINHERIT)
9cfe71ba
DW
2530 flags |= XFS_DIFLAG_EXTSIZE;
2531
2532 fa = libxfs_inode_validate_extsize(mp, cli->fsx.fsx_extsize, S_IFREG,
2533 flags);
2534
2535 if (fa) {
2536 fprintf(stderr,
2537_("illegal extent size hint %lld, must be less than %u and a multiple of %u.\n"),
2538 (long long)cli->fsx.fsx_extsize,
d3e0c71f 2539 min(XFS_MAX_BMBT_EXTLEN, mp->m_sb.sb_agblocks / 2),
9cfe71ba
DW
2540 mp->m_sb.sb_rextsize);
2541 usage();
2542 }
2543}
2544
2545/* Validate the incoming CoW extsize hint. */
2546static void
2547validate_cowextsize_hint(
2548 struct xfs_mount *mp,
2549 struct cli_params *cli)
2550{
2551 xfs_failaddr_t fa;
2552 uint64_t flags2 = 0;
2553
2554 /*
2555 * Validate the copy on write extent size inherit hint on a directory
2556 * so that we know that we'll be propagating a correct hint and flag to
2557 * new files on the data device.
2558 */
2559 if (cli->fsx.fsx_xflags & FS_XFLAG_COWEXTSIZE)
2560 flags2 |= XFS_DIFLAG2_COWEXTSIZE;
2561
2562 fa = libxfs_inode_validate_cowextsize(mp, cli->fsx.fsx_cowextsize,
2563 S_IFDIR, 0, flags2);
2564 if (fa) {
2565 fprintf(stderr,
2566_("illegal CoW extent size hint %lld, must be less than %u.\n"),
2567 (long long)cli->fsx.fsx_cowextsize,
d3e0c71f 2568 min(XFS_MAX_BMBT_EXTLEN, mp->m_sb.sb_agblocks / 2));
9cfe71ba
DW
2569 usage();
2570 }
2571}
2572
6e0ed3d1
DW
2573/* Complain if this filesystem is not a supported configuration. */
2574static void
2575validate_supported(
2576 struct xfs_mount *mp,
2577 struct cli_params *cli)
2578{
2579 /* Undocumented option to enable unsupported tiny filesystems. */
2580 if (!cli->is_supported) {
2581 printf(
2582 _("Filesystems formatted with --unsupported are not supported!!\n"));
2583 return;
2584 }
2585
2586 /*
2587 * fstests has a large number of tests that create tiny filesystems to
2588 * perform specific regression and resource depletion tests in a
2589 * controlled environment. Avoid breaking fstests by allowing
2590 * unsupported configurations if TEST_DIR, TEST_DEV, and QA_CHECK_FS
2591 * are all set.
2592 */
2593 if (getenv("TEST_DIR") && getenv("TEST_DEV") && getenv("QA_CHECK_FS"))
2594 return;
2595
2596 /*
2597 * We don't support filesystems smaller than 300MB anymore. Tiny
2598 * filesystems have never been XFS' design target. This limit has been
2599 * carefully calculated to prevent formatting with a log smaller than
2600 * the "realistic" size.
2601 *
2602 * If the realistic log size is 64MB, there are four AGs, and the log
2603 * AG should be at least 1/8 free after formatting, this gives us:
2604 *
2605 * 64MB * (8 / 7) * 4 = 293MB
2606 */
2607 if (mp->m_sb.sb_dblocks < MEGABYTES(300, mp->m_sb.sb_blocklog)) {
2608 fprintf(stderr,
2609 _("Filesystem must be larger than 300MB.\n"));
2610 usage();
2611 }
2612
2613 /*
2614 * For best performance, we don't allow unrealistically small logs.
2615 * See the comment for XFS_MIN_REALISTIC_LOG_BLOCKS.
2616 */
2617 if (mp->m_sb.sb_logblocks <
2618 XFS_MIN_REALISTIC_LOG_BLOCKS(mp->m_sb.sb_blocklog)) {
2619 fprintf(stderr,
2620 _("Log size must be at least 64MB.\n"));
2621 usage();
2622 }
2623
2624 /*
2625 * Filesystems should not have fewer than two AGs, because we need to
2626 * have redundant superblocks.
2627 */
2628 if (mp->m_sb.sb_agcount < 2) {
2629 fprintf(stderr,
2630 _("Filesystem must have at least 2 superblocks for redundancy!\n"));
2631 usage();
2632 }
2633}
2634
2f44b1b0
DC
2635/*
2636 * Validate the configured stripe geometry, or is none is specified, pull
2637 * the configuration from the underlying device.
2638 *
2639 * CLI parameters come in as different units, go out as filesystem blocks.
2640 */
2641static void
2642calc_stripe_factors(
2643 struct mkfs_params *cfg,
2644 struct cli_params *cli,
2645 struct fs_topology *ft)
2646{
91c7d131 2647 long long int big_dswidth;
2f44b1b0
DC
2648 int dsunit = 0;
2649 int dswidth = 0;
2650 int lsunit = 0;
2651 int dsu = 0;
2652 int dsw = 0;
2653 int lsu = 0;
2654 bool use_dev = false;
2655
2656 if (cli_opt_set(&dopts, D_SUNIT))
2657 dsunit = cli->dsunit;
2658 if (cli_opt_set(&dopts, D_SWIDTH))
2659 dswidth = cli->dswidth;
2660
2661 if (cli_opt_set(&dopts, D_SU))
2662 dsu = getnum(cli->dsu, &dopts, D_SU);
2663 if (cli_opt_set(&dopts, D_SW))
2664 dsw = cli->dsw;
2665
2666 /* data sunit/swidth options */
16adcb88 2667 if (cli_opt_set(&dopts, D_SUNIT) != cli_opt_set(&dopts, D_SWIDTH)) {
2f44b1b0
DC
2668 fprintf(stderr,
2669_("both data sunit and data swidth options must be specified\n"));
2670 usage();
2671 }
2672
2673 /* convert dsu/dsw to dsunit/dswidth and use them from now on */
2674 if (dsu || dsw) {
16adcb88 2675 if (cli_opt_set(&dopts, D_SU) != cli_opt_set(&dopts, D_SW)) {
2f44b1b0
DC
2676 fprintf(stderr,
2677_("both data su and data sw options must be specified\n"));
2678 usage();
2679 }
2680
060ea87a
GX
2681 big_dswidth = (long long int)dsu * dsw;
2682 if (BTOBBT(big_dswidth) > INT_MAX) {
2f44b1b0 2683 fprintf(stderr,
060ea87a
GX
2684_("data stripe width (%lld) is too large of a multiple of the data stripe unit (%d)\n"),
2685 big_dswidth, dsu);
2f44b1b0
DC
2686 usage();
2687 }
2688
060ea87a
GX
2689 if (!libxfs_validate_stripe_geometry(NULL, dsu, big_dswidth,
2690 cfg->sectorsize, false))
91c7d131 2691 usage();
2f44b1b0 2692
060ea87a
GX
2693 dsunit = BTOBBT(dsu);
2694 dswidth = BTOBBT(big_dswidth);
2695 } else if (!libxfs_validate_stripe_geometry(NULL, BBTOB(dsunit),
2696 BBTOB(dswidth), cfg->sectorsize, false)) {
2f44b1b0
DC
2697 usage();
2698 }
2699
2700 /* If sunit & swidth were manually specified as 0, same as noalign */
2701 if ((cli_opt_set(&dopts, D_SUNIT) || cli_opt_set(&dopts, D_SU)) &&
2702 !dsunit && !dswidth)
2703 cfg->sb_feat.nodalign = true;
2704
2705 /* if we are not using alignment, don't apply device defaults */
2706 if (cfg->sb_feat.nodalign) {
2707 cfg->dsunit = 0;
2708 cfg->dswidth = 0;
2709 goto check_lsunit;
2710 }
2711
2712 /* if no stripe config set, use the device default */
2713 if (!dsunit) {
060ea87a
GX
2714 /* Ignore nonsense from device report. */
2715 if (!libxfs_validate_stripe_geometry(NULL, BBTOB(ft->dsunit),
2716 BBTOB(ft->dswidth), 0, true)) {
99a3f52e 2717 fprintf(stderr,
060ea87a
GX
2718_("%s: Volume reports invalid stripe unit (%d) and stripe width (%d), ignoring.\n"),
2719 progname, BBTOB(ft->dsunit), BBTOB(ft->dswidth));
99a3f52e
JM
2720 ft->dsunit = 0;
2721 ft->dswidth = 0;
42371fb3
DW
2722 } else if (cfg->dblocks < GIGABYTES(1, cfg->blocklog)) {
2723 /*
2724 * Don't use automatic stripe detection if the device
2725 * size is less than 1GB because the performance gains
2726 * on such a small system are not worth the risk that
2727 * we'll end up with an undersized log.
2728 */
2729 if (ft->dsunit || ft->dswidth)
2730 fprintf(stderr,
2731_("%s: small data volume, ignoring data volume stripe unit %d and stripe width %d\n"),
2732 progname, ft->dsunit,
2733 ft->dswidth);
2734 ft->dsunit = 0;
2735 ft->dswidth = 0;
99a3f52e
JM
2736 } else {
2737 dsunit = ft->dsunit;
2738 dswidth = ft->dswidth;
2739 use_dev = true;
2740 }
2f44b1b0 2741 } else {
99a3f52e 2742 /* check and warn if user-specified alignment is sub-optimal */
2f44b1b0
DC
2743 if (ft->dsunit && ft->dsunit != dsunit) {
2744 fprintf(stderr,
2745_("%s: Specified data stripe unit %d is not the same as the volume stripe unit %d\n"),
2746 progname, dsunit, ft->dsunit);
2747 }
2748 if (ft->dswidth && ft->dswidth != dswidth) {
2749 fprintf(stderr,
2750_("%s: Specified data stripe width %d is not the same as the volume stripe width %d\n"),
2751 progname, dswidth, ft->dswidth);
2752 }
2753 }
2754
2755 /*
2756 * now we have our stripe config, check it's a multiple of block
2757 * size.
2758 */
2759 if ((BBTOB(dsunit) % cfg->blocksize) ||
2760 (BBTOB(dswidth) % cfg->blocksize)) {
2761 /*
2762 * If we are using device defaults, just clear them and we're
2763 * good to go. Otherwise bail out with an error.
2764 */
2765 if (!use_dev) {
2766 fprintf(stderr,
2767_("%s: Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n"),
2768 progname, BBTOB(dsunit), BBTOB(dswidth),
2769 cfg->blocksize);
2770 exit(1);
2771 }
2772 dsunit = 0;
2773 dswidth = 0;
2774 cfg->sb_feat.nodalign = true;
2775 }
2776
2777 /* convert from 512 byte blocks to fs blocksize */
2778 cfg->dsunit = DTOBT(dsunit, cfg->blocklog);
2779 cfg->dswidth = DTOBT(dswidth, cfg->blocklog);
2780
2781check_lsunit:
2782 /* log sunit options */
2783 if (cli_opt_set(&lopts, L_SUNIT))
2784 lsunit = cli->lsunit;
2785 else if (cli_opt_set(&lopts, L_SU))
2786 lsu = getnum(cli->lsu, &lopts, L_SU);
2787 else if (cfg->lsectorsize > XLOG_HEADER_SIZE)
2788 lsu = cfg->blocksize; /* lsunit matches filesystem block size */
2789
2790 if (lsu) {
2791 /* verify if lsu is a multiple block size */
2792 if (lsu % cfg->blocksize != 0) {
2793 fprintf(stderr,
2794 _("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
2795 lsu, cfg->blocksize);
2796 usage();
2797 }
2798 lsunit = (int)BTOBBT(lsu);
2799 }
2800 if (BBTOB(lsunit) % cfg->blocksize != 0) {
2801 fprintf(stderr,
2802_("log stripe unit (%d) must be a multiple of the block size (%d)\n"),
2803 BBTOB(lsunit), cfg->blocksize);
2804 usage();
2805 }
2806
2807 /*
2808 * check that log sunit is modulo fsblksize or default it to dsunit.
2809 */
2810 if (lsunit) {
2811 /* convert from 512 byte blocks to fs blocks */
2812 cfg->lsunit = DTOBT(lsunit, cfg->blocklog);
2813 } else if (cfg->sb_feat.log_version == 2 &&
2814 cfg->loginternal && cfg->dsunit) {
2815 /* lsunit and dsunit now in fs blocks */
2816 cfg->lsunit = cfg->dsunit;
2817 }
2818
2819 if (cfg->sb_feat.log_version == 2 &&
2820 cfg->lsunit * cfg->blocksize > 256 * 1024) {
2821 /* Warn only if specified on commandline */
2822 if (cli->lsu || cli->lsunit != -1) {
2823 fprintf(stderr,
2824_("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n"
2825 "log stripe unit adjusted to 32KiB\n"),
2826 (cfg->lsunit * cfg->blocksize));
2827 }
2828 /* XXX: 64k block size? */
2829 cfg->lsunit = (32 * 1024) / cfg->blocksize;
2830 }
2831
2832}
2833
379f01d2
DC
2834static void
2835open_devices(
2836 struct mkfs_params *cfg,
01dcfd9e 2837 struct libxfs_init *xi)
379f01d2
DC
2838{
2839 uint64_t sector_mask;
2840
2841 /*
2842 * Initialize. This will open the log and rt devices as well.
2843 */
2844 xi->setblksize = cfg->sectorsize;
2845 if (!libxfs_init(xi))
2846 usage();
2847 if (!xi->ddev) {
2848 fprintf(stderr, _("no device name given in argument list\n"));
2849 usage();
2850 }
2851
2852 /*
2853 * Ok, Linux only has a 1024-byte resolution on device _size_,
2854 * and the sizes below are in basic 512-byte blocks,
2855 * so if we have (size % 2), on any partition, we can't get
2856 * to the last 512 bytes. The same issue exists for larger
2857 * sector sizes - we cannot write past the last sector.
2858 *
2859 * So, we reduce the size (in basic blocks) to a perfect
2860 * multiple of the sector size, or 1024, whichever is larger.
2861 */
68d16907 2862 sector_mask = (uint64_t)-1 << (max(cfg->sectorlog, 10) - BBSHIFT);
379f01d2
DC
2863 xi->dsize &= sector_mask;
2864 xi->rtsize &= sector_mask;
68d16907 2865 xi->logBBsize &= (uint64_t)-1 << (max(cfg->lsectorlog, 10) - BBSHIFT);
915a27a0 2866}
379f01d2 2867
915a27a0
JT
2868static void
2869discard_devices(
01dcfd9e 2870 struct libxfs_init *xi,
7e8a6edb 2871 int quiet)
915a27a0
JT
2872{
2873 /*
2874 * This function has to be called after libxfs has been initialized.
2875 */
379f01d2
DC
2876
2877 if (!xi->disfile)
7e8a6edb 2878 discard_blocks(xi->ddev, xi->dsize, quiet);
379f01d2 2879 if (xi->rtdev && !xi->risfile)
7e8a6edb 2880 discard_blocks(xi->rtdev, xi->rtsize, quiet);
379f01d2 2881 if (xi->logdev && xi->logdev != xi->ddev && !xi->lisfile)
7e8a6edb 2882 discard_blocks(xi->logdev, xi->logBBsize, quiet);
379f01d2
DC
2883}
2884
dd5ac314
DC
2885static void
2886validate_datadev(
2887 struct mkfs_params *cfg,
2888 struct cli_params *cli)
2889{
01dcfd9e 2890 struct libxfs_init *xi = cli->xi;
dd5ac314
DC
2891
2892 if (!xi->dsize) {
2893 /*
2894 * if the device is a file, we can't validate the size here.
2895 * Instead, the file will be truncated to the correct length
2896 * later on. if it's not a file, we've got a dud device.
2897 */
2898 if (!xi->disfile) {
2899 fprintf(stderr, _("can't get size of data subvolume\n"));
2900 usage();
2901 }
2902 ASSERT(cfg->dblocks);
2903 } else if (cfg->dblocks) {
2904 /* check the size fits into the underlying device */
2905 if (cfg->dblocks > DTOBT(xi->dsize, cfg->blocklog)) {
2906 fprintf(stderr,
2907_("size %s specified for data subvolume is too large, maximum is %lld blocks\n"),
2908 cli->dsize,
2909 (long long)DTOBT(xi->dsize, cfg->blocklog));
2910 usage();
2911 }
2912 } else {
2913 /* no user size, so use the full block device */
2914 cfg->dblocks = DTOBT(xi->dsize, cfg->blocklog);
2915 }
2916
97a40596 2917 if (cfg->dblocks < XFS_MIN_DATA_BLOCKS(cfg)) {
dd5ac314 2918 fprintf(stderr,
97a40596
PR
2919_("size %lld of data subvolume is too small, minimum %lld blocks\n"),
2920 (long long)cfg->dblocks, XFS_MIN_DATA_BLOCKS(cfg));
dd5ac314
DC
2921 usage();
2922 }
2923
2924 if (xi->dbsize > cfg->sectorsize) {
2925 fprintf(stderr, _(
2926"Warning: the data subvolume sector size %u is less than the sector size \n\
2927reported by the device (%u).\n"),
2928 cfg->sectorsize, xi->dbsize);
2929 }
2930}
2931
90b7e13d
DC
2932static void
2933validate_logdev(
2934 struct mkfs_params *cfg,
732f5b90 2935 struct cli_params *cli)
90b7e13d 2936{
01dcfd9e 2937 struct libxfs_init *xi = cli->xi;
90b7e13d 2938
732f5b90 2939 cfg->loginternal = cli->loginternal;
90b7e13d
DC
2940
2941 /* now run device checks */
2942 if (cfg->loginternal) {
90b7e13d
DC
2943 /*
2944 * if no sector size has been specified on the command line,
2945 * use what has been configured and validated for the data
2946 * device.
2947 */
2948 if (!cli->lsectorsize) {
2949 cfg->lsectorsize = cfg->sectorsize;
2950 cfg->lsectorlog = cfg->sectorlog;
2951 }
2952
2953 if (cfg->sectorsize != cfg->lsectorsize) {
2954 fprintf(stderr,
2955_("data and log sector sizes must be equal for internal logs\n"));
2956 usage();
2957 }
2958 if (cli->logsize && cfg->logblocks >= cfg->dblocks) {
2959 fprintf(stderr,
2960_("log size %lld too large for internal log\n"),
2961 (long long)cfg->logblocks);
2962 usage();
2963 }
90b7e13d
DC
2964 return;
2965 }
2966
2967 /* External/log subvolume checks */
732f5b90 2968 if (!*xi->logname || !xi->logdev) {
90b7e13d
DC
2969 fprintf(stderr, _("no log subvolume or external log.\n"));
2970 usage();
2971 }
2972
2973 if (!cfg->logblocks) {
2974 if (xi->logBBsize == 0) {
2975 fprintf(stderr,
2976_("unable to get size of the log subvolume.\n"));
2977 usage();
2978 }
2979 cfg->logblocks = DTOBT(xi->logBBsize, cfg->blocklog);
2980 } else if (cfg->logblocks > DTOBT(xi->logBBsize, cfg->blocklog)) {
2981 fprintf(stderr,
2982_("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
2983 cli->logsize,
2984 (long long)DTOBT(xi->logBBsize, cfg->blocklog));
2985 usage();
2986 }
2987
2988 if (xi->lbsize > cfg->lsectorsize) {
2989 fprintf(stderr, _(
2990"Warning: the log subvolume sector size %u is less than the sector size\n\
2991reported by the device (%u).\n"),
2992 cfg->lsectorsize, xi->lbsize);
2993 }
2994}
2995
7a9af89a
DC
2996static void
2997validate_rtdev(
2998 struct mkfs_params *cfg,
732f5b90 2999 struct cli_params *cli)
7a9af89a 3000{
01dcfd9e 3001 struct libxfs_init *xi = cli->xi;
7a9af89a 3002
7a9af89a
DC
3003 if (!xi->rtdev) {
3004 if (cli->rtsize) {
3005 fprintf(stderr,
3006_("size specified for non-existent rt subvolume\n"));
3007 usage();
3008 }
3009
7a9af89a
DC
3010 cfg->rtblocks = 0;
3011 cfg->rtextents = 0;
3012 cfg->rtbmblocks = 0;
3013 return;
3014 }
3015 if (!xi->rtsize) {
3016 fprintf(stderr, _("Invalid zero length rt subvolume found\n"));
3017 usage();
3018 }
3019
7a9af89a
DC
3020 if (cli->rtsize) {
3021 if (cfg->rtblocks > DTOBT(xi->rtsize, cfg->blocklog)) {
3022 fprintf(stderr,
3023_("size %s specified for rt subvolume is too large, maxi->um is %lld blocks\n"),
3024 cli->rtsize,
3025 (long long)DTOBT(xi->rtsize, cfg->blocklog));
3026 usage();
3027 }
3028 if (xi->rtbsize > cfg->sectorsize) {
3029 fprintf(stderr, _(
3030"Warning: the realtime subvolume sector size %u is less than the sector size\n\
3031reported by the device (%u).\n"),
3032 cfg->sectorsize, xi->rtbsize);
3033 }
3034 } else {
3035 /* grab volume size */
3036 cfg->rtblocks = DTOBT(xi->rtsize, cfg->blocklog);
3037 }
3038
3039 cfg->rtextents = cfg->rtblocks / cfg->rtextblocks;
3040 cfg->rtbmblocks = (xfs_extlen_t)howmany(cfg->rtextents,
3041 NBBY * cfg->blocksize);
3042}
3043
1de01446
DC
3044static void
3045calculate_initial_ag_geometry(
3046 struct mkfs_params *cfg,
3047 struct cli_params *cli)
3048{
3049 if (cli->agsize) { /* User-specified AG size */
3050 cfg->agsize = getnum(cli->agsize, &dopts, D_AGSIZE);
3051
3052 /*
3053 * Check specified agsize is a multiple of blocksize.
3054 */
3055 if (cfg->agsize % cfg->blocksize) {
3056 fprintf(stderr,
3057_("agsize (%s) not a multiple of fs blk size (%d)\n"),
3058 cli->agsize, cfg->blocksize);
3059 usage();
3060 }
3061 cfg->agsize /= cfg->blocksize;
3062 cfg->agcount = cfg->dblocks / cfg->agsize +
3063 (cfg->dblocks % cfg->agsize != 0);
3064
3065 } else if (cli->agcount) { /* User-specified AG count */
3066 cfg->agcount = cli->agcount;
3067 cfg->agsize = cfg->dblocks / cfg->agcount +
3068 (cfg->dblocks % cfg->agcount != 0);
3069 } else {
3070 calc_default_ag_geometry(cfg->blocklog, cfg->dblocks,
3071 cfg->dsunit, &cfg->agsize,
3072 &cfg->agcount);
3073 }
3074}
3075
051b4e37
DC
3076/*
3077 * Align the AG size to stripe geometry. If this fails and we are using
3078 * discovered stripe geometry, tell the caller to clear the stripe geometry.
3079 * Otherwise, set the aligned geometry (valid or invalid!) so that the
3080 * validation call will fail and exit.
3081 */
3082static void
3083align_ag_geometry(
3084 struct mkfs_params *cfg)
3085{
3086 uint64_t tmp_agsize;
3087 int dsunit = cfg->dsunit;
3088
3089 if (!dsunit)
3090 goto validate;
3091
3092 /*
3093 * agsize is not a multiple of dsunit
3094 */
3095 if ((cfg->agsize % dsunit) != 0) {
3096 /*
3097 * Round up to stripe unit boundary. Also make sure
3098 * that agsize is still larger than
3099 * XFS_AG_MIN_BLOCKS(blocklog)
3100 */
3101 tmp_agsize = ((cfg->agsize + dsunit - 1) / dsunit) * dsunit;
3102 /*
3103 * Round down to stripe unit boundary if rounding up
3104 * created an AG size that is larger than the AG max.
3105 */
3106 if (tmp_agsize > XFS_AG_MAX_BLOCKS(cfg->blocklog))
3107 tmp_agsize = (cfg->agsize / dsunit) * dsunit;
3108
3109 if (tmp_agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog) &&
3110 tmp_agsize > XFS_AG_MAX_BLOCKS(cfg->blocklog)) {
3111
3112 /*
3113 * If the AG size is invalid and we are using device
3114 * probed stripe alignment, just clear the alignment
3115 * and continue on.
3116 */
3117 if (!cli_opt_set(&dopts, D_SUNIT) &&
3118 !cli_opt_set(&dopts, D_SU)) {
3119 cfg->dsunit = 0;
3120 cfg->dswidth = 0;
3121 goto validate;
3122 }
3123 /*
3124 * set the agsize to the invalid value so the following
3125 * validation of the ag will fail and print a nice error
3126 * and exit.
3127 */
3128 cfg->agsize = tmp_agsize;
3129 goto validate;
3130 }
3131
3132 /* update geometry to be stripe unit aligned */
3133 cfg->agsize = tmp_agsize;
3134 if (!cli_opt_set(&dopts, D_AGCOUNT))
3135 cfg->agcount = cfg->dblocks / cfg->agsize +
3136 (cfg->dblocks % cfg->agsize != 0);
3137 if (cli_opt_set(&dopts, D_AGSIZE))
3138 fprintf(stderr,
3139_("agsize rounded to %lld, sunit = %d\n"),
3140 (long long)cfg->agsize, dsunit);
3141 }
3142
3143 if ((cfg->agsize % cfg->dswidth) == 0 &&
3144 cfg->dswidth != cfg->dsunit &&
3145 cfg->agcount > 1) {
3146
3147 if (cli_opt_set(&dopts, D_AGCOUNT) ||
3148 cli_opt_set(&dopts, D_AGSIZE)) {
ffb1fbc8 3149 printf(_(
051b4e37
DC
3150"Warning: AG size is a multiple of stripe width. This can cause performance\n\
3151problems by aligning all AGs on the same disk. To avoid this, run mkfs with\n\
3152an AG size that is one stripe unit smaller or larger, for example %llu.\n"),
3153 (unsigned long long)cfg->agsize - dsunit);
ffb1fbc8 3154 fflush(stdout);
051b4e37
DC
3155 goto validate;
3156 }
3157
3158 /*
3159 * This is a non-optimal configuration because all AGs start on
3160 * the same disk in the stripe. Changing the AG size by one
3161 * sunit will guarantee that this does not happen.
3162 */
3163 tmp_agsize = cfg->agsize - dsunit;
3164 if (tmp_agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog)) {
3165 tmp_agsize = cfg->agsize + dsunit;
3166 if (cfg->dblocks < cfg->agsize) {
3167 /* oh well, nothing to do */
3168 tmp_agsize = cfg->agsize;
3169 }
3170 }
3171
3172 cfg->agsize = tmp_agsize;
3173 cfg->agcount = cfg->dblocks / cfg->agsize +
3174 (cfg->dblocks % cfg->agsize != 0);
3175 }
3176
3177validate:
3178 /*
3179 * If the last AG is too small, reduce the filesystem size
3180 * and drop the blocks.
3181 */
3182 if (cfg->dblocks % cfg->agsize != 0 &&
3183 (cfg->dblocks % cfg->agsize < XFS_AG_MIN_BLOCKS(cfg->blocklog))) {
3184 ASSERT(!cli_opt_set(&dopts, D_AGCOUNT));
3185 cfg->dblocks = (xfs_rfsblock_t)((cfg->agcount - 1) * cfg->agsize);
3186 cfg->agcount--;
3187 ASSERT(cfg->agcount != 0);
3188 }
3189
3190 validate_ag_geometry(cfg->blocklog, cfg->dblocks,
3191 cfg->agsize, cfg->agcount);
3192}
3193
d7240c96
DC
3194static void
3195calculate_imaxpct(
3196 struct mkfs_params *cfg,
3197 struct cli_params *cli)
3198{
3199 cfg->imaxpct = cli->imaxpct;
3200 if (cfg->imaxpct)
3201 return;
3202
3203 /*
3204 * This returns the % of the disk space that is used for
3205 * inodes, it changes relatively to the FS size:
3206 * - over 50 TB, use 1%,
3207 * - 1TB - 50 TB, use 5%,
3208 * - under 1 TB, use XFS_DFL_IMAXIMUM_PCT (25%).
3209 */
3210
3211 if (cfg->dblocks < TERABYTES(1, cfg->blocklog))
3212 cfg->imaxpct = XFS_DFL_IMAXIMUM_PCT;
3213 else if (cfg->dblocks < TERABYTES(50, cfg->blocklog))
3214 cfg->imaxpct = 5;
3215 else
3216 cfg->imaxpct = 1;
3217}
3218
befcd768
DC
3219/*
3220 * Set up the initial state of the superblock so we can start using the
3221 * libxfs geometry macros.
3222 */
3223static void
3224sb_set_features(
3225 struct mkfs_params *cfg,
3226 struct xfs_sb *sbp)
3227{
3228 struct sb_feat_args *fp = &cfg->sb_feat;
3229
3230 sbp->sb_versionnum = XFS_DFL_SB_VERSION_BITS;
3231 if (fp->crcs_enabled)
3232 sbp->sb_versionnum |= XFS_SB_VERSION_5;
3233 else
3234 sbp->sb_versionnum |= XFS_SB_VERSION_4;
3235
3236 if (fp->inode_align) {
3237 int cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
3238
3239 sbp->sb_versionnum |= XFS_SB_VERSION_ALIGNBIT;
3240 if (cfg->sb_feat.crcs_enabled)
3241 cluster_size *= cfg->inodesize / XFS_DINODE_MIN_SIZE;
3242 sbp->sb_inoalignmt = cluster_size >> cfg->blocklog;
3243 } else
3244 sbp->sb_inoalignmt = 0;
3245
3246 if (cfg->dsunit)
3247 sbp->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT;
3248 if (fp->log_version == 2)
3249 sbp->sb_versionnum |= XFS_SB_VERSION_LOGV2BIT;
3250 if (fp->attr_version == 1)
3251 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
3252 if (fp->nci)
3253 sbp->sb_versionnum |= XFS_SB_VERSION_BORGBIT;
3254
3255 if (cfg->sectorsize > BBSIZE || cfg->lsectorsize > BBSIZE) {
3256 sbp->sb_versionnum |= XFS_SB_VERSION_SECTORBIT;
3257 sbp->sb_logsectlog = (uint8_t)cfg->lsectorlog;
3258 sbp->sb_logsectsize = (uint16_t)cfg->lsectorsize;
3259 } else {
3260 sbp->sb_logsectlog = 0;
3261 sbp->sb_logsectsize = 0;
3262 }
3263
3264 sbp->sb_features2 = 0;
3265 if (fp->lazy_sb_counters)
3266 sbp->sb_features2 |= XFS_SB_VERSION2_LAZYSBCOUNTBIT;
639d0b0b 3267 if (fp->projid32bit)
befcd768
DC
3268 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
3269 if (fp->parent_pointers)
3270 sbp->sb_features2 |= XFS_SB_VERSION2_PARENTBIT;
3271 if (fp->crcs_enabled)
3272 sbp->sb_features2 |= XFS_SB_VERSION2_CRCBIT;
3273 if (fp->attr_version == 2)
3274 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
3275
3276 /* v5 superblocks have their own feature bit for dirftype */
3277 if (fp->dirftype && !fp->crcs_enabled)
3278 sbp->sb_features2 |= XFS_SB_VERSION2_FTYPE;
3279
3280 /* update whether extended features are in use */
3281 if (sbp->sb_features2 != 0)
3282 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
3283
3284 /*
3285 * Due to a structure alignment issue, sb_features2 ended up in one
3286 * of two locations, the second "incorrect" location represented by
3287 * the sb_bad_features2 field. To avoid older kernels mounting
3288 * filesystems they shouldn't, set both field to the same value.
3289 */
3290 sbp->sb_bad_features2 = sbp->sb_features2;
3291
3292 if (!fp->crcs_enabled)
3293 return;
3294
3295 /* default features for v5 filesystems */
3296 sbp->sb_features_compat = 0;
3297 sbp->sb_features_ro_compat = 0;
3298 sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE;
3299 sbp->sb_features_log_incompat = 0;
3300
3301 if (fp->finobt)
3302 sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT;
3303 if (fp->rmapbt)
3304 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT;
3305 if (fp->reflink)
3306 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
9eb0d6eb
DW
3307 if (fp->inobtcnt)
3308 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
e9601810
DW
3309 if (fp->bigtime)
3310 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
befcd768
DC
3311
3312 /*
3313 * Sparse inode chunk support has two main inode alignment requirements.
3314 * First, sparse chunk alignment must match the cluster size. Second,
3315 * full chunk alignment must match the inode chunk size.
3316 *
3317 * Copy the already calculated/scaled inoalignmt to spino_align and
3318 * update the former to the full inode chunk size.
3319 */
3320 if (fp->spinodes) {
3321 sbp->sb_spino_align = sbp->sb_inoalignmt;
3322 sbp->sb_inoalignmt = XFS_INODES_PER_CHUNK *
3323 cfg->inodesize >> cfg->blocklog;
3324 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_SPINODES;
3325 }
3326
69e72722
CB
3327 if (fp->nrext64)
3328 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
befcd768
DC
3329}
3330
e3bc8390
DC
3331/*
3332 * Make sure that the log size is a multiple of the stripe unit
3333 */
3334static void
3335align_log_size(
3336 struct mkfs_params *cfg,
8d1bff2b
DW
3337 int sunit,
3338 int max_logblocks)
e3bc8390 3339{
8d1bff2b 3340 uint64_t tmp_logblocks;
e3bc8390
DC
3341
3342 /* nothing to do if it's already aligned. */
3343 if ((cfg->logblocks % sunit) == 0)
3344 return;
3345
3346 if (cli_opt_set(&lopts, L_SIZE)) {
3347 fprintf(stderr,
3348_("log size %lld is not a multiple of the log stripe unit %d\n"),
3349 (long long) cfg->logblocks, sunit);
3350 usage();
3351 }
3352
3353 tmp_logblocks = ((cfg->logblocks + (sunit - 1)) / sunit) * sunit;
3354
3355 /* If the log is too large, round down instead of round up */
3356 if ((tmp_logblocks > XFS_MAX_LOG_BLOCKS) ||
8d1bff2b
DW
3357 ((tmp_logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES) ||
3358 tmp_logblocks > max_logblocks) {
e3bc8390
DC
3359 tmp_logblocks = (cfg->logblocks / sunit) * sunit;
3360 }
3361 cfg->logblocks = tmp_logblocks;
3362}
3363
3364/*
3365 * Make sure that the internal log is correctly aligned to the specified
3366 * stripe unit.
3367 */
3368static void
3369align_internal_log(
3370 struct mkfs_params *cfg,
3371 struct xfs_mount *mp,
8d1bff2b
DW
3372 int sunit,
3373 int max_logblocks)
e3bc8390
DC
3374{
3375 /* round up log start if necessary */
3376 if ((cfg->logstart % sunit) != 0)
3377 cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit;
3378
8da52988 3379 /* If our log start overlaps the next AG's metadata, fail. */
93a199f2
DW
3380 if (!libxfs_verify_fsbno(mp, cfg->logstart)) {
3381 fprintf(stderr,
8da52988
DW
3382_("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n"
3383 "within an allocation group.\n"),
3384 (long long) cfg->logstart);
3385 usage();
3386 }
3387
e3bc8390 3388 /* round up/down the log size now */
8d1bff2b 3389 align_log_size(cfg, sunit, max_logblocks);
e3bc8390 3390
0da883dd
DW
3391 /*
3392 * If the end of the log has been rounded past the end of the AG,
3393 * reduce logblocks by a stripe unit to try to get it back under EOAG.
3394 */
3395 if (!libxfs_verify_fsbext(mp, cfg->logstart, cfg->logblocks) &&
3396 cfg->logblocks > sunit) {
3397 cfg->logblocks -= sunit;
3398 }
3399
9c726ef0 3400 /* check the aligned log still starts and ends in the same AG. */
93a199f2 3401 if (!libxfs_verify_fsbext(mp, cfg->logstart, cfg->logblocks)) {
e3bc8390
DC
3402 fprintf(stderr,
3403_("Due to stripe alignment, the internal log size (%lld) is too large.\n"
3404 "Must fit within an allocation group.\n"),
3405 (long long) cfg->logblocks);
3406 usage();
3407 }
3408}
3409
00ff2b10 3410static void
e3bc8390
DC
3411validate_log_size(uint64_t logblocks, int blocklog, int min_logblocks)
3412{
3413 if (logblocks < min_logblocks) {
3414 fprintf(stderr,
3415 _("log size %lld blocks too small, minimum size is %d blocks\n"),
3416 (long long)logblocks, min_logblocks);
3417 usage();
3418 }
3419 if (logblocks > XFS_MAX_LOG_BLOCKS) {
3420 fprintf(stderr,
3421 _("log size %lld blocks too large, maximum size is %lld blocks\n"),
3422 (long long)logblocks, XFS_MAX_LOG_BLOCKS);
3423 usage();
3424 }
3425 if ((logblocks << blocklog) > XFS_MAX_LOG_BYTES) {
3426 fprintf(stderr,
3427 _("log size %lld bytes too large, maximum size is %lld bytes\n"),
3428 (long long)(logblocks << blocklog), XFS_MAX_LOG_BYTES);
3429 usage();
3430 }
3431}
3432
1b580a77
DW
3433static void
3434adjust_ag0_internal_logblocks(
3435 struct mkfs_params *cfg,
3436 struct xfs_mount *mp,
3437 int min_logblocks,
3438 int *max_logblocks)
3439{
3440 int backoff = 0;
3441 int ichunk_blocks;
3442
3443 /*
3444 * mkfs will trip over the write verifiers if the log is allocated in
3445 * AG 0 and consumes enough space that we cannot allocate a non-sparse
3446 * inode chunk for the root directory. The inode allocator requires
3447 * that the AG have enough free space for the chunk itself plus enough
3448 * to fix up the freelist with aligned blocks if we need to fill the
3449 * allocation from the AGFL.
3450 */
3451 ichunk_blocks = XFS_INODES_PER_CHUNK * cfg->inodesize >> cfg->blocklog;
3452 backoff = ichunk_blocks * 4;
3453
3454 /*
3455 * We try to align inode allocations to the data device stripe unit,
3456 * so ensure there's enough space to perform an aligned allocation.
3457 * The inode geometry structure isn't set up yet, so compute this by
3458 * hand.
3459 */
3460 backoff = max(backoff, cfg->dsunit * 2);
3461
3462 *max_logblocks -= backoff;
3463
3464 /* If the specified log size is too big, complain. */
3465 if (cli_opt_set(&lopts, L_SIZE) && cfg->logblocks > *max_logblocks) {
3466 fprintf(stderr,
3467_("internal log size %lld too large, must be less than %d\n"),
3468 (long long)cfg->logblocks,
3469 *max_logblocks);
3470 usage();
3471 }
3472
3473 cfg->logblocks = min(cfg->logblocks, *max_logblocks);
3474}
3475
e3bc8390
DC
3476static void
3477calculate_log_size(
3478 struct mkfs_params *cfg,
3479 struct cli_params *cli,
3480 struct xfs_mount *mp)
3481{
e3bc8390 3482 struct xfs_sb *sbp = &mp->m_sb;
cdfa467e 3483 int min_logblocks; /* absolute minimum */
aba6743c 3484 int max_logblocks; /* absolute max for this AG */
a6fb6abe 3485 struct xfs_mount mount;
ddd9942b 3486 struct libxfs_init dummy_init = { };
e3bc8390 3487
a6fb6abe
DC
3488 /* we need a temporary mount to calculate the minimum log size. */
3489 memset(&mount, 0, sizeof(mount));
3490 mount.m_sb = *sbp;
ddd9942b 3491 libxfs_mount(&mount, &mp->m_sb, &dummy_init, 0);
a6fb6abe
DC
3492 min_logblocks = libxfs_log_calc_minimum_size(&mount);
3493 libxfs_umount(&mount);
e3bc8390
DC
3494
3495 ASSERT(min_logblocks);
68d16907 3496 min_logblocks = max(XFS_MIN_LOG_BLOCKS, min_logblocks);
e3bc8390
DC
3497
3498 /* if we have lots of blocks, check against XFS_MIN_LOG_BYTES, too */
3499 if (!cli->logsize &&
3500 cfg->dblocks >= (1024*1024*1024) >> cfg->blocklog)
68d16907 3501 min_logblocks = max(min_logblocks,
e3bc8390
DC
3502 XFS_MIN_LOG_BYTES >> cfg->blocklog);
3503
3504 /*
3505 * external logs will have a device and size by now, so all we have
3506 * to do is validate it against minimum size and align it.
3507 */
3508 if (!cfg->loginternal) {
3509 if (min_logblocks > cfg->logblocks) {
3510 fprintf(stderr,
4f6eceed 3511_("external log device size %lld blocks too small, must be at least %lld blocks\n"),
e3bc8390
DC
3512 (long long)cfg->logblocks,
3513 (long long)min_logblocks);
3514 usage();
3515 }
3516 cfg->logstart = 0;
3517 cfg->logagno = 0;
3518 if (cfg->lsunit)
8d1bff2b 3519 align_log_size(cfg, cfg->lsunit, XFS_MAX_LOG_BLOCKS);
e3bc8390
DC
3520
3521 validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
3522 return;
3523 }
3524
aba6743c
DW
3525 /*
3526 * Make sure the log fits wholly within an AG
3527 *
3528 * XXX: If agf->freeblks ends up as 0 because the log uses all
3529 * the free space, it causes the kernel all sorts of problems
3530 * with per-ag reservations. Right now just back it off one
3531 * block, but there's a whole can of worms here that needs to be
3532 * opened to decide what is the valid maximum size of a log in
3533 * an AG.
3534 */
3535 max_logblocks = libxfs_alloc_ag_max_usable(mp) - 1;
db5b8665
DW
3536 if (max_logblocks < min_logblocks) {
3537 fprintf(stderr,
3538_("max log size %d smaller than min log size %d, filesystem is too small\n"),
3539 max_logblocks,
3540 min_logblocks);
3541 usage();
3542 }
aba6743c 3543
e3bc8390
DC
3544 /* internal log - if no size specified, calculate automatically */
3545 if (!cfg->logblocks) {
cdfa467e
ES
3546 /* Use a 2048:1 fs:log ratio for most filesystems */
3547 cfg->logblocks = (cfg->dblocks << cfg->blocklog) / 2048;
3548 cfg->logblocks = cfg->logblocks >> cfg->blocklog;
e3bc8390 3549
cdfa467e
ES
3550 /* But don't go below a reasonable size */
3551 cfg->logblocks = max(cfg->logblocks,
3552 XFS_MIN_REALISTIC_LOG_BLOCKS(cfg->blocklog));
3553
3554 /* And for a tiny filesystem, use the absolute minimum size */
3555 if (cfg->dblocks < MEGABYTES(300, cfg->blocklog))
3556 cfg->logblocks = min_logblocks;
e3bc8390 3557
aba6743c 3558 /* Ensure the chosen size fits within log size requirements */
68d16907 3559 cfg->logblocks = max(min_logblocks, cfg->logblocks);
aba6743c 3560 cfg->logblocks = min(cfg->logblocks, max_logblocks);
e3bc8390
DC
3561
3562 /* and now clamp the size to the maximum supported size */
68d16907 3563 cfg->logblocks = min(cfg->logblocks, XFS_MAX_LOG_BLOCKS);
e3bc8390
DC
3564 if ((cfg->logblocks << cfg->blocklog) > XFS_MAX_LOG_BYTES)
3565 cfg->logblocks = XFS_MAX_LOG_BYTES >> cfg->blocklog;
3566
3567 validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
aba6743c
DW
3568 } else if (cfg->logblocks > max_logblocks) {
3569 /* check specified log size */
3570 fprintf(stderr,
3571_("internal log size %lld too large, must be less than %d\n"),
3572 (long long)cfg->logblocks,
3573 max_logblocks);
3574 usage();
e3bc8390
DC
3575 }
3576
3577 if (cfg->logblocks > sbp->sb_agblocks - libxfs_prealloc_blocks(mp)) {
3578 fprintf(stderr,
3579_("internal log size %lld too large, must fit in allocation group\n"),
3580 (long long)cfg->logblocks);
3581 usage();
3582 }
3583
3584 if (cli_opt_set(&lopts, L_AGNUM)) {
3585 if (cli->logagno >= sbp->sb_agcount) {
3586 fprintf(stderr,
3587_("log ag number %lld too large, must be less than %lld\n"),
3588 (long long)cli->logagno,
3589 (long long)sbp->sb_agcount);
3590 usage();
3591 }
3592 cfg->logagno = cli->logagno;
3593 } else
3594 cfg->logagno = (xfs_agnumber_t)(sbp->sb_agcount / 2);
3595
1b580a77
DW
3596 if (cfg->logagno == 0)
3597 adjust_ag0_internal_logblocks(cfg, mp, min_logblocks,
3598 &max_logblocks);
3599
e3bc8390
DC
3600 cfg->logstart = XFS_AGB_TO_FSB(mp, cfg->logagno,
3601 libxfs_prealloc_blocks(mp));
3602
3603 /*
3604 * Align the logstart at stripe unit boundary.
3605 */
3606 if (cfg->lsunit) {
8d1bff2b 3607 align_internal_log(cfg, mp, cfg->lsunit, max_logblocks);
e3bc8390 3608 } else if (cfg->dsunit) {
8d1bff2b 3609 align_internal_log(cfg, mp, cfg->dsunit, max_logblocks);
e3bc8390
DC
3610 }
3611 validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
3612}
3613
befcd768 3614/*
a6fb6abe 3615 * Set up superblock with the minimum parameters required for
befcd768 3616 * the libxfs macros needed by the log sizing code to run successfully.
a6fb6abe
DC
3617 * This includes a minimum log size calculation, so we need everything
3618 * that goes into that calculation to be setup here including feature
3619 * flags.
befcd768
DC
3620 */
3621static void
a6fb6abe 3622start_superblock_setup(
befcd768
DC
3623 struct mkfs_params *cfg,
3624 struct xfs_mount *mp,
3625 struct xfs_sb *sbp)
3626{
a6fb6abe
DC
3627 sbp->sb_magicnum = XFS_SB_MAGIC;
3628 sbp->sb_sectsize = (uint16_t)cfg->sectorsize;
befcd768 3629 sbp->sb_sectlog = (uint8_t)cfg->sectorlog;
a6fb6abe
DC
3630 sbp->sb_blocksize = cfg->blocksize;
3631 sbp->sb_blocklog = (uint8_t)cfg->blocklog;
3632
befcd768 3633 sbp->sb_agblocks = (xfs_agblock_t)cfg->agsize;
a6fb6abe 3634 sbp->sb_agblklog = (uint8_t)log2_roundup(cfg->agsize);
befcd768 3635 sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
93a199f2 3636 sbp->sb_dblocks = (xfs_rfsblock_t)cfg->dblocks;
a6fb6abe
DC
3637
3638 sbp->sb_inodesize = (uint16_t)cfg->inodesize;
3639 sbp->sb_inodelog = (uint8_t)cfg->inodelog;
3640 sbp->sb_inopblock = (uint16_t)(cfg->blocksize / cfg->inodesize);
3641 sbp->sb_inopblog = (uint8_t)(cfg->blocklog - cfg->inodelog);
3642
3643 sbp->sb_dirblklog = cfg->dirblocklog - cfg->blocklog;
3644
3645 sb_set_features(cfg, sbp);
befcd768
DC
3646
3647 /*
a6fb6abe
DC
3648 * log stripe unit is stored in bytes on disk and cannot be zero
3649 * for v2 logs.
befcd768 3650 */
a6fb6abe
DC
3651 if (cfg->sb_feat.log_version == 2) {
3652 if (cfg->lsunit)
3653 sbp->sb_logsunit = XFS_FSB_TO_B(mp, cfg->lsunit);
3654 else
3655 sbp->sb_logsunit = 1;
3656 } else
3657 sbp->sb_logsunit = 0;
3658
31409f48
DW
3659 /* log reservation calculations depend on rt geometry */
3660 sbp->sb_rblocks = cfg->rtblocks;
3661 sbp->sb_rextsize = cfg->rtextblocks;
3bc1fdd4 3662 mp->m_features |= libxfs_sb_version_to_features(sbp);
a6fb6abe
DC
3663}
3664
3665static void
3666initialise_mount(
a6fb6abe
DC
3667 struct xfs_mount *mp,
3668 struct xfs_sb *sbp)
3669{
3670 /* Minimum needed for libxfs_prealloc_blocks() */
3671 mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
3672 mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
befcd768
DC
3673}
3674
afda75a5
DC
3675/*
3676 * Format everything from the generated config into the superblock that
3677 * will be used to initialise the on-disk superblock. This is the in-memory
3678 * copy, so no need to care about endian swapping here.
3679 */
3680static void
a6fb6abe 3681finish_superblock_setup(
afda75a5
DC
3682 struct mkfs_params *cfg,
3683 struct xfs_mount *mp,
3684 struct xfs_sb *sbp)
3685{
7f0d0b55
DW
3686 if (cfg->label) {
3687 size_t label_len;
3688
3689 /*
3690 * Labels are null terminated unless the string fits exactly
3691 * in the label field, so assume sb_fname is zeroed and then
3692 * do a memcpy because the destination isn't a normal C string.
3693 */
3694 label_len = min(sizeof(sbp->sb_fname), strlen(cfg->label));
3695 memcpy(sbp->sb_fname, cfg->label, label_len);
3696 }
afda75a5 3697
afda75a5 3698 sbp->sb_dblocks = cfg->dblocks;
afda75a5
DC
3699 sbp->sb_rextents = cfg->rtextents;
3700 platform_uuid_copy(&sbp->sb_uuid, &cfg->uuid);
3701 /* Only in memory; libxfs expects this as if read from disk */
3702 platform_uuid_copy(&sbp->sb_meta_uuid, &cfg->uuid);
3703 sbp->sb_logstart = cfg->logstart;
3704 sbp->sb_rootino = sbp->sb_rbmino = sbp->sb_rsumino = NULLFSINO;
afda75a5
DC
3705 sbp->sb_agcount = (xfs_agnumber_t)cfg->agcount;
3706 sbp->sb_rbmblocks = cfg->rtbmblocks;
3707 sbp->sb_logblocks = (xfs_extlen_t)cfg->logblocks;
afda75a5
DC
3708 sbp->sb_rextslog = (uint8_t)(cfg->rtextents ?
3709 libxfs_highbit32((unsigned int)cfg->rtextents) : 0);
3710 sbp->sb_inprogress = 1; /* mkfs is in progress */
3711 sbp->sb_imax_pct = cfg->imaxpct;
3712 sbp->sb_icount = 0;
3713 sbp->sb_ifree = 0;
3714 sbp->sb_fdblocks = cfg->dblocks -
3715 cfg->agcount * libxfs_prealloc_blocks(mp) -
3716 (cfg->loginternal ? cfg->logblocks : 0);
3717 sbp->sb_frextents = 0; /* will do a free later */
3718 sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0;
3719 sbp->sb_qflags = 0;
3720 sbp->sb_unit = cfg->dsunit;
3721 sbp->sb_width = cfg->dswidth;
3bc1fdd4 3722 mp->m_features |= libxfs_sb_version_to_features(sbp);
afda75a5 3723
afda75a5
DC
3724}
3725
09468119
DW
3726/* Prepare an uncached buffer, ready to write something out. */
3727static inline struct xfs_buf *
3728alloc_write_buf(
3729 struct xfs_buftarg *btp,
3730 xfs_daddr_t daddr,
3731 int bblen)
3732{
3733 struct xfs_buf *bp;
d918bc57 3734 int error;
09468119 3735
d918bc57
DW
3736 error = -libxfs_buf_get_uncached(btp, bblen, 0, &bp);
3737 if (error) {
3738 fprintf(stderr, _("Could not get memory for buffer, err=%d\n"),
3739 error);
3740 exit(1);
3741 }
a25314af
DW
3742
3743 xfs_buf_set_daddr(bp, daddr);
09468119
DW
3744 return bp;
3745}
3746
e99bf83d
DC
3747/*
3748 * Sanitise the data and log devices and prepare them so libxfs can mount the
3749 * device successfully. Also check we can access the rt device if configured.
3750 */
3751static void
3752prepare_devices(
3753 struct mkfs_params *cfg,
01dcfd9e 3754 struct libxfs_init *xi,
e99bf83d
DC
3755 struct xfs_mount *mp,
3756 struct xfs_sb *sbp,
3757 bool clear_stale)
3758{
3759 struct xfs_buf *buf;
3760 int whack_blks = BTOBB(WHACK_SIZE);
3761 int lsunit;
3762
3763 /*
3764 * If there's an old XFS filesystem on the device with enough intact
3765 * information that we can parse the superblock, there's enough
3766 * information on disk to confuse a future xfs_repair call. To avoid
3767 * this, whack all the old secondary superblocks that we can find.
3768 */
3769 if (clear_stale)
3770 zero_old_xfs_structures(xi, sbp);
3771
3772 /*
3773 * If the data device is a file, grow out the file to its final size if
3774 * needed so that the reads for the end of the device in the mount code
3775 * will succeed.
3776 */
3777 if (xi->disfile &&
3778 xi->dsize * xi->dbsize < cfg->dblocks * cfg->blocksize) {
3779 if (ftruncate(xi->dfd, cfg->dblocks * cfg->blocksize) < 0) {
3780 fprintf(stderr,
3781 _("%s: Growing the data section failed\n"),
3782 progname);
3783 exit(1);
3784 }
3785
3786 /* update size to be able to whack blocks correctly */
3787 xi->dsize = BTOBB(cfg->dblocks * cfg->blocksize);
3788 }
3789
3790 /*
3791 * Zero out the end to obliterate any old MD RAID (or other) metadata at
3792 * the end of the device. (MD sb is ~64k from the end, take out a wider
3793 * swath to be sure)
3794 */
09468119
DW
3795 buf = alloc_write_buf(mp->m_ddev_targp, (xi->dsize - whack_blks),
3796 whack_blks);
04338619 3797 memset(buf->b_addr, 0, WHACK_SIZE);
f524ae04 3798 libxfs_buf_mark_dirty(buf);
18b4f688 3799 libxfs_buf_relse(buf);
e99bf83d
DC
3800
3801 /*
3802 * Now zero out the beginning of the device, to obliterate any old
3803 * filesystem signatures out there. This should take care of
3804 * swap (somewhere around the page size), jfs (32k),
3805 * ext[2,3] and reiserfs (64k) - and hopefully all else.
3806 */
09468119 3807 buf = alloc_write_buf(mp->m_ddev_targp, 0, whack_blks);
04338619 3808 memset(buf->b_addr, 0, WHACK_SIZE);
f524ae04 3809 libxfs_buf_mark_dirty(buf);
18b4f688 3810 libxfs_buf_relse(buf);
e99bf83d
DC
3811
3812 /* OK, now write the superblock... */
09468119 3813 buf = alloc_write_buf(mp->m_ddev_targp, XFS_SB_DADDR,
8b4de37c 3814 XFS_FSS_TO_BB(mp, 1));
e99bf83d 3815 buf->b_ops = &xfs_sb_buf_ops;
04338619
CM
3816 memset(buf->b_addr, 0, cfg->sectorsize);
3817 libxfs_sb_to_disk(buf->b_addr, sbp);
f524ae04 3818 libxfs_buf_mark_dirty(buf);
18b4f688 3819 libxfs_buf_relse(buf);
e99bf83d
DC
3820
3821 /* ...and zero the log.... */
3822 lsunit = sbp->sb_logsunit;
3823 if (lsunit == 1)
3824 lsunit = sbp->sb_logsectsize;
3825
3826 libxfs_log_clear(mp->m_logdev_targp, NULL,
3827 XFS_FSB_TO_DADDR(mp, cfg->logstart),
3828 (xfs_extlen_t)XFS_FSB_TO_BB(mp, cfg->logblocks),
3829 &sbp->sb_uuid, cfg->sb_feat.log_version,
3830 lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
3831
3832 /* finally, check we can write the last block in the realtime area */
ab434d12 3833 if (mp->m_rtdev_targp->bt_bdev && cfg->rtblocks > 0) {
09468119
DW
3834 buf = alloc_write_buf(mp->m_rtdev_targp,
3835 XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
3836 BTOBB(cfg->blocksize));
04338619 3837 memset(buf->b_addr, 0, cfg->blocksize);
f524ae04 3838 libxfs_buf_mark_dirty(buf);
18b4f688 3839 libxfs_buf_relse(buf);
e99bf83d
DC
3840 }
3841
3842}
3843
0ff1b0ed
DC
3844static void
3845initialise_ag_headers(
3846 struct mkfs_params *cfg,
3847 struct xfs_mount *mp,
0ff1b0ed 3848 xfs_agnumber_t agno,
7b754805
DW
3849 int *worst_freelist,
3850 struct list_head *buffer_list)
0ff1b0ed 3851{
7b754805
DW
3852 struct aghdr_init_data id = {
3853 .agno = agno,
3854 .agsize = cfg->agsize,
3855 };
0ff1b0ed 3856 struct xfs_perag *pag = libxfs_perag_get(mp, agno);
7b754805 3857 int error;
0ff1b0ed 3858
0ff1b0ed 3859 if (agno == cfg->agcount - 1)
7b754805 3860 id.agsize = cfg->dblocks - (xfs_rfsblock_t)(agno * cfg->agsize);
0ff1b0ed 3861
7b754805
DW
3862 INIT_LIST_HEAD(&id.buffer_list);
3863 error = -libxfs_ag_init_headers(mp, &id);
3864 if (error) {
3865 fprintf(stderr, _("AG header init failed, error %d\n"), error);
3866 exit(1);
0ff1b0ed
DC
3867 }
3868
7b754805 3869 list_splice_tail_init(&id.buffer_list, buffer_list);
0ff1b0ed 3870
0ff1b0ed
DC
3871 if (libxfs_alloc_min_freelist(mp, pag) > *worst_freelist)
3872 *worst_freelist = libxfs_alloc_min_freelist(mp, pag);
0ff1b0ed
DC
3873 libxfs_perag_put(pag);
3874}
3875
3876static void
3877initialise_ag_freespace(
3878 struct xfs_mount *mp,
3879 xfs_agnumber_t agno,
3880 int worst_freelist)
3881{
3882 struct xfs_alloc_arg args;
3883 struct xfs_trans *tp;
0ff1b0ed
DC
3884 int c;
3885
225e4bb2 3886 c = -libxfs_trans_alloc_rollable(mp, worst_freelist, &tp);
0ff1b0ed
DC
3887 if (c)
3888 res_failed(c);
3889
3890 memset(&args, 0, sizeof(args));
3891 args.tp = tp;
3892 args.mp = mp;
3893 args.agno = agno;
3894 args.alignment = 1;
3895 args.pag = libxfs_perag_get(mp, agno);
3896
3897 libxfs_alloc_fix_freelist(&args, 0);
3898 libxfs_perag_put(args.pag);
f2279d8d 3899 c = -libxfs_trans_commit(tp);
5770b2f0
DW
3900 if (c) {
3901 errno = c;
3902 perror(_("initializing AG free space list"));
3903 exit(1);
3904 }
0ff1b0ed
DC
3905}
3906
e2847e5c
DC
3907/*
3908 * rewrite several secondary superblocks with the root inode number filled out.
3909 * This can help repair recovery from a trashed primary superblock without
3910 * losing the root inode.
3911 */
3912static void
3913rewrite_secondary_superblocks(
3914 struct xfs_mount *mp)
3915{
3916 struct xfs_buf *buf;
d6522f1d 3917 struct xfs_dsb *dsb;
31079e67 3918 int error;
e2847e5c
DC
3919
3920 /* rewrite the last superblock */
31079e67 3921 error = -libxfs_buf_read(mp->m_dev,
e2847e5c
DC
3922 XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount - 1,
3923 XFS_SB_DADDR),
31079e67
DW
3924 XFS_FSS_TO_BB(mp, 1), 0, &buf, &xfs_sb_buf_ops);
3925 if (error) {
d855bce8
DW
3926 fprintf(stderr, _("%s: could not re-read AG %u superblock\n"),
3927 progname, mp->m_sb.sb_agcount - 1);
3928 exit(1);
3929 }
d6522f1d
CH
3930 dsb = buf->b_addr;
3931 dsb->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
f524ae04 3932 libxfs_buf_mark_dirty(buf);
18b4f688 3933 libxfs_buf_relse(buf);
e2847e5c
DC
3934
3935 /* and one in the middle for luck if there's enough AGs for that */
3936 if (mp->m_sb.sb_agcount <= 2)
3937 return;
3938
31079e67 3939 error = -libxfs_buf_read(mp->m_dev,
e2847e5c
DC
3940 XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount - 1) / 2,
3941 XFS_SB_DADDR),
31079e67
DW
3942 XFS_FSS_TO_BB(mp, 1), 0, &buf, &xfs_sb_buf_ops);
3943 if (error) {
d855bce8
DW
3944 fprintf(stderr, _("%s: could not re-read AG %u superblock\n"),
3945 progname, (mp->m_sb.sb_agcount - 1) / 2);
3946 exit(1);
3947 }
d6522f1d
CH
3948 dsb = buf->b_addr;
3949 dsb->sb_rootino = cpu_to_be64(mp->m_sb.sb_rootino);
f524ae04 3950 libxfs_buf_mark_dirty(buf);
18b4f688 3951 libxfs_buf_relse(buf);
e2847e5c
DC
3952}
3953
659a4358
DW
3954static void
3955check_root_ino(
3956 struct xfs_mount *mp)
3957{
3958 xfs_ino_t ino;
3959
3960 if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
3961 fprintf(stderr,
3962 _("%s: root inode created in AG %u, not AG 0\n"),
3963 progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
3964 exit(1);
3965 }
3966
3967 /*
3968 * The superblock points to the root directory inode, but xfs_repair
3969 * expects to find the root inode in a very specific location computed
3970 * from the filesystem geometry for an extra level of verification.
3971 *
3972 * Fail the format immediately if those assumptions ever break, because
3973 * repair will toss the root directory.
3974 */
3975 ino = libxfs_ialloc_calc_rootino(mp, mp->m_sb.sb_unit);
3976 if (mp->m_sb.sb_rootino != ino) {
3977 fprintf(stderr,
3978 _("%s: root inode (%llu) not allocated in expected location (%llu)\n"),
3979 progname,
3980 (unsigned long long)mp->m_sb.sb_rootino,
3981 (unsigned long long)ino);
3982 exit(1);
3983 }
3984}
3985
33c62516
DC
3986/*
3987 * INI file format option parser.
3988 *
3989 * This is called by the file parser library for every valid option it finds in
3990 * the config file. The option is already broken down into a
3991 * {section,name,value} tuple, so all we need to do is feed it to the correct
3992 * suboption parser function and translate the return value.
3993 *
3994 * Returns 0 on failure, 1 for success.
3995 */
3996static int
3997cfgfile_parse_ini(
3998 void *user,
3999 const char *section,
4000 const char *name,
4001 const char *value)
4002{
4003 struct cli_params *cli = user;
4004
ab2eef12
DC
4005 if (!parse_cfgopt(section, name, value, cli))
4006 return 0;
33c62516
DC
4007 return 1;
4008}
4009
b6fef47a 4010static void
33c62516
DC
4011cfgfile_parse(
4012 struct cli_params *cli)
4013{
4014 int error;
4015
4016 if (!cli->cfgfile)
4017 return;
4018
4019 error = ini_parse(cli->cfgfile, cfgfile_parse_ini, cli);
4020 if (error) {
4021 if (error > 0) {
4022 fprintf(stderr,
4023 _("%s: Unrecognised input on line %d. Aborting.\n"),
4024 cli->cfgfile, error);
4025 } else if (error == -1) {
4026 fprintf(stderr,
4027 _("Unable to open config file %s. Aborting.\n"),
4028 cli->cfgfile);
4029 } else if (error == -2) {
4030 fprintf(stderr,
4031 _("Memory allocation failure parsing %s. Aborting.\n"),
4032 cli->cfgfile);
4033 } else {
4034 fprintf(stderr,
4035 _("Unknown error %d opening config file %s. Aborting.\n"),
4036 error, cli->cfgfile);
4037 }
4038 exit(1);
4039 }
4040 printf(_("Parameters parsed from config file %s successfully\n"),
4041 cli->cfgfile);
4042}
4043
2bd0ea18 4044int
9440d84d
NS
4045main(
4046 int argc,
4047 char **argv)
2bd0ea18 4048{
2bd0ea18 4049 xfs_agnumber_t agno;
167137fe 4050 struct xfs_buf *buf;
2bd0ea18 4051 int c;
fdea8fbc 4052 int dry_run = 0;
ad136b33 4053 int discard = 1;
b449c79e 4054 int force_overwrite = 0;
fdea8fbc 4055 int quiet = 0;
b449c79e
DC
4056 char *protostring = NULL;
4057 int worst_freelist = 0;
4058
01dcfd9e 4059 struct libxfs_init xi = {
b449c79e
DC
4060 .isdirect = LIBXFS_DIRECT,
4061 .isreadonly = LIBXFS_EXCLUSIVELY,
4062 };
befcd768
DC
4063 struct xfs_mount mbuf = {};
4064 struct xfs_mount *mp = &mbuf;
4065 struct xfs_sb *sbp = &mp->m_sb;
d6522f1d 4066 struct xfs_dsb *dsb;
b449c79e
DC
4067 struct fs_topology ft = {};
4068 struct cli_params cli = {
4069 .xi = &xi,
4070 .loginternal = 1,
6e0ed3d1 4071 .is_supported = 1,
b449c79e
DC
4072 };
4073 struct mkfs_params cfg = {};
4074
6e0ed3d1
DW
4075 struct option long_options[] = {
4076 {
4077 .name = "unsupported",
4078 .has_arg = no_argument,
4079 .flag = &cli.is_supported,
4080 .val = 0,
4081 },
4082 {NULL, 0, NULL, 0 },
4083 };
4084 int option_index = 0;
4085
68344ba0
DC
4086 /* build time defaults */
4087 struct mkfs_default_params dft = {
b729d144 4088 .source = _("package build definitions"),
68344ba0
DC
4089 .sectorsize = XFS_MIN_SECTORSIZE,
4090 .blocksize = 1 << XFS_DFL_BLOCKSIZE_LOG,
4091 .sb_feat = {
4092 .log_version = 2,
4093 .attr_version = 2,
129d98a9
ES
4094 .dir_version = 2,
4095 .inode_align = true,
68344ba0
DC
4096 .nci = false,
4097 .lazy_sb_counters = true,
639d0b0b 4098 .projid32bit = true,
68344ba0
DC
4099 .crcs_enabled = true,
4100 .dirftype = true,
4101 .finobt = true,
9cf846b5 4102 .spinodes = true,
bcd5b1b7 4103 .rmapbt = true,
ec1b42e6 4104 .reflink = true,
1c08f0ae 4105 .inobtcnt = true,
68344ba0
DC
4106 .parent_pointers = false,
4107 .nodalign = false,
4108 .nortalign = false,
1c08f0ae 4109 .bigtime = true,
e5b18d7d 4110 .nrext64 = true,
fbdda8fa
DW
4111 /*
4112 * When we decide to enable a new feature by default,
4113 * please remember to update the mkfs conf files.
4114 */
68344ba0 4115 },
5f1a2100 4116 };
2bd0ea18 4117
7b754805 4118 struct list_head buffer_list;
d73b61f9 4119 int error;
7b754805 4120
a43e656b 4121 platform_uuid_generate(&cli.uuid);
2bd0ea18 4122 progname = basename(argv[0]);
9440d84d
NS
4123 setlocale(LC_ALL, "");
4124 bindtextdomain(PACKAGE, LOCALEDIR);
4125 textdomain(PACKAGE);
4126
68344ba0
DC
4127 /*
4128 * TODO: Sourcing defaults from a config file
4129 *
4130 * Before anything else, see if there's a config file with different
4131 * defaults. If a file exists in <package location>, read in the new
4132 * default values and overwrite them in the &dft structure. This way the
4133 * new defaults will apply before we parse the CLI, and the CLI will
b729d144
ES
4134 * still be able to override them. When more than one source is
4135 * implemented, emit a message to indicate where the defaults being
4136 * used came from.
4137 *
4138 * printf(_("Default configuration sourced from %s\n"), dft.source);
68344ba0 4139 */
68344ba0
DC
4140
4141 /* copy new defaults into CLI parsing structure */
4142 memcpy(&cli.sb_feat, &dft.sb_feat, sizeof(cli.sb_feat));
4143 memcpy(&cli.fsx, &dft.fsx, sizeof(cli.fsx));
4144
6e0ed3d1
DW
4145 while ((c = getopt_long(argc, argv, "b:c:d:i:l:L:m:n:KNp:qr:s:CfV",
4146 long_options, &option_index)) != EOF) {
2bd0ea18 4147 switch (c) {
6e0ed3d1
DW
4148 case 0:
4149 break;
2bd0ea18 4150 case 'C':
2bd0ea18 4151 case 'f':
f937adac 4152 force_overwrite = 1;
2bd0ea18
NS
4153 break;
4154 case 'b':
33c62516 4155 case 'c':
b449c79e 4156 case 'd':
d7240c96 4157 case 'i':
e3bc8390 4158 case 'l':
b449c79e 4159 case 'm':
fdea8fbc 4160 case 'n':
fb22e1b1 4161 case 'p':
7a9af89a 4162 case 'r':
22319b56 4163 case 's':
85d6f03d 4164 parse_subopts(c, optarg, &cli);
2bd0ea18 4165 break;
979f7189
NS
4166 case 'L':
4167 if (strlen(optarg) > sizeof(sbp->sb_fname))
4168 illegal(optarg, "L");
b449c79e 4169 cfg.label = optarg;
f7b80291 4170 break;
33a12367 4171 case 'N':
ebed4acf 4172 dry_run = 1;
33a12367 4173 break;
ad136b33
CH
4174 case 'K':
4175 discard = 0;
4176 break;
2bd0ea18 4177 case 'q':
ebed4acf 4178 quiet = 1;
2bd0ea18 4179 break;
2bd0ea18 4180 case 'V':
9440d84d 4181 printf(_("%s version %s\n"), progname, VERSION);
3d98fe63 4182 exit(0);
78aeaffd 4183 default:
2bd0ea18
NS
4184 unknown(optopt, "");
4185 }
4186 }
4187 if (argc - optind > 1) {
9440d84d 4188 fprintf(stderr, _("extra arguments\n"));
2bd0ea18
NS
4189 usage();
4190 } else if (argc - optind == 1) {
732f5b90
CH
4191 xi.dname = getstr(argv[optind], &dopts, D_NAME);
4192 }
9440d84d 4193
33c62516
DC
4194 /*
4195 * Now we have all the options parsed, we can read in the option file
4196 * specified on the command line via "-c options=xxx". Once we have all
4197 * the options from this file parsed, we can then proceed with parameter
4198 * and bounds checking and making the filesystem.
4199 */
4200 cfgfile_parse(&cli);
4201
fb22e1b1 4202 protostring = setup_proto(cli.protofile);
a3ac5af1 4203
06ac92fd 4204 /*
585f41bb
DC
4205 * Extract as much of the valid config as we can from the CLI input
4206 * before opening the libxfs devices.
06ac92fd 4207 */
b1b8e54e 4208 validate_blocksize(&cfg, &cli, &dft);
732f5b90 4209 validate_sectorsize(&cfg, &cli, &dft, &ft, dry_run, force_overwrite);
b449c79e
DC
4210
4211 /*
4212 * XXX: we still need to set block size and sector size global variables
4213 * so that getnum/cvtnum works correctly
4214 */
4215 blocksize = cfg.blocksize;
4216 sectorsize = cfg.sectorsize;
4217
22319b56 4218 validate_log_sectorsize(&cfg, &cli, &dft);
a43e656b 4219 validate_sb_features(&cfg, &cli);
fd5eda53 4220
fdea8fbc
DC
4221 /*
4222 * we've now completed basic validation of the features, sector and
4223 * block sizes, so from this point onwards we use the values found in
4224 * the cfg structure for them, not the command line structure.
4225 */
4226 validate_dirblocksize(&cfg, &cli);
8fe29028 4227 validate_inodesize(&cfg, &cli);
fdea8fbc 4228
e24dfa22
DC
4229 /*
4230 * if the device size was specified convert it to a block count
4231 * now we have a valid block size. These will be set to zero if
4232 * nothing was specified, indicating we should use the full device.
4233 */
4234 cfg.dblocks = calc_dev_size(cli.dsize, &cfg, &dopts, D_SIZE, "data");
4235 cfg.logblocks = calc_dev_size(cli.logsize, &cfg, &lopts, L_SIZE, "log");
4236 cfg.rtblocks = calc_dev_size(cli.rtsize, &cfg, &ropts, R_SIZE, "rt");
4237
80b154f7
DC
4238 validate_rtextsize(&cfg, &cli, &ft);
4239
379f01d2
DC
4240 /*
4241 * Open and validate the device configurations
4242 */
915a27a0 4243 open_devices(&cfg, &xi);
732f5b90 4244 validate_overwrite(xi.dname, force_overwrite);
dd5ac314 4245 validate_datadev(&cfg, &cli);
732f5b90
CH
4246 validate_logdev(&cfg, &cli);
4247 validate_rtdev(&cfg, &cli);
59cf9679 4248 calc_stripe_factors(&cfg, &cli, &ft);
379f01d2 4249
1de01446
DC
4250 /*
4251 * At this point when know exactly what size all the devices are,
4252 * so we can start validating and calculating layout options that are
4253 * dependent on device sizes. Once calculated, make sure everything
4254 * aligns to device geometry correctly.
4255 */
4256 calculate_initial_ag_geometry(&cfg, &cli);
051b4e37 4257 align_ag_geometry(&cfg);
1de01446 4258
d7240c96
DC
4259 calculate_imaxpct(&cfg, &cli);
4260
befcd768
DC
4261 /*
4262 * Set up the basic superblock parameters now so that we can use
4263 * the geometry information we've already validated in libxfs
4264 * provided functions to determine on-disk format information.
4265 */
a6fb6abe 4266 start_superblock_setup(&cfg, mp, sbp);
a4170b73 4267 initialise_mount(mp, sbp);
befcd768 4268
e3bc8390
DC
4269 /*
4270 * With the mount set up, we can finally calculate the log size
4271 * constraints and do default size calculations and final validation
4272 */
4273 calculate_log_size(&cfg, &cli, mp);
4274
ebc2e798
DW
4275 finish_superblock_setup(&cfg, mp, sbp);
4276
9cfe71ba
DW
4277 /* Validate the extent size hints now that @mp is fully set up. */
4278 validate_extsize_hint(mp, &cli);
4279 validate_cowextsize_hint(mp, &cli);
4280
6e0ed3d1
DW
4281 validate_supported(mp, &cli);
4282
ebc2e798 4283 /* Print the intended geometry of the fs. */
ebed4acf 4284 if (!quiet || dry_run) {
ebc2e798 4285 struct xfs_fsop_geom geo;
ebc2e798 4286
fa25ff74 4287 libxfs_fs_geometry(mp, &geo, XFS_FS_GEOM_MAX_STRUCT_VER);
732f5b90 4288 xfs_report_geom(&geo, xi.dname, xi.logname, xi.rtname);
ebed4acf 4289 if (dry_run)
9440d84d
NS
4290 exit(0);
4291 }
6003fd81 4292
ca14a570
DW
4293 /* Make sure our checksum algorithm really works. */
4294 if (crc32c_test(CRC32CTEST_QUIET) != 0) {
4295 fprintf(stderr,
4296 _("crc32c self-test failed, will not create a filesystem here.\n"));
4297 return 1;
4298 }
4299
b9d29568
DW
4300 /* Make sure our dir/attr hash algorithm really works. */
4301 if (dahash_test(DAHASHTEST_QUIET) != 0) {
4302 fprintf(stderr,
4303 _("xfs dir/attr self-test failed, will not create a filesystem here.\n"));
4304 return 1;
4305 }
4306
915a27a0
JT
4307 /*
4308 * All values have been validated, discard the old device layout.
4309 */
4310 if (discard && !dry_run)
7e8a6edb 4311 discard_devices(&xi, quiet);
915a27a0 4312
2f012bf9 4313 /*
e99bf83d 4314 * we need the libxfs buffer cache from here on in.
2f012bf9 4315 */
ca8cc76e 4316 libxfs_buftarg_init(mp, &xi);
2bd0ea18 4317
2bd0ea18 4318 /*
e99bf83d
DC
4319 * Before we mount the filesystem we need to make sure the devices have
4320 * enough of the filesystem structure on them that allows libxfs to
4321 * mount.
2bd0ea18 4322 */
e99bf83d 4323 prepare_devices(&cfg, &xi, mp, sbp, force_overwrite);
ddd9942b 4324 mp = libxfs_mount(mp, sbp, &xi, 0);
02e85e7f 4325 if (mp == NULL) {
9440d84d
NS
4326 fprintf(stderr, _("%s: filesystem failed to initialize\n"),
4327 progname);
2bd0ea18
NS
4328 exit(1);
4329 }
2bd0ea18 4330
75c8b434 4331 /*
0ff1b0ed 4332 * Initialise all the static on disk metadata.
75c8b434 4333 */
7b754805
DW
4334 INIT_LIST_HEAD(&buffer_list);
4335 for (agno = 0; agno < cfg.agcount; agno++) {
a4170b73 4336 initialise_ag_headers(&cfg, mp, agno, &worst_freelist,
7b754805
DW
4337 &buffer_list);
4338
4339 if (agno % 16)
4340 continue;
4341
d73b61f9
DW
4342 error = -libxfs_buf_delwri_submit(&buffer_list);
4343 if (error) {
4344 fprintf(stderr,
4345 _("%s: writing AG headers failed, err=%d\n"),
4346 progname, error);
7b754805
DW
4347 exit(1);
4348 }
4349 }
4350
d73b61f9
DW
4351 error = -libxfs_buf_delwri_submit(&buffer_list);
4352 if (error) {
4353 fprintf(stderr, _("%s: writing AG headers failed, err=%d\n"),
4354 progname, error);
7b754805
DW
4355 exit(1);
4356 }
2bd0ea18 4357
2bd0ea18 4358 /*
0ff1b0ed 4359 * Initialise the freespace freelists (i.e. AGFLs) in each AG.
2bd0ea18 4360 */
0ff1b0ed
DC
4361 for (agno = 0; agno < cfg.agcount; agno++)
4362 initialise_ag_freespace(mp, agno, worst_freelist);
9440d84d 4363
2bd0ea18
NS
4364 /*
4365 * Allocate the root inode and anything else in the proto file.
4366 */
e0aeb058 4367 parse_proto(mp, &cli.fsx, &protostring, cli.proto_slashes_are_spaces);
2bd0ea18
NS
4368
4369 /*
9440d84d 4370 * Protect ourselves against possible stupidity
2bd0ea18 4371 */
659a4358 4372 check_root_ino(mp);
2bd0ea18
NS
4373
4374 /*
e2847e5c 4375 * Re-write multiple secondary superblocks with rootinode field set
2bd0ea18 4376 */
e2847e5c
DC
4377 if (mp->m_sb.sb_agcount > 1)
4378 rewrite_secondary_superblocks(mp);
2bd0ea18 4379
f1b058f9
NS
4380 /*
4381 * Dump all inodes and buffers before marking us all done.
4382 * Need to drop references to inodes we still hold, first.
4383 */
4384 libxfs_rtmount_destroy(mp);
f1b058f9
NS
4385 libxfs_bcache_purge();
4386
2bd0ea18
NS
4387 /*
4388 * Mark the filesystem ok.
4389 */
67c4a324
ES
4390 buf = libxfs_getsb(mp);
4391 if (!buf || buf->b_error)
4392 exit(1);
d6522f1d
CH
4393 dsb = buf->b_addr;
4394 dsb->sb_inprogress = 0;
f524ae04 4395 libxfs_buf_mark_dirty(buf);
18b4f688 4396 libxfs_buf_relse(buf);
2bd0ea18 4397
10fc0759
DW
4398 /* Exit w/ failure if anything failed to get written to our new fs. */
4399 error = -libxfs_umount(mp);
4400 if (error)
4401 exit(1);
2bd0ea18 4402
10fc0759 4403 libxfs_destroy(&xi);
2bd0ea18
NS
4404 return 0;
4405}