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