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