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