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 	
(4) Event deallocator: Deallocator for "struct lgfs2_sbd".
Also see events: [allocation][assign][allocation]
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