1 #include "clusterautoconfig.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <errno.h>
13 #include <stdarg.h>
14 #include <mntent.h>
15 #include <ctype.h>
16 #include <poll.h>
17 #include <signal.h>
18 #include <libintl.h>
19 #include <sys/ioctl.h>
20 #include <limits.h>
21 #include <blkid.h>
22 #include <locale.h>
23 #include <uuid.h>
24
25 #define _(String) gettext(String)
26
27 #include "libgfs2.h"
28 #include "gfs2_mkfs.h"
29 #include "progress.h"
30 #include "struct_print.h"
31
32 static void print_usage(const char *prog_name)
33 {
34 int i;
35 const char *option, *param, *desc;
36 const char *options[] = {
37 /* Translators: This is a usage string printed with --help.
38 <size> and <number> here are the commandline parameters,
39 e.g. mkfs.gfs2 -b <size> -j <number> /dev/sda */
40 "-b", _("<size>"), _("File system block size, in bytes"),
41 "-c", _("<size>"), _("Size of quota change file, in megabytes"),
42 "-D", NULL, _("Enable debugging code"),
43 "-h", NULL, _("Display this help, then exit"),
44 "-J", _("<size>"), _("Size of journals, in megabytes"),
45 "-j", _("<number>"), _("Number of journals"),
46 "-K", NULL, _("Don't try to discard unused blocks"),
47 "-O", NULL, _("Don't ask for confirmation"),
48 "-o", _("<key>[=<value>][,...]"), _("Specify extended options. See '-o help'."),
49 "-p", _("<name>"), _("Name of the locking protocol"),
50 "-q", NULL, _("Don't print anything"),
51 "-r", _("<size>"), _("Size of resource groups, in megabytes"),
52 "-t", _("<name>"), _("Name of the lock table"),
53 "-U", _("<UUID>"), _("The UUID of the file system"),
54 "-V", NULL, _("Display program version information, then exit"),
55 NULL, NULL, NULL /* Must be kept at the end */
56 };
57
58 printf("%s\n", _("Usage:"));
59 printf("%s [%s] <%s> [%s]\n\n", prog_name, _("options"), _("device"), _("size"));
60 printf(_("Create a gfs2 file system on a device. If a size, in blocks, is not "
61 "specified, the whole device will be used."));
62 printf("\n\n%s\n", _("Options:"));
63
64 for (i = 0; options[i] != NULL; i += 3) {
65 option = options[i];
66 param = options[i + 1];
67 desc = options[i + 2];
68 printf("%3s %-22s %s\n", option, param ? param : "", desc);
69 }
70 }
71
72 static void print_ext_opts(void)
73 {
74 int i;
75 const char *options[] = {
76 "help", _("Display this help, then exit"),
77 "swidth=N", _("Specify the stripe width of the device, overriding probed values"),
78 "sunit=N", _("Specify the stripe unit of the device, overriding probed values"),
79 "align=[0|1]", _("Disable or enable alignment of resource groups"),
80 "format=N", _("Specify the format version number"),
81 NULL, NULL
82 };
83 printf(_("Extended options:\n"));
84 for (i = 0; options[i] != NULL; i += 2) {
85 printf("%15s %-22s\n", options[i], options[i + 1]);
86 }
87 }
88
89 /**
90 * Values probed by libblkid:
91 * alignment_offset: offset, in bytes, of the start of the dev from its natural alignment
92 * logical_sector_size: smallest addressable unit
93 * minimum_io_size: device's preferred unit of I/O. RAID stripe unit.
94 * optimal_io_size: biggest I/O we can submit without incurring a penalty. RAID stripe width.
95 * physical_sector_size: the smallest unit we can write atomically
96 */
97 struct mkfs_dev {
98 int fd;
99 const char *path;
100 struct stat stat;
101 uint64_t size;
102 unsigned long alignment_offset;
103 unsigned long logical_sector_size;
104 unsigned long minimum_io_size;
105 unsigned long optimal_io_size;
106 unsigned long physical_sector_size;
107
108 unsigned int got_topol:1;
109 };
110
111 /* Number of resource groups */
112 static uint64_t nrgrp = 0;
113
114 struct mkfs_opts {
115 unsigned bsize;
116 unsigned qcsize;
117 unsigned jsize;
118 unsigned rgsize;
119 unsigned long sunit;
120 unsigned long swidth;
121 unsigned format;
122 uint64_t fssize;
123 int journals;
124 const char *lockproto;
125 const char *locktable;
126 const char *uuid;
127 struct mkfs_dev dev;
128 unsigned discard:1;
129 unsigned root_inherit_jd:1;
130
131 unsigned got_bsize:1;
132 unsigned got_qcsize:1;
133 unsigned got_jsize:1;
134 unsigned got_rgsize:1;
135 unsigned got_sunit:1;
136 unsigned got_swidth:1;
137 unsigned got_fssize:1;
138 unsigned got_journals:1;
139 unsigned got_lockproto:1;
140 unsigned got_locktable:1;
141 unsigned got_device:1;
142 unsigned got_topol:1;
143 unsigned got_format:1;
144 unsigned got_uuid:1;
145
146 unsigned override:1;
147 unsigned quiet:1;
148 unsigned debug:1;
149 unsigned confirm:1;
150 unsigned align;
151 };
152
153 static void opts_init(struct mkfs_opts *opts)
154 {
155 memset(opts, 0, sizeof(*opts));
156 opts->discard = 1;
157 opts->journals = 1;
158 opts->bsize = LGFS2_DEFAULT_BSIZE;
159 opts->jsize = LGFS2_DEFAULT_JSIZE;
160 opts->qcsize = LGFS2_DEFAULT_QCSIZE;
161 opts->rgsize = LGFS2_DEFAULT_RGSIZE;
162 opts->lockproto = "lock_dlm";
163 opts->locktable = "";
164 opts->confirm = 1;
165 opts->align = 1;
166 opts->format = GFS2_FORMAT_FS;
167 }
168
169 static struct lgfs2_inum *mkfs_journals = NULL;
170
171 #ifndef BLKDISCARD
172 #define BLKDISCARD _IO(0x12,119)
173 #endif
174
175 static int discard_blocks(int fd, uint64_t len, int debug)
176 {
177 uint64_t range[2];
178
179 range[0] = 0;
180 range[1] = len;
181 if (debug)
182 /* Translators: "discard" is a request sent to a storage device to
183 * discard a range of blocks. */
184 printf(_("Issuing discard request: range: %"PRIu64" - %"PRIu64"..."),
185 range[0], range[1]);
186 if (ioctl(fd, BLKDISCARD, &range) < 0) {
187 if (debug)
188 printf("%s = %d\n", _("error"), errno);
189 return errno;
190 }
191 if (debug)
192 printf(_("Successful.\n"));
193 return 0;
194 }
195
196 /**
197 * Convert a human-readable size string to a long long.
198 * Copied and adapted from xfs_mkfs.c.
199 */
200 static long long cvtnum(unsigned int blocksize, unsigned int sectorsize, const char *s)
201 {
202 long long i;
203 char *sp;
204
205 i = strtoll(s, &sp, 0);
206 if (i == 0 && sp == s)
207 return -1LL;
208 if (*sp == '\0')
209 return i;
210
211 *sp = tolower(*sp);
212 if (*sp == 'b' && sp[1] == '\0') {
213 if (blocksize)
214 return i * blocksize;
215 fprintf(stderr, _("Block size not available yet.\n"));
216 return -1LL;
217 }
218 if (*sp == 's' && sp[1] == '\0') {
219 if (sectorsize)
220 return i * sectorsize;
221 return i * GFS2_BASIC_BLOCK;
222 }
223 if (*sp == 'k' && sp[1] == '\0')
224 return 1024LL * i;
225 if (*sp == 'm' && sp[1] == '\0')
226 return 1024LL * 1024LL * i;
227 if (*sp == 'g' && sp[1] == '\0')
228 return 1024LL * 1024LL * 1024LL * i;
229 if (*sp == 't' && sp[1] == '\0')
230 return 1024LL * 1024LL * 1024LL * 1024LL * i;
231 if (*sp == 'p' && sp[1] == '\0')
232 return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
233 if (*sp == 'e' && sp[1] == '\0')
234 return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
235 return -1LL;
236 }
237
238 static int parse_ulong(struct mkfs_opts *opts, const char *key, const char *val, unsigned long *pn,
239 unsigned long max)
240 {
241 long long l;
242 if (val == NULL || *val == '\0') {
243 fprintf(stderr, _("Missing argument to '%s'\n"), key);
244 return -1;
245 }
246 l = cvtnum(opts->bsize, 0, val);
247 if ((max > 0 && l > max) || l < 0) {
248 fprintf(stderr, _("Value of '%s' is invalid\n"), key);
249 return -1;
250 }
251 *pn = (unsigned long)l;
252 return 0;
253 }
254
255 static int parse_bool(struct mkfs_opts *opts, const char *key, const char *val, unsigned *pbool)
256 {
257 if (strnlen(val, 2) == 1) {
258 if (*val == '0') {
259 *pbool = 0;
260 return 0;
261 }
262 if (*val == '1') {
263 *pbool = 1;
264 return 0;
265 }
266 }
267 fprintf(stderr, _("Option '%s' must be either 1 or 0\n"), key);
268 return -1;
269 }
270
271 static int parse_topology(struct mkfs_opts *opts, char *str)
272 {
273 char *opt;
274 unsigned i = 0;
275 unsigned long *topol[5] = {
276 &opts->dev.alignment_offset,
277 &opts->dev.logical_sector_size,
278 &opts->dev.minimum_io_size,
279 &opts->dev.optimal_io_size,
280 &opts->dev.physical_sector_size
281 };
282
283 while ((opt = strsep(&str, ":")) != NULL) {
284 if (i > 4) {
285 fprintf(stderr, "Too many topology values.\n");
286 return 1;
287 }
288 if (parse_ulong(opts, "test_topology", opt, topol[i], 0))
289 return 1;
290 i++;
291 }
292 if (i < 5) {
293 fprintf(stderr, "Too few topology values.\n");
294 return 1;
295 }
296 return 0;
297 }
298
299 static int parse_format(struct mkfs_opts *opts, char *str)
300 {
301 unsigned long ln;
302
303 if (parse_ulong(opts, "format", str, &ln, LGFS2_FS_FORMAT_MAX) != 0)
304 return -1;
305
306 if (ln < LGFS2_FS_FORMAT_MIN) {
307 fprintf(stderr, _("Invalid filesystem format: %s\n"), str);
308 return -1;
309 }
310 opts->format = ln;
311 opts->got_format = 1;
312 return 0;
313 }
314
315 static int parse_root_inherit_jd(struct mkfs_opts *opts, const char *str)
316 {
317 unsigned long n = 0;
318
319 if (str == NULL) { /* -o root_inherit_jdata */
320 opts->root_inherit_jd = 1;
321 return 0;
322 }
323 /* -o root_inherit_jdata=N */
324 if (parse_ulong(opts, "root_inherit_jdata", str, &n, 1) != 0)
325 return -1;
326 opts->root_inherit_jd = (unsigned)n;
327 return 0;
328 }
329
330 static int opt_parse_extended(char *str, struct mkfs_opts *opts)
331 {
332 char *opt;
333 while ((opt = strsep(&str, ",")) != NULL) {
334 char *key = strsep(&opt, "=");
335 char *val = strsep(&opt, "=");
336 if (key == NULL || *key == '\0') {
337 fprintf(stderr, _("Missing argument to '-o' option\n"));
338 return -1;
339 }
340 if (strcmp("sunit", key) == 0) {
341 if (parse_ulong(opts, "sunit", val, &opts->sunit, 0) != 0)
342 return -1;
343 opts->got_sunit = 1;
344 } else if (strcmp("swidth", key) == 0) {
345 if (parse_ulong(opts, "swidth", val, &opts->swidth, 0) != 0)
346 return -1;
347 opts->got_swidth = 1;
348 } else if (strcmp("align", key) == 0) {
349 if (parse_bool(opts, "align", val, &opts->align) != 0)
350 return -1;
351 } else if (strcmp("test_topology", key) == 0) {
352 if (parse_topology(opts, val) != 0)
353 return -1;
354 opts->got_topol = (opts->dev.logical_sector_size != 0 &&
355 opts->dev.physical_sector_size != 0);
356 } else if (strcmp("format", key) == 0) {
357 if (parse_format(opts, val) != 0)
358 return -1;
359 } else if (strcmp("root_inherit_jdata", key) == 0) {
360 if (parse_root_inherit_jd(opts, val) != 0)
361 return -1;
362 } else if (strcmp("help", key) == 0) {
363 print_ext_opts();
364 return 1;
365 } else {
366 fprintf(stderr, _("Invalid extended option (specified with -o): '%s'\n"), key);
367 print_ext_opts();
368 return -1;
369 }
370 }
371 return 0;
372 }
373
374 static int opts_get(int argc, char *argv[], struct mkfs_opts *opts)
375 {
376 int ret;
377 int c;
378 while (1) {
379 c = getopt(argc, argv, "-b:c:DhJ:j:KOo:p:qr:t:U:V");
380 if (c == -1)
381 break;
382
383 switch (c) {
384 case 'b':
385 opts->bsize = atoi(optarg);
386 opts->got_bsize = 1;
387 break;
388 case 'c':
389 opts->qcsize = atoi(optarg);
390 opts->got_qcsize = 1;
391 break;
392 case 'D':
393 opts->debug = 1;
394 break;
395 case 'h':
396 print_usage(argv[0]);
397 return 1;
398 case 'J':
399 opts->jsize = atoi(optarg);
400 opts->got_jsize = 1;
401 break;
402 case 'j':
403 opts->journals = atoi(optarg);
404 opts->got_journals = 1;
405 break;
406 case 'K':
407 opts->discard = 0;
408 break;
409 case 'O':
410 opts->override = 1;
411 break;
412 case 'p':
413 opts->lockproto = optarg;
414 opts->got_lockproto = 1;
415 break;
416 case 't':
417 opts->locktable = optarg;
418 opts->got_locktable = 1;
419 break;
420 case 'q':
421 opts->quiet = 1;
422 break;
423 case 'r':
424 opts->rgsize = atoi(optarg);
425 opts->got_rgsize = 1;
426 break;
427 case 'o':
428 ret = opt_parse_extended(optarg, opts);
429 if (ret != 0)
430 return ret;
431 break;
432 case 'U':
433 opts->uuid = optarg;
434 opts->got_uuid = 1;
435 break;
436 case 'V':
437 printf("mkfs.gfs2 " VERSION "\n");
438 printf(REDHAT_COPYRIGHT "\n");
439 return 1;
440 break;
441 case ':':
442 case '?':
443 fprintf(stderr, _("Please use '-h' for help.\n"));
444 return -1;
445 break;
446 case 1:
447 if (strcmp(optarg, "gfs2") == 0)
448 continue;
449 if (!opts->got_device) {
450 opts->dev.path = optarg;
451 opts->got_device = 1;
452 } else if (!opts->got_fssize && isdigit(optarg[0])) {
453 opts->fssize = atol(optarg);
454 opts->got_fssize = 1;
455 } else {
456 fprintf(stderr, _("More than one device specified (try -h for help)\n"));
457 return -1;
458 }
459 break;
460 default:
461 fprintf(stderr, _("Invalid option: %c\n"), c);
462 return -1;
463 };
464 }
465 return 0;
466 }
467
468 __attribute__((format(printf,3,4)))
469 static void debug_print_ip(struct mkfs_opts *opts, struct lgfs2_inode *ip, const char *fmt, ...)
470 {
471 va_list ap;
472
473 if (!opts->debug)
474 return;
475
476 va_start(ap, fmt);
477 vprintf(fmt, ap);
478 va_end(ap);
479 dinode_print(ip->i_bh->b_data);
480 printf("\n");
481 }
482
483 /**
484 * Make sure the GFS2 is set up to use the right lock protocol
485 * @lockproto: the lock protocol to mount
486 * @locktable: the locktable name
487 *
488 */
489
490 static int test_locking(struct mkfs_opts *opts)
491 {
492 const char *c;
493 /* Translators: A lock table is a string identifying a gfs2 file system
494 * in a cluster, e.g. cluster_name:fs_name */
495 const char *errprefix = _("Invalid lock table:");
496 int table_required = (strcmp(opts->lockproto, "lock_gulm") == 0)
497 || (strcmp(opts->lockproto, "lock_dlm") == 0);
498
499 if ((strcmp(opts->lockproto, "lock_nolock") != 0) && !table_required) {
500 fprintf(stderr, _("Invalid lock protocol: %s\n"), opts->lockproto);
501 return -1;
502 }
503 /* When lock_*lm is given as the lock protocol, require a lock table too */
504 if (!opts->got_locktable) {
505 if (table_required) {
506 fprintf(stderr, _("No lock table specified.\n"));
507 return -1;
508 }
509 return 0;
510 }
511 /* User gave a lock table option, validate it */
512 if (*opts->locktable == '\0') {
513 fprintf(stderr, _("Lock table is empty.\n"));
514 return -1;
515 }
516 for (c = opts->locktable; *c; c++) {
517 if (!isalnum(*c) && (*c != '-') && (*c != '_') && (*c != ':')) {
518 fprintf(stderr, "%s %s '%c'\n", errprefix, _("invalid character"), *c);
519 return -1;
520 }
521 }
522 c = strstr(opts->locktable, ":");
523 if (!c) {
524 fprintf(stderr, "%s %s\n", errprefix, _("missing colon"));
525 return -1;
526 }
527
528 if (c == opts->locktable) {
529 fprintf(stderr, "%s %s\n", errprefix, _("cluster name is missing"));
530 return -1;
531 }
532 if (c - opts->locktable > 32) {
533 fprintf(stderr, "%s %s\n", errprefix, _("cluster name is too long"));
534 return -1;
535 }
536
537 c++;
538 if (strstr(c, ":")) {
539 fprintf(stderr, "%s %s\n", errprefix, _("contains more than one colon"));
540 return -1;
541 }
542 if (!strlen(c)) {
543 fprintf(stderr, "%s %s\n", errprefix, _("file system name is missing"));
544 return -1;
545 }
546 if (strlen(c) > 30) {
547 fprintf(stderr, "%s %s\n", errprefix, _("file system name is too long"));
548 return -1;
549 }
550 return 0;
551 }
552
553 static int are_you_sure(void)
554 {
555 while (1) {
556 char *line = NULL;
557 size_t len = 0;
558 int ret;
559 int res;
560
561 /* Translators: We use rpmatch(3) to match the answers to y/n
562 questions in the user's own language, so the [y/n] here must also be
563 translated to match one of the letters in the pattern printed by
564 `locale -k yesexpr` and one of the letters in the pattern printed by
565 `locale -k noexpr` */
566 printf( _("Are you sure you want to proceed? [y/n] "));
567 ret = getline(&line, &len, stdin);
568 if (ret < 0) {
569 printf("\n");
570 free(line);
571 return 0;
572 }
573 res = rpmatch(line);
574 free(line);
575 if (ret == 0)
576 continue;
577 if (res == 1) /* Yes */
578 return 1;
579 if (res == 0) /* No */
580 return 0;
581 /* Unrecognized input; go again. */
582 }
583 }
584
585 static int choose_blocksize(struct mkfs_opts *opts, unsigned *pbsize)
586 {
587 unsigned int x;
588 unsigned int bsize = opts->bsize;
589 struct mkfs_dev *dev = &opts->dev;
590 int got_topol = (dev->got_topol || opts->got_topol);
591
592 if (got_topol && opts->debug) {
593 printf("alignment_offset: %lu\n", dev->alignment_offset);
594 printf("logical_sector_size: %lu\n", dev->logical_sector_size);
595 printf("minimum_io_size: %lu\n", dev->minimum_io_size);
596 printf("optimal_io_size: %lu\n", dev->optimal_io_size);
597 printf("physical_sector_size: %lu\n", dev->physical_sector_size);
598 }
599 if (got_topol && dev->alignment_offset != 0) {
600 fprintf(stderr,
601 _("Warning: device is not properly aligned. This may harm performance.\n"));
602 dev->physical_sector_size = dev->logical_sector_size;
603 }
604 if (!opts->got_bsize && got_topol) {
605 if (dev->optimal_io_size <= getpagesize() &&
606 dev->optimal_io_size >= LGFS2_DEFAULT_BSIZE)
607 bsize = dev->optimal_io_size;
608 else if (dev->physical_sector_size <= getpagesize() &&
609 dev->physical_sector_size >= LGFS2_DEFAULT_BSIZE)
610 bsize = dev->physical_sector_size;
611 }
612 /* Block sizes must be a power of two from 512 to 65536 */
613 for (x = 512; x; x <<= 1)
614 if (x == bsize)
615 break;
616
617 if (!x || bsize > getpagesize()) {
618 fprintf(stderr, _("Block size must be a power of two between 512 and %d\n"),
619 getpagesize());
620 return -1;
621 }
622 if (bsize < dev->logical_sector_size) {
623 fprintf(stderr, _("Error: Block size %d is less than minimum logical "
624 "block size (%lu).\n"), bsize, dev->logical_sector_size);
625 return -1;
626 }
627 if (bsize < dev->physical_sector_size) {
628 printf( _("Warning: Block size %d is inefficient because it "
629 "is less than the physical block size (%lu).\n"),
630 bsize, dev->physical_sector_size);
631 opts->confirm = 1;
632 }
633 *pbsize = bsize;
634 return 0;
635 }
636
637 static int opts_check(struct mkfs_opts *opts)
638 {
639 if (!opts->got_device) {
640 fprintf(stderr, _("No device specified. Use -h for help\n"));
641 return -1;
642 }
643
644 if (test_locking(opts) != 0)
645 return -1;
646
647 if (LGFS2_MIN_RGSIZE > opts->rgsize || opts->rgsize > LGFS2_MAX_RGSIZE) {
648 /* Translators: gfs2 file systems are split into equal sized chunks called
649 resource groups. We're checking that the user gave a valid size for them. */
650 fprintf(stderr, _("Bad resource group size\n"));
651 return -1;
652 }
653
654 if (!opts->journals) {
655 fprintf(stderr, _("No journals specified\n"));
656 return -1;
657 }
658 if (opts->journals < 0) {
659 fprintf(stderr, _("Number of journals cannot be negative: %d\n"), opts->journals);
660 return -1;
661 }
662 if (opts->jsize < LGFS2_MIN_JSIZE || opts->jsize > LGFS2_MAX_JSIZE) {
663 fprintf(stderr, _("Bad journal size\n"));
664 return -1;
665 }
666
667 if (!opts->qcsize || opts->qcsize > 64) {
668 fprintf(stderr, _("Bad quota change size\n"));
669 return -1;
670 }
671
672 if ((opts->got_sunit && !opts->got_swidth) || (!opts->got_sunit && opts->got_swidth)) {
673 fprintf(stderr, _("Stripe unit and stripe width must be specified together\n"));
674 return -1;
675 }
676 return 0;
677 }
678
679 static void print_results(struct lgfs2_sbd *sb, struct mkfs_opts *opts)
680 {
681 char readable_uuid[36+1];
682
683 uuid_unparse(sb->sd_uuid, readable_uuid);
684
685 printf("%-27s%s\n", _("Device:"), opts->dev.path);
686 printf("%-27s%u\n", _("Block size:"), sb->sd_bsize);
687 printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Device size:"),
688 /* Translators: "GB" here means "gigabytes" */
689 (opts->dev.size / ((float)(1 << 30))), _("GB"),
690 (opts->dev.size / sb->sd_bsize), _("blocks"));
691 printf("%-27s%.2f %s (%"PRIu64" %s)\n", _("Filesystem size:"),
692 (sb->fssize / ((float)(1 << 30)) * sb->sd_bsize), _("GB"), sb->fssize, _("blocks"));
693 printf("%-27s%u\n", _("Journals:"), opts->journals);
694 printf("%-27s%uMB\n", _("Journal size:"), opts->jsize);
695 printf("%-27s%"PRIu64"\n", _("Resource groups:"), nrgrp);
696 printf("%-27s\"%s\"\n", _("Locking protocol:"), opts->lockproto);
697 printf("%-27s\"%s\"\n", _("Lock table:"), opts->locktable);
698 /* Translators: "UUID" = universally unique identifier. */
699 printf("%-27s%s\n", _("UUID:"), readable_uuid);
700 }
701
702 static int warn_of_destruction(const char *path, struct mkfs_opts *opts)
703 {
704 struct stat lnkstat;
705 char *abspath = NULL;
706
707 if (lstat(path, &lnkstat) == -1) {
708 perror(_("Failed to lstat the device"));
709 return -1;
710 }
711 if (S_ISLNK(lnkstat.st_mode)) {
712 /* coverity[toctou:SUPPRESS] */
713 abspath = realpath(path, NULL);
714 if (abspath == NULL) {
715 perror(_("Could not find the absolute path of the device"));
716 return -1;
717 }
718 /* Translators: Example: "/dev/vg/lv is a symbolic link to /dev/dm-2" */
719 printf( _("%s is a symbolic link to %s\n"), path, abspath);
720 path = abspath;
721 }
722 if (!opts->quiet) {
723 printf(_("This will destroy any data on %s\n"), path);
724 fflush(stdout);
725 }
726 free(abspath);
727 return 0;
728 }
729
730 static int build_per_node(struct lgfs2_sbd *sdp, struct mkfs_opts *opts)
731 {
732 struct lgfs2_inode *per_node;
733 unsigned int j;
734
735 /* coverity[identity_transfer:SUPPRESS] False positive */
736 per_node = lgfs2_createi(sdp->master_dir, "per_node", S_IFDIR | 0700,
737 GFS2_DIF_SYSTEM);
738 if (per_node == NULL) {
739 fprintf(stderr, _("Error building '%s': %s\n"), "per_node", strerror(errno));
740 return -1;
741 }
742 for (j = 0; j < sdp->md.journals; j++) {
743 struct lgfs2_inode *ip;
744
745 /* coverity[identity_transfer:SUPPRESS] False positive */
746 ip = lgfs2_build_inum_range(per_node, j);
747 if (ip == NULL) {
748 fprintf(stderr, _("Error building '%s': %s\n"), "inum_range",
749 strerror(errno));
750 lgfs2_inode_put(&per_node);
751 return 1;
752 }
753 debug_print_ip(opts, ip, "inum_range%u:", j);
754 lgfs2_inode_put(&ip);
755
756 /* coverity[identity_transfer:SUPPRESS] False positive */
757 ip = lgfs2_build_statfs_change(per_node, j);
758 if (ip == NULL) {
759 fprintf(stderr, _("Error building '%s': %s\n"), "statfs_change",
760 strerror(errno));
761 lgfs2_inode_put(&per_node);
762 return 1;
763 }
764 debug_print_ip(opts, ip, "statfs_change%u:", j);
765 lgfs2_inode_put(&ip);
766
767 /* coverity[identity_transfer:SUPPRESS] False positive */
768 ip = lgfs2_build_quota_change(per_node, j, LGFS2_DEFAULT_QCSIZE);
769 if (ip == NULL) {
770 fprintf(stderr, _("Error building '%s': %s\n"), "quota_change",
771 strerror(errno));
772 /* coverity[deref_arg:SUPPRESS] */
773 lgfs2_inode_put(&per_node);
774 return 1;
775 }
776 debug_print_ip(opts, ip, "quota_change%u:", j);
777 lgfs2_inode_put(&ip);
778 }
779 debug_print_ip(opts, per_node, "per_node:");
780 lgfs2_inode_put(&per_node);
781 return 0;
782 }
783
784 static int zero_gap(struct lgfs2_sbd *sdp, uint64_t addr, size_t blocks)
785 {
786 struct iovec *iov;
787 char *zerobuf;
788 ssize_t wrote;
789 unsigned i;
790
791 if (blocks == 0)
792 return 0;
793 iov = calloc(blocks, sizeof(*iov));
794 if (iov == NULL) {
795 perror(_("Failed to zero blocks\n"));
796 return 1;
797 }
798 zerobuf = calloc(1, sdp->sd_bsize);
799 if (zerobuf == NULL) {
800 perror(_("Failed to zero blocks\n"));
801 free(iov);
802 return 1;
803 }
804 for (i = 0; i < blocks; i++) {
805 iov[i].iov_base = zerobuf;
806 iov[i].iov_len = sdp->sd_bsize;
807 }
808 wrote = pwritev(sdp->device_fd, iov, blocks, addr * sdp->sd_bsize);
809 if (wrote != blocks * sdp->sd_bsize) {
810 fprintf(stderr, _("Zeroing write failed at block %"PRIu64"\n"), addr);
811 free(zerobuf);
812 free(iov);
813 return 1;
814 }
815 free(zerobuf);
816 free(iov);
817 return 0;
818 }
819
820 static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct lgfs2_sbd *sdp)
821 {
822 lgfs2_rgrps_t rgs;
823 uint64_t al_base = 0;
824 uint64_t al_off = 0;
825
826 if (opts->align && opts->got_sunit) {
827 if ((opts->sunit % sdp->sd_bsize) != 0) {
828 fprintf(stderr, _("Stripe unit (%lu) must be a multiple of block size (%u)\n"),
829 opts->sunit, sdp->sd_bsize);
830 return NULL;
831 } else if ((opts->swidth % opts->sunit) != 0) {
832 fprintf(stderr, _("Stripe width (%lu) must be a multiple of stripe unit (%lu)\n"),
833 opts->swidth, opts->sunit);
834 return NULL;
835 } else {
836 al_base = opts->swidth / sdp->sd_bsize;
837 al_off = opts->sunit / sdp->sd_bsize;
838 }
839 } else if (opts->align) {
840 if (opts->dev.optimal_io_size <= opts->dev.physical_sector_size ||
841 opts->dev.minimum_io_size <= opts->dev.physical_sector_size ||
842 (opts->dev.optimal_io_size % opts->dev.minimum_io_size) != 0) {
843 /* If optimal_io_size is not a multiple of minimum_io_size then
844 the values are not reliable swidth and sunit values, so disable
845 rgrp alignment */
846 opts->align = 0;
847 } else {
848 al_base = opts->dev.optimal_io_size / sdp->sd_bsize;
849 al_off = opts->dev.minimum_io_size / sdp->sd_bsize;
850 }
851 }
852
853 rgs = lgfs2_rgrps_init(sdp, al_base, al_off);
854 if (rgs == NULL) {
855 perror(_("Could not initialise resource groups"));
856 return NULL;
857 }
858
859 if (opts->debug) {
860 printf(" rgrp align = ");
861 if (opts->align)
862 printf("%"PRIu64"+%"PRIu64" blocks\n", al_base, al_off);
863 else
864 printf("(disabled)\n");
865 }
866
867 return rgs;
868 }
869
870 static int place_rgrp(struct lgfs2_sbd *sdp, lgfs2_rgrp_t rg, int debug)
871 {
872 uint64_t prev_end = (GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->sd_bsize) + 1;
873 lgfs2_rgrp_t prev = lgfs2_rgrp_prev(rg);
874 struct gfs2_rindex ri;
875 uint64_t addr;
876 int err = 0;
877
878 if (prev != NULL) {
879 lgfs2_rindex_out(prev, &ri);
880 prev_end = be64_to_cpu(ri.ri_data0) + be32_to_cpu(ri.ri_data);
881 }
882
883 lgfs2_rindex_out(rg, &ri);
884 addr = be64_to_cpu(ri.ri_addr);
885
886 while (prev_end < addr) {
887 size_t gap_len = addr - prev_end;
888
889 if (gap_len > IOV_MAX)
890 gap_len = IOV_MAX;
891 err = zero_gap(sdp, prev_end, gap_len);
892 if (err != 0)
893 return -1;
894 prev_end += gap_len;
895 }
896 err = lgfs2_rgrp_write(sdp->device_fd, rg);
897 if (err != 0) {
898 perror(_("Failed to write resource group"));
899 return -1;
900 }
901 if (debug) {
902 rindex_print(&ri);
903 printf("\n");
904 }
905 sdp->blks_total += be32_to_cpu(ri.ri_data);
906 sdp->fssize = be64_to_cpu(ri.ri_data0) + be32_to_cpu(ri.ri_data);
907 nrgrp++;
908 return 0;
909 }
910
911 static int add_rgrp(lgfs2_rgrps_t rgs, uint64_t *addr, uint32_t len, lgfs2_rgrp_t *rg)
912 {
913 struct gfs2_rindex ri;
914 uint64_t nextaddr;
915
916 /* When we get to the end of the device, it's only an error if we have
917 more structures left to write, i.e. when len is != 0. */
918 nextaddr = lgfs2_rindex_entry_new(rgs, &ri, *addr, len);
919 if (nextaddr == 0) {
920 if (len != 0) {
921 perror(_("Failed to create resource group index entry"));
922 return -1;
923 } else {
924 return 1;
925 }
926 }
927 *rg = lgfs2_rgrps_append(rgs, &ri, nextaddr - *addr);
928 if (*rg == NULL) {
929 perror(_("Failed to create resource group"));
930 return -1;
931 }
932 *addr = nextaddr;
933 return 0;
934 }
935
936 static int place_journals(struct lgfs2_sbd *sdp, lgfs2_rgrps_t rgs, struct mkfs_opts *opts, uint64_t *rgaddr)
937 {
938 struct gfs2_progress_bar progress;
939 uint64_t jfsize = lgfs2_space_for_data(sdp, sdp->sd_bsize, opts->jsize << 20);
940 uint32_t rgsize = lgfs2_rgsize_for_data(jfsize, sdp->sd_bsize);
941 unsigned j;
942
943 gfs2_progress_init(&progress, opts->journals, _("Adding journals: "), opts->quiet);
944
945 /* We'll build the jindex later so remember where we put the journals */
946 mkfs_journals = calloc(opts->journals, sizeof(*mkfs_journals));
947 if (mkfs_journals == NULL)
948 return 1;
949 *rgaddr = lgfs2_rgrp_align_addr(rgs, LGFS2_SB_ADDR(sdp) + 1);
950 rgsize = lgfs2_rgrp_align_len(rgs, rgsize);
951
952 for (j = 0; j < opts->journals; j++) {
953 int result;
954 lgfs2_rgrp_t rg;
955 struct lgfs2_inode in = {0};
956 struct gfs2_rindex ri;
957
958 gfs2_progress_update(&progress, (j + 1));
959
960 if (opts->debug)
961 printf(_("Placing resource group for journal%u\n"), j);
962
963 result = add_rgrp(rgs, rgaddr, rgsize, &rg);
964 if (result > 0)
965 break;
966 else if (result < 0)
967 return result;
968
969 result = lgfs2_rgrp_bitbuf_alloc(rg);
970 if (result != 0) {
971 perror(_("Failed to allocate space for bitmap buffer"));
972 return result;
973 }
974 /* Allocate at the beginning of the rgrp, bypassing extent search */
975 lgfs2_rindex_out(rg, &ri);
976 in.i_num.in_addr = be64_to_cpu(ri.ri_data0);
977 /* In order to keep writes sequential here, we have to allocate
978 the journal, then write the rgrp header (which is now in its
979 final form) and then write the journal out */
980 result = lgfs2_file_alloc(rg, opts->jsize << 20, &in, GFS2_DIF_SYSTEM, S_IFREG | 0600);
981 if (result != 0) {
982 fprintf(stderr, _("Failed to allocate space for journal %u\n"), j);
983 return result;
984 }
985
986 result = place_rgrp(sdp, rg, opts->debug);
987 if (result != 0)
988 return result;
989
990 lgfs2_rgrp_bitbuf_free(rg);
991
992 result = lgfs2_write_filemeta(&in);
993 if (result != 0) {
994 fprintf(stderr, _("Failed to write journal %u: %s\n"),
995 j, strerror(errno));
996 return result;
997 }
998
999 result = lgfs2_write_journal_data(&in);
1000 if (result != 0) {
1001 fprintf(stderr, _("Failed to write data blocks for journal %u: %s\n"),
1002 j, strerror(errno));
1003 return result;
1004 }
1005 mkfs_journals[j] = in.i_num;
1006 }
1007 gfs2_progress_close(&progress, _("Done\n"));
1008
1009 return 0;
1010 }
1011
1012 static int place_rgrps(struct lgfs2_sbd *sdp, lgfs2_rgrps_t rgs, uint64_t *rgaddr, struct mkfs_opts *opts)
1013 {
1014 struct gfs2_progress_bar progress;
1015 uint32_t rgblks = ((opts->rgsize << 20) / sdp->sd_bsize);
1016 uint32_t rgnum;
1017 int result;
1018
1019 rgnum = lgfs2_rgrps_plan(rgs, sdp->device.length - *rgaddr, rgblks);
1020 gfs2_progress_init(&progress, (rgnum + opts->journals), _("Building resource groups: "), opts->quiet);
1021
1022 while (1) {
1023 lgfs2_rgrp_t rg;
1024 result = add_rgrp(rgs, rgaddr, 0, &rg);
1025 if (result > 0)
1026 break;
1027 else if (result < 0)
1028 return result;
1029
1030 result = place_rgrp(sdp, rg, opts->debug);
1031 if (result != 0) {
1032 fprintf(stderr, _("Failed to build resource groups\n"));
1033 return result;
1034 }
1035 gfs2_progress_update(&progress, nrgrp);
1036 }
1037 if (lgfs2_rgrps_write_final(sdp->device_fd, rgs) != 0) {
1038 perror(_("Failed to write final resource group"));
1039 return 0;
1040 }
1041 gfs2_progress_close(&progress, _("Done\n"));
1042
1043 return 0;
1044 }
1045
1046 static int create_jindex(struct lgfs2_sbd *sdp, struct mkfs_opts *opts, struct lgfs2_inum *jnls)
1047 {
1048 struct lgfs2_inode *jindex;
1049
1050 jindex = lgfs2_build_jindex(sdp->master_dir, jnls, opts->journals);
1051 if (jindex == NULL) {
1052 fprintf(stderr, _("Error building '%s': %s\n"), "jindex", strerror(errno));
1053 return 1;
1054 }
1055 debug_print_ip(opts, jindex, "jindex:");
1056 lgfs2_inode_put(&jindex);
1057 return 0;
1058 }
1059
1060
1061 /*
1062 * Find a reasonable journal file size (in blocks) given the number of blocks
1063 * in the filesystem. For very small filesystems, it is not reasonable to
1064 * have a journal that fills more than half of the filesystem.
1065 *
1066 * n.b. comments assume 4k blocks
1067 *
1068 * This was copied and adapted from e2fsprogs.
1069 */
1070 static int default_journal_size(unsigned bsize, uint64_t num_blocks)
1071 {
1072 int min_blocks = (LGFS2_MIN_JSIZE << 20) / bsize;
1073
1074 if (num_blocks < 2 * min_blocks)
1075 return -1;
1076 if (num_blocks < 131072) /* 512 MB */
1077 return min_blocks; /* 8 MB */
1078 if (num_blocks < 512*1024) /* 2 GB */
1079 return (4096); /* 16 MB */
1080 if (num_blocks < 2048*1024) /* 8 GB */
1081 return (8192); /* 32 MB */
1082 if (num_blocks < 4096*1024) /* 16 GB */
1083 return (16384); /* 64 MB */
1084 if (num_blocks < 262144*1024) /* 1 TB */
1085 return (32768); /* 128 MB */
1086 if (num_blocks < 2621440UL*1024) /* 10 TB */
1087 return (131072); /* 512 MB */
1088 return 262144; /* 1 GB */
1089 }
1090
1091 static int sbd_init(struct lgfs2_sbd *sdp, struct mkfs_opts *opts, unsigned bsize)
1092 {
1093 memset(sdp, 0, sizeof(struct lgfs2_sbd));
1094 sdp->rgtree.osi_node = NULL;
1095 sdp->md.journals = opts->journals;
1096 sdp->device_fd = opts->dev.fd;
1097 sdp->sd_bsize = bsize;
1098 sdp->sd_fs_format = opts->format;
1099 sdp->sd_multihost_format = GFS2_FORMAT_MULTI;
1100 sdp->sd_bsize = bsize;
1101 sdp->sd_bsize_shift = ffs(bsize) - 1;
1102
1103 if (opts->got_uuid) {
1104 int err = uuid_parse(opts->uuid, sdp->sd_uuid);
1105 if (err != 0) {
1106 fprintf(stderr, _("Failed to parse UUID option."));
1107 return -1;
1108 }
1109 } else
1110 uuid_generate(sdp->sd_uuid);
1111
1112 if (lgfs2_compute_constants(sdp)) {
1113 perror(_("Failed to compute file system constants"));
1114 return -1;
1115 }
1116 sdp->device.length = opts->dev.size / sdp->sd_bsize;
1117 if (opts->got_fssize) {
1118 if (opts->fssize > sdp->device.length) {
1119 fprintf(stderr, _("Specified size is bigger than the device."));
1120 fprintf(stderr, "%s %.2f %s (%"PRIu64" %s)\n", _("Device size:"),
1121 opts->dev.size / ((float)(1 << 30)), _("GB"),
1122 opts->dev.size / sdp->sd_bsize, _("blocks"));
1123 return -1;
1124 }
1125 sdp->device.length = opts->fssize;
1126 }
1127 /* opts->jsize has already been max/min checked but we need to check it
1128 makes sense for the device size, or set a sensible default, if one
1129 will fit. For user-provided journal sizes, limit it to half of the fs. */
1130 if (!opts->got_jsize) {
1131 int default_jsize = default_journal_size(sdp->sd_bsize, sdp->device.length / opts->journals);
1132 unsigned jsize_mb;
1133
1134 if (default_jsize < 0) {
1135 fprintf(stderr, _("gfs2 will not fit on this device.\n"));
1136 return -1;
1137 }
1138 jsize_mb = (default_jsize * sdp->sd_bsize) >> 20;
1139 if (jsize_mb < LGFS2_MIN_JSIZE)
1140 opts->jsize = LGFS2_MIN_JSIZE;
1141 else
1142 opts->jsize = jsize_mb;
1143 } else if ((((opts->jsize * opts->journals) << 20) / sdp->sd_bsize) > (sdp->device.length / 2)) {
1144 unsigned max_jsize = (sdp->device.length / 2 * sdp->sd_bsize / opts->journals) >> 20;
1145
1146 fprintf(stderr, _("gfs2 will not fit on this device.\n"));
1147 if (max_jsize >= LGFS2_MIN_JSIZE)
1148 fprintf(stderr, _("Maximum size for %u journals on this device is %uMB.\n"),
1149 opts->journals, max_jsize);
1150 return -1;
1151 }
1152 return 0;
1153 }
1154
1155 static int probe_contents(struct mkfs_dev *dev)
1156 {
1157 int ret;
1158 const char *contents;
1159 blkid_probe pr = blkid_new_probe();
1160 if (pr == NULL || blkid_probe_set_device(pr, dev->fd, 0, 0) != 0
1161 || blkid_probe_enable_superblocks(pr, 1) != 0
1162 || blkid_probe_enable_partitions(pr, 1) != 0) {
1163 fprintf(stderr, _("Failed to create probe\n"));
1164 return -1;
1165 }
1166
1167 if (!S_ISREG(dev->stat.st_mode) && blkid_probe_enable_topology(pr, 1) != 0) {
1168 fprintf(stderr, _("Failed to create probe\n"));
1169 return -1;
1170 }
1171
1172 ret = blkid_do_fullprobe(pr);
1173 if (ret == -1) {
1174 fprintf(stderr, _("Failed to probe device\n"));
1175 return -1;
1176 }
1177
1178 if (ret == 1)
1179 return 0;
1180
1181 if (!blkid_probe_lookup_value(pr, "TYPE", &contents, NULL)) {
1182 printf(_("%s appears to contain an existing filesystem (%s)\n"),
1183 dev->path, contents);
1184 } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &contents, NULL)) {
1185 printf(_("%s appears to contain a partition table (%s).\n"),
1186 dev->path, contents);
1187 }
1188
1189 if (!S_ISREG(dev->stat.st_mode)) {
1190 blkid_topology tp = blkid_probe_get_topology(pr);
1191 if (tp != NULL) {
1192 dev->alignment_offset = blkid_topology_get_alignment_offset(tp);
1193 dev->logical_sector_size = blkid_topology_get_logical_sector_size(tp);
1194 dev->minimum_io_size = blkid_topology_get_minimum_io_size(tp);
1195 dev->optimal_io_size = blkid_topology_get_optimal_io_size(tp);
1196 dev->physical_sector_size = blkid_topology_get_physical_sector_size(tp);
1197 dev->got_topol = (dev->logical_sector_size != 0 &&
1198 dev->physical_sector_size != 0);
1199 }
1200 }
1201
1202 blkid_free_probe(pr);
1203 return 0;
1204 }
1205
1206 static int open_dev(struct mkfs_dev *dev, int withprobe)
1207 {
1208 int error;
1209
1210 dev->fd = open(dev->path, O_RDWR|O_CLOEXEC|O_EXCL);
1211 if (dev->fd < 0) {
1212 perror(dev->path);
1213 return 1;
1214 }
1215
1216 /* Freshen up the cache */
1217 (void)posix_fadvise(dev->fd, 0, 0, POSIX_FADV_DONTNEED);
1218
1219 error = fstat(dev->fd, &dev->stat);
1220 if (error < 0) {
1221 perror(dev->path);
1222 return 1;
1223 }
1224
1225 if (S_ISREG(dev->stat.st_mode)) {
1226 dev->size = dev->stat.st_size;
1227 } else if (S_ISBLK(dev->stat.st_mode)) {
1228 dev->size = lseek(dev->fd, 0, SEEK_END);
1229 if (dev->size < 1) {
1230 fprintf(stderr, _("Device '%s' is too small\n"), dev->path);
1231 return 1;
1232 }
1233 } else {
1234 fprintf(stderr, _("'%s' is not a block device or regular file\n"), dev->path);
1235 return 1;
1236 }
1237 if (withprobe && (probe_contents(dev) != 0))
1238 return 1;
1239 return 0;
1240 }
1241
1242 #ifndef UNITTESTS
1243 int main(int argc, char *argv[])
1244 {
1245 struct gfs2_statfs_change sc;
1246 struct lgfs2_sbd sbd;
1247 struct mkfs_opts opts;
1248 struct lgfs2_inode *ip;
1249 lgfs2_rgrps_t rgs;
1250 uint64_t rgaddr;
1251 int error;
1252 unsigned bsize;
1253
1254 setlocale(LC_ALL, "");
1255 textdomain("gfs2-utils");
1256 srandom(time(NULL) ^ getpid());
1257
1258 opts_init(&opts);
1259 error = opts_get(argc, argv, &opts);
1260 if (error == 1)
1261 exit(0);
1262 if (error != 0)
1263 exit(-1);
1264 error = opts_check(&opts);
1265 if (error != 0)
1266 exit(error);
1267
1268 error = open_dev(&opts.dev, !opts.got_topol);
1269 if (error != 0)
1270 exit(error);
1271 error = choose_blocksize(&opts, &bsize);
1272 if (error != 0)
1273 exit(-1);
1274
1275 if (S_ISREG(opts.dev.stat.st_mode)) {
1276 opts.got_bsize = 1; /* Use default block size for regular files */
1277 }
1278 if (sbd_init(&sbd, &opts, bsize) != 0)
1279 exit(-1);
1280 if (opts.debug) {
1281 printf(_("File system options:\n"));
1282 printf(" bsize = %u\n", sbd.sd_bsize);
1283 printf(" qcsize = %u\n", opts.qcsize);
1284 printf(" jsize = %u\n", opts.jsize);
1285 printf(" journals = %u\n", sbd.md.journals);
1286 printf(" proto = %s\n", opts.lockproto);
1287 printf(" table = %s\n", opts.locktable);
1288 printf(" rgsize = %u\n", opts.rgsize);
1289 printf(" fssize = %"PRIu64"\n", opts.fssize);
1290 printf(" sunit = %lu\n", opts.sunit);
1291 printf(" swidth = %lu\n", opts.swidth);
1292 printf(" format = %u\n", opts.format);
1293 }
1294 rgs = rgs_init(&opts, &sbd);
1295 if (rgs == NULL)
1296 exit(-1);
1297 if (warn_of_destruction(opts.dev.path, &opts) != 0)
1298 exit(-1);
1299
1300 if (opts.confirm && !opts.override)
1301 if (!are_you_sure())
1302 exit(-1);
1303
1304 if (!S_ISREG(opts.dev.stat.st_mode) && opts.discard) {
1305 if (!opts.quiet) {
1306 printf("%s", _("Discarding device contents (may take a while on large devices): "));
1307 fflush(stdout);
1308 }
1309 discard_blocks(opts.dev.fd, opts.dev.size, opts.debug);
1310
1311 if (!opts.quiet)
1312 printf("%s", _("Done\n"));
1313 }
1314 rgaddr = lgfs2_rgrp_align_addr(rgs, LGFS2_SB_ADDR(&sbd) + 1);
1315 error = place_journals(&sbd, rgs, &opts, &rgaddr);
1316 if (error != 0) {
1317 fprintf(stderr, _("Failed to create journals\n"));
1318 exit(1);
1319 }
1320 error = place_rgrps(&sbd, rgs, &rgaddr, &opts);
1321 if (error) {
1322 fprintf(stderr, _("Failed to build resource groups\n"));
1323 exit(1);
1324 }
1325 lgfs2_attach_rgrps(&sbd, rgs); // Temporary
1326
1327 error = lgfs2_build_master(&sbd);
1328 if (error) {
1329 fprintf(stderr, _("Error building '%s': %s\n"), "master", strerror(errno));
1330 exit(EXIT_FAILURE);
1331 }
1332 debug_print_ip(&opts, sbd.master_dir, "master:");
1333 sbd.sd_meta_dir = sbd.master_dir->i_num;
1334
1335 error = create_jindex(&sbd, &opts, mkfs_journals);
1336 free(mkfs_journals);
1337 if (error != 0)
1338 exit(1);
1339
1340 error = build_per_node(&sbd, &opts);
1341 if (error != 0)
1342 exit(1);
1343
1344 sbd.md.inum = lgfs2_build_inum(&sbd);
1345 if (sbd.md.inum == NULL) {
1346 fprintf(stderr, _("Error building '%s': %s\n"), "inum", strerror(errno));
1347 exit(EXIT_FAILURE);
1348 }
1349 debug_print_ip(&opts, sbd.md.inum, "inum:");
1350 sbd.md.statfs = lgfs2_build_statfs(&sbd);
1351 if (sbd.md.statfs == NULL) {
1352 fprintf(stderr, _("Error building '%s': %s\n"), "statfs", strerror(errno));
1353 exit(EXIT_FAILURE);
1354 }
1355 debug_print_ip(&opts, sbd.md.statfs, "statfs:");
1356 ip = lgfs2_build_rindex(&sbd);
1357 if (ip == NULL) {
1358 fprintf(stderr, _("Error building '%s': %s\n"), "rindex", strerror(errno));
1359 exit(EXIT_FAILURE);
1360 }
1361 debug_print_ip(&opts, ip, "rindex:");
1362 lgfs2_inode_put(&ip);
1363 if (!opts.quiet) {
1364 printf("%s", _("Creating quota file: "));
1365 fflush(stdout);
1366 }
1367 ip = lgfs2_build_quota(&sbd);
1368 if (ip == NULL) {
1369 fprintf(stderr, _("Error building '%s': %s\n"), "quota", strerror(errno));
1370 exit(EXIT_FAILURE);
1371 }
1372 debug_print_ip(&opts, ip, "quota:");
1373 lgfs2_inode_put(&ip);
1374 if (!opts.quiet)
1375 printf("%s", _("Done\n"));
1376
1377 lgfs2_build_root(&sbd);
1378 if (opts.root_inherit_jd) {
1379 sbd.md.rooti->i_flags |= GFS2_DIF_INHERIT_JDATA;
1380 lgfs2_dinode_out(sbd.md.rooti, sbd.md.rooti->i_bh->b_data);
1381 }
1382 debug_print_ip(&opts, sbd.md.rooti, "root:");
1383 sbd.sd_root_dir = sbd.md.rooti->i_num;
1384
1385 strncpy(sbd.sd_lockproto, opts.lockproto, GFS2_LOCKNAME_LEN - 1);
1386 strncpy(sbd.sd_locktable, opts.locktable, GFS2_LOCKNAME_LEN - 1);
1387 sbd.sd_lockproto[GFS2_LOCKNAME_LEN - 1] = '\0';
1388 sbd.sd_locktable[GFS2_LOCKNAME_LEN - 1] = '\0';
1389
1390 lgfs2_init_inum(&sbd);
1391 if (opts.debug)
1392 printf("Next inum: %"PRIu64"\n", sbd.md.next_inum);
1393
1394 lgfs2_init_statfs(&sbd, &sc);
1395 if (opts.debug) {
1396 printf("Statfs:\n");
1397 statfs_change_print(&sc);
1398 printf("\n");
1399 }
1400 lgfs2_inode_put(&sbd.md.rooti);
1401 lgfs2_inode_put(&sbd.master_dir);
1402 lgfs2_inode_put(&sbd.md.inum);
1403 lgfs2_inode_put(&sbd.md.statfs);
1404
1405 lgfs2_rgrps_free(&rgs);
1406
1407 if (!opts.quiet) {
1408 printf("%s", _("Writing superblock and syncing: "));
1409 fflush(stdout);
1410 }
1411
1412 error = lgfs2_sb_write(&sbd, opts.dev.fd);
1413 if (error) {
1414 perror(_("Failed to write superblock\n"));
1415 exit(EXIT_FAILURE);
1416 }
1417
1418 error = fsync(opts.dev.fd);
1419 if (error){
1420 perror(opts.dev.path);
1421 exit(EXIT_FAILURE);
1422 }
1423 error = close(opts.dev.fd);
1424 if (error){
1425 perror(opts.dev.path);
1426 exit(EXIT_FAILURE);
1427 }
1428
1429 if (!opts.quiet) {
1430 printf("%s", _("Done\n"));
1431 print_results(&sbd, &opts);
1432 }
1433 return 0;
1434 }
1435 #endif /* UNITTESTS */
1436