25
28
/* superblock - 512 bytes */
28
unsigned int s_start; /* byte offset of start of data */
29
unsigned int s_end; /* sizeof(slice)-1 */
31
/* for recovery during compaction */
32
int s_from, s_to; /* src and dest block of current transfer */
33
int s_backup_from, s_backup_to;
35
/* labels - may well contain garbage */
31
unsigned int s_start; /* byte offset of start of data */
32
unsigned int s_end; /* sizeof(slice)-1 */
34
/* for recovery during compaction */
35
int s_from, s_to; /* src and dest block of current transfer */
36
int s_backup_from, s_backup_to;
38
/* labels - may well contain garbage */
41
44
/* inode - 64 bytes */
44
unsigned char i_pad1[2];
45
unsigned long i_first_block;
46
unsigned long i_last_block;
47
unsigned long i_bytes_to_end;
48
unsigned long i_type; /* 1: file, 2: the unique dir */
50
unsigned long i_uid, i_gid;
51
unsigned long i_nlinks;
52
unsigned long i_atime, i_mtime, i_ctime;
53
unsigned char i_pad2[16];
47
unsigned char i_pad1[2];
48
unsigned long i_first_block;
49
unsigned long i_last_block;
50
unsigned long i_bytes_to_end;
51
unsigned long i_type; /* 1: file, 2: the unique dir */
53
unsigned long i_uid, i_gid;
54
unsigned long i_nlinks;
55
unsigned long i_atime, i_mtime, i_ctime;
56
unsigned char i_pad2[16];
56
59
#define BFS_DIR_TYPE 2
58
61
/* directory entry - 16 bytes */
61
char d_name[BFS_NAMELEN];
64
char d_name[BFS_NAMELEN];
65
static char *progname;
73
fprintf(stderr, "\n%s: ", progname);
74
vfprintf(stderr, s, p);
76
fprintf(stderr, "\n");
83
"Usage: %s [-v] [-N nr-of-inodes] [-V volume-name]\n"
84
" [-F fsname] device [block-count]\n"),
90
main(int argc, char *argv[]) {
67
static void __attribute__ ((__noreturn__)) usage(FILE * out)
70
_("Usage: %s [options] device [block-count]\n"),
71
program_invocation_short_name);
72
fprintf(out, _("\nOptions:\n"
73
" -N, --inodes=NUM specify desired number of inodes\n"
74
" -V, --vname=NAME specify volume name\n"
75
" -F, --fname=NAME specify file system name\n"
76
" -v, --verbose explain what is being done\n"
77
" -c this option is silently ignored\n"
78
" -l this option is silently ignored\n"
79
" -V, --version output version information and exit\n"
80
" -V as version must be only option\n"
81
" -h, --help display this help and exit\n\n"));
83
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
86
static void __attribute__ ((__noreturn__)) print_version(void)
88
printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING);
92
int main(int argc, char **argv)
91
94
char *device, *volume, *fsname;
93
96
unsigned long long total_blocks, ino_bytes, ino_blocks, data_blocks;
94
97
unsigned long long user_specified_total_blocks = 0;
100
103
struct stat statbuf;
106
if ((p = strrchr(progname, '/')) != NULL)
107
enum { VERSION_OPTION = CHAR_MAX + 1 };
108
static const struct option longopts[] = {
109
{"inodes", required_argument, NULL, 'N'},
110
{"vname", required_argument, NULL, 'V'},
111
{"fname", required_argument, NULL, 'F'},
112
{"verbose", no_argument, NULL, 'v'},
113
{"version", no_argument, NULL, VERSION_OPTION},
114
{"help", no_argument, NULL, 'h'},
113
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
114
printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
121
if (argc == 2 && !strcmp(argv[1], "-V"))
118
124
volume = fsname = " "; /* is there a default? */
121
while ((c = getopt(argc, argv, "vF:N:V:cl:")) != -1) {
127
while ((c = getopt_long(argc, argv, "N:V:F:vhcl", longopts, NULL)) != -1) {
124
inodes = atol(optarg);
130
inodes = strtol_or_err(optarg, _("invalid number of inodes"));
128
134
len = strlen(optarg);
129
135
if (len <= 0 || len > 6)
130
fatal(_("volume name too long"));
131
volume = strdup(optarg);
136
errx(EXIT_FAILURE, _("volume name too long"));
137
volume = xstrdup(optarg);
135
141
len = strlen(optarg);
136
142
if (len <= 0 || len > 6)
137
fatal(_("fsname name too long"));
138
fsname = strdup(optarg);
143
errx(EXIT_FAILURE, _("fsname name too long"));
144
fsname = xstrdup(optarg);
145
/* when called via mkfs we may get options c,l,v */
153
/* when called via mkfs we may get options c,l,v */
155
165
if (optind == argc)
158
168
device = argv[optind++];
160
if (stat(device, &statbuf) == -1) {
162
fatal(_("cannot stat device %s"), device);
170
if (stat(device, &statbuf) < 0)
171
err(EXIT_FAILURE, _("cannot stat device %s"), device);
165
173
if (!S_ISBLK(statbuf.st_mode))
166
fatal(_("%s is not a block special device"), device);
174
errx(EXIT_FAILURE, _("%s is not a block special device"), device);
168
176
fd = open(device, O_RDWR | O_EXCL);
171
fatal(_("cannot open %s"), device);
178
err(EXIT_FAILURE, _("cannot open %s"), device);
174
if (optind == argc-1)
175
user_specified_total_blocks = atoll(argv[optind]);
180
if (optind == argc - 1)
181
user_specified_total_blocks =
182
strtoll_or_err(argv[optind], _("invalid block-count"));
176
183
else if (optind != argc)
179
186
if (blkdev_get_sectors(fd, &total_blocks) == -1) {
180
if (!user_specified_total_blocks) {
181
perror("blkdev_get_sectors");
182
fatal(_("cannot get size of %s"), device);
187
if (!user_specified_total_blocks)
188
err(EXIT_FAILURE, _("cannot get size of %s"), device);
184
189
total_blocks = user_specified_total_blocks;
185
190
} else if (user_specified_total_blocks) {
186
191
if (user_specified_total_blocks > total_blocks)
187
fatal(_("blocks argument too large, max is %llu"),
193
_("blocks argument too large, max is %llu"),
189
195
total_blocks = user_specified_total_blocks;
193
199
/* pick some reasonable default */
194
inodes = 8*(total_blocks/800);
200
inodes = 8 * (total_blocks / 800);
200
206
/* believe the user */
202
fatal(_("too many inodes - max is 512"));
208
errx(EXIT_FAILURE, _("too many inodes - max is 512"));
205
211
ino_bytes = inodes * sizeof(struct bfsi);
224
231
fprintf(stderr, _("Volume: <%-6s>\n"), volume);
225
232
fprintf(stderr, _("FSname: <%-6s>\n"), fsname);
226
233
fprintf(stderr, _("BlockSize: %d\n"), BFS_BLOCKSIZE);
228
fprintf(stderr, _("Inodes: %d (in 1 block)\n"),
235
fprintf(stderr, _("Inodes: %lu (in 1 block)\n"),
231
fprintf(stderr, _("Inodes: %d (in %lld blocks)\n"),
238
fprintf(stderr, _("Inodes: %lu (in %llu blocks)\n"),
232
239
inodes, ino_blocks);
233
240
fprintf(stderr, _("Blocks: %lld\n"), total_blocks);
234
241
fprintf(stderr, _("Inode end: %d, Data end: %d\n"),
235
sb.s_start-1, sb.s_end);
242
sb.s_start - 1, sb.s_end);
238
245
if (write(fd, &sb, sizeof(sb)) != sizeof(sb))
239
fatal(_("error writing superblock"));
246
err(EXIT_FAILURE, _("error writing superblock"));
241
248
memset(&ri, 0, sizeof(ri));
242
249
ri.i_ino = BFS_ROOT_INO;
243
250
ri.i_first_block = 1 + ino_blocks;
244
251
ri.i_last_block = ri.i_first_block +
245
(inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
252
(inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
246
253
ri.i_bytes_to_end = ri.i_first_block * BFS_BLOCKSIZE
247
+ 2 * sizeof(struct bfsde) - 1;
254
+ 2 * sizeof(struct bfsde) - 1;
248
255
ri.i_type = BFS_DIR_TYPE;
249
ri.i_mode = S_IFDIR | 0755; /* or just 0755 */
256
ri.i_mode = S_IFDIR | 0755; /* or just 0755 */
251
258
ri.i_gid = 1; /* random */
256
263
ri.i_ctime = now;
258
265
if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
259
fatal(_("error writing root inode"));
266
err(EXIT_FAILURE, _("error writing root inode"));
261
268
memset(&ri, 0, sizeof(ri));
262
for (i=1; i<inodes; i++)
269
for (i = 1; i < inodes; i++)
263
270
if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
264
fatal(_("error writing inode"));
271
err(EXIT_FAILURE, _("error writing inode"));
266
if (lseek(fd, (1 + ino_blocks)*BFS_BLOCKSIZE, SEEK_SET) == -1)
267
fatal(_("seek error"));
273
if (lseek(fd, (1 + ino_blocks) * BFS_BLOCKSIZE, SEEK_SET) == -1)
274
err(EXIT_FAILURE, _("seek error"));
269
276
memset(&de, 0, sizeof(de));
270
277
de.d_ino = BFS_ROOT_INO;
271
278
memcpy(de.d_name, ".", 1);
272
279
if (write(fd, &de, sizeof(de)) != sizeof(de))
273
fatal(_("error writing . entry"));
280
err(EXIT_FAILURE, _("error writing . entry"));
275
282
memcpy(de.d_name, "..", 2);
276
283
if (write(fd, &de, sizeof(de)) != sizeof(de))
277
fatal(_("error writing .. entry"));
279
if (close(fd) == -1) {
281
fatal(_("error closing %s"), device);
284
err(EXIT_FAILURE, _("error writing .. entry"));
287
err(EXIT_FAILURE, _("error closing %s"), device);