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