]>
Commit | Line | Data |
---|---|---|
3839e657 TT |
1 | /* |
2 | * mke2fs.c - Make a ext2fs filesystem. | |
3 | * | |
19c78dc0 TT |
4 | * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o. |
5 | * | |
6 | * %Begin-Header% | |
7 | * This file may be redistributed under the terms of the GNU Public | |
8 | * License. | |
9 | * %End-Header% | |
3839e657 TT |
10 | */ |
11 | ||
12 | /* Usage: mke2fs [options] device | |
13 | * | |
14 | * The device may be a block device or a image of one, but this isn't | |
15 | * enforced (but it's not much fun on a character device :-). | |
16 | */ | |
17 | ||
a418d3ad | 18 | #include <stdio.h> |
3839e657 TT |
19 | #include <string.h> |
20 | #include <fcntl.h> | |
21 | #include <ctype.h> | |
3839e657 | 22 | #include <time.h> |
2740156b TT |
23 | #ifdef linux |
24 | #include <sys/utsname.h> | |
25 | #endif | |
a418d3ad | 26 | #ifdef HAVE_GETOPT_H |
3839e657 | 27 | #include <getopt.h> |
373b8337 TT |
28 | #else |
29 | extern char *optarg; | |
30 | extern int optind; | |
a418d3ad TT |
31 | #endif |
32 | #ifdef HAVE_UNISTD_H | |
3839e657 | 33 | #include <unistd.h> |
a418d3ad TT |
34 | #endif |
35 | #ifdef HAVE_STDLIB_H | |
3839e657 | 36 | #include <stdlib.h> |
a418d3ad TT |
37 | #endif |
38 | #ifdef HAVE_ERRNO_H | |
39 | #include <errno.h> | |
40 | #endif | |
41 | #ifdef HAVE_MNTENT_H | |
3839e657 | 42 | #include <mntent.h> |
a418d3ad | 43 | #endif |
3839e657 | 44 | #include <sys/ioctl.h> |
f3db3566 TT |
45 | #include <sys/types.h> |
46 | ||
f3db3566 | 47 | #include <linux/ext2_fs.h> |
3839e657 TT |
48 | |
49 | #include "et/com_err.h" | |
1e3472c5 | 50 | #include "uuid/uuid.h" |
896938d5 | 51 | #include "e2p/e2p.h" |
3839e657 | 52 | #include "ext2fs/ext2fs.h" |
63985320 | 53 | #include "util.h" |
3839e657 | 54 | #include "../version.h" |
d9c56d3c | 55 | #include "nls-enable.h" |
3839e657 TT |
56 | |
57 | #define STRIDE_LENGTH 8 | |
58 | ||
6733c2fd | 59 | #ifndef __sparc__ |
1e3472c5 TT |
60 | #define ZAP_BOOTBLOCK |
61 | #endif | |
62 | ||
3839e657 | 63 | extern int isatty(int); |
f3db3566 | 64 | extern FILE *fpopen(const char *cmd, const char *mode); |
3839e657 TT |
65 | |
66 | const char * program_name = "mke2fs"; | |
d48755e9 | 67 | const char * device_name /* = NULL */; |
3839e657 TT |
68 | |
69 | /* Command line options */ | |
d48755e9 TT |
70 | int cflag /* = 0 */ ; |
71 | int verbose /* = 0 */ ; | |
72 | int quiet /* = 0 */ ; | |
73 | int super_only /* = 0 */ ; | |
74 | int force /* = 0 */ ; | |
75 | int noaction /* = 0 */ ; | |
76 | int journal_size /* = 0 */ ; | |
77 | int journal_flags /* = 0 */ ; | |
78 | char *bad_blocks_filename /* = 0 */ ; | |
79 | __u32 fs_stride /* = 0 */ ; | |
3839e657 TT |
80 | |
81 | struct ext2_super_block param; | |
d48755e9 TT |
82 | char *creator_os /* = NULL */ ; |
83 | char *volume_label /* = NULL */ ; | |
84 | char *mount_dir /* = NULL */ ; | |
85 | char *journal_device /* = NULL */ ; | |
3839e657 | 86 | |
63985320 | 87 | static void usage(void) |
3839e657 | 88 | { |
d9c56d3c | 89 | fprintf(stderr, _("Usage: %s [-c|-t|-l filename] [-b block-size] " |
16ad3334 | 90 | "[-f fragment-size]\n\t[-i bytes-per-inode] [-j journal-options]" |
5515e6b4 TT |
91 | " [-N number-of-inodes]\n\t[-m reserved-blocks-percentage] " |
92 | "[-o creator-os] [-g blocks-per-group]\n\t[-L volume-label] " | |
18160d26 TT |
93 | "[-M last-mounted-directory] [-O feature[,...]]\n\t" |
94 | "[-r fs-revision] [-R raid_opts] [-s sparse-super-flag]\n\t" | |
d9c56d3c | 95 | "[-qvSV] device [blocks-count]\n"), |
3839e657 TT |
96 | program_name); |
97 | exit(1); | |
98 | } | |
99 | ||
6733c2fd | 100 | static int int_log2(int arg) |
3839e657 TT |
101 | { |
102 | int l = 0; | |
103 | ||
104 | arg >>= 1; | |
105 | while (arg) { | |
106 | l++; | |
107 | arg >>= 1; | |
108 | } | |
109 | return l; | |
110 | } | |
111 | ||
6733c2fd | 112 | static int int_log10(unsigned int arg) |
1dde43f0 TT |
113 | { |
114 | int l; | |
115 | ||
116 | for (l=0; arg ; l++) | |
117 | arg = arg / 10; | |
118 | return l; | |
119 | } | |
120 | ||
50787ea2 TT |
121 | /* |
122 | * This function sets the default parameters for a filesystem | |
123 | * | |
2740156b TT |
124 | * The type is specified by the user. The size is the maximum size |
125 | * (in megabytes) for which a set of parameters applies, with a size | |
126 | * of zero meaning that it is the default parameter for the type. | |
127 | * Note that order is important in the table below. | |
50787ea2 TT |
128 | */ |
129 | static char default_str[] = "default"; | |
130 | struct mke2fs_defaults { | |
4a600566 TT |
131 | const char *type; |
132 | int size; | |
133 | int blocksize; | |
134 | int inode_ratio; | |
50787ea2 TT |
135 | } settings[] = { |
136 | { default_str, 0, 4096, 8192 }, | |
137 | { default_str, 512, 1024, 4096 }, | |
138 | { default_str, 3, 1024, 8192 }, | |
139 | { "news", 0, 4096, 4096 }, | |
44c09c04 TT |
140 | { "largefile", 0, 4096, 1024 * 1024 }, |
141 | { "largefile4", 0, 4096, 4096 * 1024 }, | |
50787ea2 TT |
142 | { 0, 0, 0, 0}, |
143 | }; | |
144 | ||
ef9abe5f | 145 | static void set_fs_defaults(char *fs_type, struct ext2_super_block *super, |
50787ea2 TT |
146 | int blocksize, int *inode_ratio) |
147 | { | |
148 | int megs; | |
149 | int ratio = 0; | |
150 | struct mke2fs_defaults *p; | |
151 | ||
9094f284 | 152 | megs = (super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / |
50787ea2 TT |
153 | 1024); |
154 | if (inode_ratio) | |
155 | ratio = *inode_ratio; | |
156 | if (!fs_type) | |
157 | fs_type = default_str; | |
158 | for (p = settings; p->type; p++) { | |
159 | if ((strcmp(p->type, fs_type) != 0) && | |
160 | (strcmp(p->type, default_str) != 0)) | |
161 | continue; | |
162 | if ((p->size != 0) && | |
163 | (megs > p->size)) | |
164 | continue; | |
165 | if (ratio == 0) | |
166 | *inode_ratio = p->inode_ratio; | |
167 | if (blocksize == 0) { | |
9094f284 | 168 | super->s_log_frag_size = super->s_log_block_size = |
6733c2fd | 169 | int_log2(p->blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); |
50787ea2 TT |
170 | } |
171 | } | |
172 | if (blocksize == 0) | |
9094f284 | 173 | super->s_blocks_count /= EXT2_BLOCK_SIZE(super) / 1024; |
50787ea2 TT |
174 | } |
175 | ||
3839e657 TT |
176 | /* |
177 | * Helper function for read_bb_file and test_disk | |
178 | */ | |
179 | static void invalid_block(ext2_filsys fs, blk_t blk) | |
180 | { | |
d9c56d3c | 181 | printf(_("Bad block %u out of range; ignored.\n"), blk); |
3839e657 TT |
182 | return; |
183 | } | |
184 | ||
185 | /* | |
186 | * Reads the bad blocks list from a file | |
187 | */ | |
188 | static void read_bb_file(ext2_filsys fs, badblocks_list *bb_list, | |
189 | const char *bad_blocks_file) | |
190 | { | |
191 | FILE *f; | |
192 | errcode_t retval; | |
193 | ||
194 | f = fopen(bad_blocks_file, "r"); | |
195 | if (!f) { | |
196 | com_err("read_bad_blocks_file", errno, | |
d9c56d3c | 197 | _("while trying to open %s"), bad_blocks_file); |
3839e657 TT |
198 | exit(1); |
199 | } | |
200 | retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block); | |
201 | fclose (f); | |
202 | if (retval) { | |
203 | com_err("ext2fs_read_bb_FILE", retval, | |
d9c56d3c | 204 | _("while reading in list of bad blocks from file")); |
3839e657 TT |
205 | exit(1); |
206 | } | |
207 | } | |
208 | ||
209 | /* | |
210 | * Runs the badblocks program to test the disk | |
211 | */ | |
212 | static void test_disk(ext2_filsys fs, badblocks_list *bb_list) | |
213 | { | |
214 | FILE *f; | |
215 | errcode_t retval; | |
216 | char buf[1024]; | |
217 | ||
f635d7f6 TT |
218 | sprintf(buf, "badblocks -b %d %s%s %d", fs->blocksize, |
219 | quiet ? "" : "-s ", fs->device_name, | |
3839e657 TT |
220 | fs->super->s_blocks_count); |
221 | if (verbose) | |
d9c56d3c | 222 | printf(_("Running command: %s\n"), buf); |
3839e657 TT |
223 | f = popen(buf, "r"); |
224 | if (!f) { | |
225 | com_err("popen", errno, | |
d9c56d3c | 226 | _("while trying run '%s'"), buf); |
3839e657 TT |
227 | exit(1); |
228 | } | |
229 | retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block); | |
f3db3566 | 230 | pclose(f); |
3839e657 TT |
231 | if (retval) { |
232 | com_err("ext2fs_read_bb_FILE", retval, | |
d9c56d3c | 233 | _("while processing list of bad blocks from program")); |
3839e657 TT |
234 | exit(1); |
235 | } | |
236 | } | |
237 | ||
238 | static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list) | |
239 | { | |
f3db3566 | 240 | int i, j; |
3839e657 TT |
241 | int must_be_good; |
242 | blk_t blk; | |
243 | badblocks_iterate bb_iter; | |
244 | errcode_t retval; | |
f3db3566 TT |
245 | blk_t group_block; |
246 | int group; | |
247 | int group_bad; | |
3839e657 TT |
248 | |
249 | if (!bb_list) | |
250 | return; | |
251 | ||
252 | /* | |
253 | * The primary superblock and group descriptors *must* be | |
254 | * good; if not, abort. | |
255 | */ | |
256 | must_be_good = fs->super->s_first_data_block + 1 + fs->desc_blocks; | |
257 | for (i = fs->super->s_first_data_block; i <= must_be_good; i++) { | |
258 | if (badblocks_list_test(bb_list, i)) { | |
d9c56d3c TT |
259 | fprintf(stderr, _("Block %d in primary " |
260 | "superblock/group descriptor area bad.\n"), i); | |
261 | fprintf(stderr, _("Blocks %d through %d must be good " | |
262 | "in order to build a filesystem.\n"), | |
3839e657 | 263 | fs->super->s_first_data_block, must_be_good); |
d9c56d3c | 264 | fprintf(stderr, _("Aborting....\n")); |
3839e657 TT |
265 | exit(1); |
266 | } | |
267 | } | |
f3db3566 TT |
268 | |
269 | /* | |
270 | * See if any of the bad blocks are showing up in the backup | |
271 | * superblocks and/or group descriptors. If so, issue a | |
272 | * warning and adjust the block counts appropriately. | |
273 | */ | |
274 | group_block = fs->super->s_first_data_block + | |
275 | fs->super->s_blocks_per_group; | |
f3db3566 TT |
276 | |
277 | for (i = 1; i < fs->group_desc_count; i++) { | |
92bcc595 | 278 | group_bad = 0; |
f3db3566 TT |
279 | for (j=0; j < fs->desc_blocks+1; j++) { |
280 | if (badblocks_list_test(bb_list, group_block + | |
281 | j)) { | |
282 | if (!group_bad) | |
283 | fprintf(stderr, | |
d9c56d3c TT |
284 | _("Warning: the backup superblock/group descriptors at block %d contain\n" |
285 | " bad blocks.\n\n"), | |
f3db3566 TT |
286 | group_block); |
287 | group_bad++; | |
288 | group = ext2fs_group_of_blk(fs, group_block+j); | |
289 | fs->group_desc[group].bg_free_blocks_count++; | |
290 | fs->super->s_free_blocks_count++; | |
291 | } | |
292 | } | |
293 | group_block += fs->super->s_blocks_per_group; | |
294 | } | |
3839e657 TT |
295 | |
296 | /* | |
297 | * Mark all the bad blocks as used... | |
298 | */ | |
299 | retval = badblocks_list_iterate_begin(bb_list, &bb_iter); | |
300 | if (retval) { | |
301 | com_err("badblocks_list_iterate_begin", retval, | |
d9c56d3c | 302 | _("while marking bad blocks as used")); |
3839e657 TT |
303 | exit(1); |
304 | } | |
305 | while (badblocks_list_iterate(bb_iter, &blk)) | |
f3db3566 | 306 | ext2fs_mark_block_bitmap(fs->block_map, blk); |
3839e657 TT |
307 | badblocks_list_iterate_end(bb_iter); |
308 | } | |
309 | ||
19c78dc0 | 310 | static void write_inode_tables(ext2_filsys fs) |
3839e657 TT |
311 | { |
312 | errcode_t retval; | |
313 | blk_t blk; | |
19c78dc0 TT |
314 | int i, j, num, count; |
315 | char *buf; | |
1dde43f0 | 316 | char format[20], backup[80]; |
7d5633cf TT |
317 | int sync_kludge = 0; |
318 | char *mke2fs_sync; | |
319 | ||
320 | mke2fs_sync = getenv("MKE2FS_SYNC"); | |
321 | if (mke2fs_sync) | |
322 | sync_kludge = atoi(mke2fs_sync); | |
3839e657 TT |
323 | |
324 | buf = malloc(fs->blocksize * STRIDE_LENGTH); | |
325 | if (!buf) { | |
d9c56d3c TT |
326 | com_err("malloc", ENOMEM, |
327 | _("while allocating zeroizing buffer")); | |
3839e657 TT |
328 | exit(1); |
329 | } | |
330 | memset(buf, 0, fs->blocksize * STRIDE_LENGTH); | |
1dde43f0 TT |
331 | |
332 | /* | |
333 | * Figure out how many digits we need | |
334 | */ | |
6733c2fd | 335 | i = int_log10(fs->group_desc_count); |
1dde43f0 TT |
336 | sprintf(format, "%%%dd/%%%dld", i, i); |
337 | memset(backup, '\b', sizeof(backup)-1); | |
338 | backup[sizeof(backup)-1] = 0; | |
339 | if ((2*i)+1 < sizeof(backup)) | |
340 | backup[(2*i)+1] = 0; | |
341 | ||
3839e657 | 342 | if (!quiet) |
d9c56d3c | 343 | printf(_("Writing inode tables: ")); |
3839e657 TT |
344 | for (i = 0; i < fs->group_desc_count; i++) { |
345 | if (!quiet) | |
1dde43f0 | 346 | printf(format, i, fs->group_desc_count); |
3839e657 | 347 | |
19c78dc0 TT |
348 | blk = fs->group_desc[i].bg_inode_table; |
349 | num = fs->inode_blocks_per_group; | |
350 | ||
351 | for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { | |
352 | if (num-j > STRIDE_LENGTH) | |
353 | count = STRIDE_LENGTH; | |
354 | else | |
355 | count = num - j; | |
356 | retval = io_channel_write_blk(fs->io, blk, count, buf); | |
357 | if (retval) | |
d9c56d3c TT |
358 | printf(_("Warning: could not write %d blocks " |
359 | "in inode table starting at %d: %s\n"), | |
19c78dc0 TT |
360 | count, blk, error_message(retval)); |
361 | } | |
3839e657 | 362 | if (!quiet) |
1dde43f0 | 363 | fputs(backup, stdout); |
7d5633cf TT |
364 | if (sync_kludge) { |
365 | if (sync_kludge == 1) | |
366 | sync(); | |
367 | else if ((i % sync_kludge) == 0) | |
368 | sync(); | |
369 | } | |
3839e657 | 370 | } |
19c78dc0 | 371 | free(buf); |
3839e657 | 372 | if (!quiet) |
d9c56d3c | 373 | fputs(_("done \n"), stdout); |
3839e657 TT |
374 | } |
375 | ||
376 | static void create_root_dir(ext2_filsys fs) | |
377 | { | |
378 | errcode_t retval; | |
f3db3566 | 379 | struct ext2_inode inode; |
3839e657 TT |
380 | |
381 | retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0); | |
382 | if (retval) { | |
d9c56d3c | 383 | com_err("ext2fs_mkdir", retval, _("while creating root dir")); |
3839e657 TT |
384 | exit(1); |
385 | } | |
f3db3566 TT |
386 | if (geteuid()) { |
387 | retval = ext2fs_read_inode(fs, EXT2_ROOT_INO, &inode); | |
388 | if (retval) { | |
389 | com_err("ext2fs_read_inode", retval, | |
d9c56d3c | 390 | _("while reading root inode")); |
f3db3566 TT |
391 | exit(1); |
392 | } | |
19c78dc0 TT |
393 | inode.i_uid = getuid(); |
394 | if (inode.i_uid) | |
395 | inode.i_gid = getgid(); | |
f3db3566 TT |
396 | retval = ext2fs_write_inode(fs, EXT2_ROOT_INO, &inode); |
397 | if (retval) { | |
398 | com_err("ext2fs_write_inode", retval, | |
d9c56d3c | 399 | _("while setting root inode ownership")); |
f3db3566 TT |
400 | exit(1); |
401 | } | |
402 | } | |
3839e657 TT |
403 | } |
404 | ||
405 | static void create_lost_and_found(ext2_filsys fs) | |
406 | { | |
407 | errcode_t retval; | |
dfcdc32f | 408 | ext2_ino_t ino; |
3839e657 TT |
409 | const char *name = "lost+found"; |
410 | int i; | |
50787ea2 | 411 | int lpf_size = 0; |
3839e657 TT |
412 | |
413 | retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name); | |
414 | if (retval) { | |
d9c56d3c TT |
415 | com_err("ext2fs_mkdir", retval, |
416 | _("while creating /lost+found")); | |
3839e657 TT |
417 | exit(1); |
418 | } | |
419 | ||
420 | retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name, strlen(name), 0, &ino); | |
421 | if (retval) { | |
d9c56d3c TT |
422 | com_err("ext2_lookup", retval, |
423 | _("while looking up /lost+found")); | |
3839e657 TT |
424 | exit(1); |
425 | } | |
426 | ||
427 | for (i=1; i < EXT2_NDIR_BLOCKS; i++) { | |
50787ea2 TT |
428 | if ((lpf_size += fs->blocksize) >= 16*1024) |
429 | break; | |
3839e657 TT |
430 | retval = ext2fs_expand_dir(fs, ino); |
431 | if (retval) { | |
432 | com_err("ext2fs_expand_dir", retval, | |
d9c56d3c | 433 | _("while expanding /lost+found")); |
3839e657 TT |
434 | exit(1); |
435 | } | |
436 | } | |
437 | } | |
438 | ||
439 | static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list) | |
440 | { | |
441 | errcode_t retval; | |
442 | ||
f3db3566 | 443 | ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_BAD_INO); |
3839e657 TT |
444 | fs->group_desc[0].bg_free_inodes_count--; |
445 | fs->super->s_free_inodes_count--; | |
446 | retval = ext2fs_update_bb_inode(fs, bb_list); | |
447 | if (retval) { | |
448 | com_err("ext2fs_update_bb_inode", retval, | |
d9c56d3c | 449 | _("while setting bad block inode")); |
3839e657 TT |
450 | exit(1); |
451 | } | |
452 | ||
453 | } | |
454 | ||
455 | static void reserve_inodes(ext2_filsys fs) | |
456 | { | |
dfcdc32f TT |
457 | ext2_ino_t i; |
458 | int group; | |
3839e657 | 459 | |
7f88b043 | 460 | for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->super); i++) { |
f3db3566 | 461 | ext2fs_mark_inode_bitmap(fs->inode_map, i); |
3839e657 TT |
462 | group = ext2fs_group_of_ino(fs, i); |
463 | fs->group_desc[group].bg_free_inodes_count--; | |
464 | fs->super->s_free_inodes_count--; | |
465 | } | |
466 | ext2fs_mark_ib_dirty(fs); | |
467 | } | |
468 | ||
e41784eb | 469 | static void zap_sector(ext2_filsys fs, int sect) |
f3db3566 TT |
470 | { |
471 | char buf[512]; | |
472 | int retval; | |
473 | ||
474 | memset(buf, 0, 512); | |
475 | ||
e41784eb TT |
476 | io_channel_set_blksize(fs->io, 512); |
477 | retval = io_channel_write_blk(fs->io, sect, -512, buf); | |
478 | io_channel_set_blksize(fs->io, fs->blocksize); | |
f3db3566 | 479 | if (retval) |
e294cf2f | 480 | printf(_("Warning: could not erase sector %d: %s\n"), sect, |
f3db3566 TT |
481 | error_message(retval)); |
482 | } | |
483 | ||
484 | ||
3839e657 TT |
485 | static void show_stats(ext2_filsys fs) |
486 | { | |
ef9abe5f | 487 | struct ext2_super_block *s = fs->super; |
1e3472c5 | 488 | char buf[80]; |
3839e657 | 489 | blk_t group_block; |
1dde43f0 | 490 | int i, need, col_left; |
3839e657 TT |
491 | |
492 | if (param.s_blocks_count != s->s_blocks_count) | |
d9c56d3c | 493 | printf(_("warning: %d blocks unused.\n\n"), |
3839e657 | 494 | param.s_blocks_count - s->s_blocks_count); |
50787ea2 TT |
495 | |
496 | memset(buf, 0, sizeof(buf)); | |
497 | strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name)); | |
d9c56d3c TT |
498 | printf(_("Filesystem label=%s\n"), buf); |
499 | printf(_("OS type: ")); | |
1e3472c5 TT |
500 | switch (fs->super->s_creator_os) { |
501 | case EXT2_OS_LINUX: printf ("Linux"); break; | |
ad6783df | 502 | case EXT2_OS_HURD: printf ("GNU/Hurd"); break; |
1e3472c5 | 503 | case EXT2_OS_MASIX: printf ("Masix"); break; |
d9c56d3c | 504 | default: printf (_("(unknown os)")); |
1e3472c5 | 505 | } |
50787ea2 | 506 | printf("\n"); |
d9c56d3c | 507 | printf(_("Block size=%u (log=%u)\n"), fs->blocksize, |
50787ea2 | 508 | s->s_log_block_size); |
d9c56d3c | 509 | printf(_("Fragment size=%u (log=%u)\n"), fs->fragsize, |
50787ea2 | 510 | s->s_log_frag_size); |
d9c56d3c | 511 | printf(_("%u inodes, %u blocks\n"), s->s_inodes_count, |
3839e657 | 512 | s->s_blocks_count); |
d9c56d3c | 513 | printf(_("%u blocks (%2.2f%%) reserved for the super user\n"), |
3839e657 TT |
514 | s->s_r_blocks_count, |
515 | 100.0 * s->s_r_blocks_count / s->s_blocks_count); | |
d9c56d3c TT |
516 | printf(_("First data block=%u\n"), s->s_first_data_block); |
517 | if (fs->group_desc_count > 1) | |
c8c071a0 | 518 | printf(_("%u block groups\n"), fs->group_desc_count); |
d9c56d3c | 519 | else |
c8c071a0 | 520 | printf(_("%u block group\n"), fs->group_desc_count); |
d9c56d3c | 521 | printf(_("%u blocks per group, %u fragments per group\n"), |
3839e657 | 522 | s->s_blocks_per_group, s->s_frags_per_group); |
d9c56d3c | 523 | printf(_("%u inodes per group\n"), s->s_inodes_per_group); |
3839e657 TT |
524 | |
525 | if (fs->group_desc_count == 1) { | |
526 | printf("\n"); | |
527 | return; | |
528 | } | |
529 | ||
d9c56d3c | 530 | printf(_("Superblock backups stored on blocks: ")); |
3839e657 TT |
531 | group_block = s->s_first_data_block; |
532 | col_left = 0; | |
533 | for (i = 1; i < fs->group_desc_count; i++) { | |
534 | group_block += s->s_blocks_per_group; | |
521e3685 TT |
535 | if (!ext2fs_bg_has_super(fs, i)) |
536 | continue; | |
7671433a TT |
537 | if (i != 1) |
538 | printf(", "); | |
6733c2fd | 539 | need = int_log10(group_block) + 2; |
1dde43f0 | 540 | if (need > col_left) { |
3839e657 | 541 | printf("\n\t"); |
1dde43f0 | 542 | col_left = 72; |
3839e657 | 543 | } |
1dde43f0 | 544 | col_left -= need; |
a418d3ad | 545 | printf("%u", group_block); |
3839e657 TT |
546 | } |
547 | printf("\n\n"); | |
548 | } | |
549 | ||
1e3472c5 TT |
550 | /* |
551 | * Set the S_CREATOR_OS field. Return true if OS is known, | |
552 | * otherwise, 0. | |
553 | */ | |
554 | static int set_os(struct ext2_super_block *sb, char *os) | |
555 | { | |
556 | if (isdigit (*os)) | |
557 | sb->s_creator_os = atoi (os); | |
558 | else if (strcasecmp(os, "linux") == 0) | |
559 | sb->s_creator_os = EXT2_OS_LINUX; | |
560 | else if (strcasecmp(os, "GNU") == 0 || strcasecmp(os, "hurd") == 0) | |
561 | sb->s_creator_os = EXT2_OS_HURD; | |
562 | else if (strcasecmp(os, "masix") == 0) | |
563 | sb->s_creator_os = EXT2_OS_MASIX; | |
564 | else | |
565 | return 0; | |
566 | return 1; | |
567 | } | |
568 | ||
a418d3ad TT |
569 | #define PATH_SET "PATH=/sbin" |
570 | ||
d163b094 | 571 | static void parse_raid_opts(const char *opts) |
a29f4d30 TT |
572 | { |
573 | char *buf, *token, *next, *p, *arg; | |
574 | int len; | |
575 | int raid_usage = 0; | |
576 | ||
577 | len = strlen(opts); | |
578 | buf = malloc(len+1); | |
579 | if (!buf) { | |
d9c56d3c TT |
580 | fprintf(stderr, _("Couldn't allocate memory to parse " |
581 | "raid options!\n")); | |
a29f4d30 TT |
582 | exit(1); |
583 | } | |
584 | strcpy(buf, opts); | |
585 | for (token = buf; token && *token; token = next) { | |
586 | p = strchr(token, ','); | |
587 | next = 0; | |
588 | if (p) { | |
589 | *p = 0; | |
590 | next = p+1; | |
591 | } | |
592 | arg = strchr(token, '='); | |
593 | if (arg) { | |
594 | *arg = 0; | |
595 | arg++; | |
596 | } | |
597 | if (strcmp(token, "stride") == 0) { | |
598 | if (!arg) { | |
599 | raid_usage++; | |
600 | continue; | |
601 | } | |
602 | fs_stride = strtoul(arg, &p, 0); | |
603 | if (*p || (fs_stride == 0)) { | |
d9c56d3c TT |
604 | fprintf(stderr, |
605 | _("Invalid stride parameter.\n")); | |
a29f4d30 TT |
606 | raid_usage++; |
607 | continue; | |
608 | } | |
609 | } else | |
610 | raid_usage++; | |
611 | } | |
612 | if (raid_usage) { | |
d9c56d3c | 613 | fprintf(stderr, _("\nBad raid options specified.\n\n" |
a29f4d30 TT |
614 | "Raid options are separated by commas, " |
615 | "and may take an argument which\n" | |
616 | "\tis set off by an equals ('=') sign.\n\n" | |
617 | "Valid raid options are:\n" | |
d9c56d3c | 618 | "\tstride=<stride length in blocks>\n\n")); |
a29f4d30 TT |
619 | exit(1); |
620 | } | |
621 | } | |
622 | ||
896938d5 TT |
623 | static __u32 ok_features[3] = { |
624 | 0, /* Compat */ | |
625 | EXT2_FEATURE_INCOMPAT_FILETYPE, /* Incompat */ | |
626 | EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */ | |
627 | }; | |
a29f4d30 TT |
628 | |
629 | ||
3839e657 TT |
630 | static void PRS(int argc, char *argv[]) |
631 | { | |
4a600566 TT |
632 | int c; |
633 | int size; | |
634 | char * tmp; | |
80c22c90 | 635 | blk_t group_blk_max = 8192; |
4a600566 TT |
636 | int blocksize = 0; |
637 | int inode_ratio = 0; | |
638 | int reserved_ratio = 5; | |
dfcdc32f | 639 | ext2_ino_t num_inodes = 0; |
a418d3ad | 640 | errcode_t retval; |
f6f65832 | 641 | int sparse_option = 1; |
4a600566 | 642 | char * oldpath = getenv("PATH"); |
ef9abe5f | 643 | struct ext2_super_block *param_ext2 = ¶m; |
4a600566 | 644 | char * raid_opts = 0; |
8ddaa66b | 645 | char * journal_opts = 0; |
4a600566 | 646 | char * fs_type = 0; |
f6f65832 | 647 | const char * feature_set = "filetype"; |
4a600566 | 648 | blk_t dev_size; |
2740156b | 649 | #ifdef linux |
4a600566 | 650 | struct utsname ut; |
2740156b TT |
651 | |
652 | if (uname(&ut)) { | |
653 | perror("uname"); | |
654 | exit(1); | |
655 | } | |
896938d5 TT |
656 | if ((ut.release[0] == '1') || |
657 | (ut.release[0] == '2' && ut.release[1] == '.' && | |
658 | ut.release[2] < '2' && ut.release[3] == '.')) | |
80c22c90 | 659 | feature_set = NULL; |
2740156b | 660 | #endif |
3839e657 | 661 | /* Update our PATH to include /sbin */ |
a418d3ad TT |
662 | if (oldpath) { |
663 | char *newpath; | |
664 | ||
665 | newpath = malloc(sizeof (PATH_SET) + 1 + strlen (oldpath)); | |
666 | strcpy (newpath, PATH_SET); | |
667 | strcat (newpath, ":"); | |
668 | strcat (newpath, oldpath); | |
669 | putenv (newpath); | |
670 | } else | |
671 | putenv (PATH_SET); | |
3839e657 TT |
672 | |
673 | setbuf(stdout, NULL); | |
674 | setbuf(stderr, NULL); | |
675 | initialize_ext2_error_table(); | |
676 | memset(¶m, 0, sizeof(struct ext2_super_block)); | |
50787ea2 | 677 | param.s_rev_level = 1; /* Create revision 1 filesystems now */ |
3839e657 | 678 | |
d9c56d3c | 679 | fprintf (stderr, _("mke2fs %s, %s for EXT2 FS %s, %s\n"), |
3839e657 TT |
680 | E2FSPROGS_VERSION, E2FSPROGS_DATE, |
681 | EXT2FS_VERSION, EXT2FS_DATE); | |
682 | if (argc && *argv) | |
683 | program_name = *argv; | |
1e3472c5 | 684 | while ((c = getopt (argc, argv, |
85ef4ae8 | 685 | "b:cf:g:i:j:l:m:no:qr:R:s:tvI:ST:FL:M:N:O:V")) != EOF) |
3839e657 TT |
686 | switch (c) { |
687 | case 'b': | |
50787ea2 TT |
688 | blocksize = strtoul(optarg, &tmp, 0); |
689 | if (blocksize < 1024 || blocksize > 4096 || *tmp) { | |
d9c56d3c TT |
690 | com_err(program_name, 0, |
691 | _("bad block size - %s"), optarg); | |
3839e657 TT |
692 | exit(1); |
693 | } | |
694 | param.s_log_block_size = | |
6733c2fd | 695 | int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); |
80c22c90 | 696 | group_blk_max = blocksize * 8; |
3839e657 TT |
697 | break; |
698 | case 'c': | |
699 | case 't': /* Check for bad blocks */ | |
700 | cflag = 1; | |
701 | break; | |
702 | case 'f': | |
703 | size = strtoul(optarg, &tmp, 0); | |
704 | if (size < 1024 || size > 4096 || *tmp) { | |
d9c56d3c TT |
705 | com_err(program_name, 0, |
706 | _("bad fragment size - %s"), | |
3839e657 TT |
707 | optarg); |
708 | exit(1); | |
709 | } | |
710 | param.s_log_frag_size = | |
6733c2fd | 711 | int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE); |
d9c56d3c TT |
712 | printf(_("Warning: fragments not supported. " |
713 | "Ignoring -f option\n")); | |
3839e657 TT |
714 | break; |
715 | case 'g': | |
716 | param.s_blocks_per_group = strtoul(optarg, &tmp, 0); | |
f3db3566 TT |
717 | if (*tmp) { |
718 | com_err(program_name, 0, | |
d9c56d3c | 719 | _("Illegal number for blocks per group")); |
f3db3566 TT |
720 | exit(1); |
721 | } | |
f3db3566 TT |
722 | if ((param.s_blocks_per_group % 8) != 0) { |
723 | com_err(program_name, 0, | |
d9c56d3c | 724 | _("blocks per group must be multiple of 8")); |
3839e657 TT |
725 | exit(1); |
726 | } | |
727 | break; | |
728 | case 'i': | |
729 | inode_ratio = strtoul(optarg, &tmp, 0); | |
44c09c04 | 730 | if (inode_ratio < 1024 || inode_ratio > 4096 * 1024 || |
3839e657 | 731 | *tmp) { |
d9c56d3c TT |
732 | com_err(program_name, 0, |
733 | _("bad inode ratio - %s"), optarg); | |
3839e657 TT |
734 | exit(1); |
735 | } | |
736 | break; | |
85ef4ae8 | 737 | case 'j': |
8ddaa66b TT |
738 | journal_opts = optarg; |
739 | break; | |
3839e657 | 740 | case 'l': |
f3db3566 TT |
741 | bad_blocks_filename = malloc(strlen(optarg)+1); |
742 | if (!bad_blocks_filename) { | |
743 | com_err(program_name, ENOMEM, | |
d9c56d3c | 744 | _("in malloc for bad_blocks_filename")); |
f3db3566 TT |
745 | exit(1); |
746 | } | |
747 | strcpy(bad_blocks_filename, optarg); | |
3839e657 TT |
748 | break; |
749 | case 'm': | |
750 | reserved_ratio = strtoul(optarg, &tmp, 0); | |
751 | if (reserved_ratio > 50 || *tmp) { | |
752 | com_err(program_name, 0, | |
d9c56d3c | 753 | _("bad reserved blocks percent - %s"), |
3839e657 TT |
754 | optarg); |
755 | exit(1); | |
756 | } | |
757 | break; | |
50787ea2 TT |
758 | case 'n': |
759 | noaction++; | |
760 | break; | |
1e3472c5 TT |
761 | case 'o': |
762 | creator_os = optarg; | |
763 | break; | |
7f88b043 TT |
764 | case 'r': |
765 | param.s_rev_level = atoi(optarg); | |
766 | break; | |
521e3685 TT |
767 | case 's': |
768 | sparse_option = atoi(optarg); | |
769 | break; | |
7f88b043 TT |
770 | #ifdef EXT2_DYNAMIC_REV |
771 | case 'I': | |
772 | param.s_inode_size = atoi(optarg); | |
773 | break; | |
774 | #endif | |
5515e6b4 TT |
775 | case 'N': |
776 | num_inodes = atoi(optarg); | |
777 | break; | |
3839e657 TT |
778 | case 'v': |
779 | verbose = 1; | |
780 | break; | |
781 | case 'q': | |
782 | quiet = 1; | |
783 | break; | |
74becf3c TT |
784 | case 'F': |
785 | force = 1; | |
786 | break; | |
1e3472c5 TT |
787 | case 'L': |
788 | volume_label = optarg; | |
789 | break; | |
790 | case 'M': | |
791 | mount_dir = optarg; | |
792 | break; | |
896938d5 TT |
793 | case 'O': |
794 | feature_set = optarg; | |
795 | break; | |
a29f4d30 TT |
796 | case 'R': |
797 | raid_opts = optarg; | |
798 | break; | |
f3db3566 TT |
799 | case 'S': |
800 | super_only = 1; | |
801 | break; | |
50787ea2 TT |
802 | case 'T': |
803 | fs_type = optarg; | |
804 | break; | |
818180cd TT |
805 | case 'V': |
806 | /* Print version number and exit */ | |
d9c56d3c | 807 | fprintf(stderr, _("\tUsing %s\n"), |
818180cd TT |
808 | error_message(EXT2_ET_BASE)); |
809 | exit(0); | |
3839e657 TT |
810 | default: |
811 | usage(); | |
812 | } | |
813 | if (optind == argc) | |
814 | usage(); | |
815 | device_name = argv[optind]; | |
816 | optind++; | |
817 | if (optind < argc) { | |
e1a0a3e3 TT |
818 | unsigned long tmp2 = strtoul(argv[optind++], &tmp, 0); |
819 | ||
820 | if ((*tmp) || (tmp2 > 0xfffffffful)) { | |
d9c56d3c | 821 | com_err(program_name, 0, _("bad blocks count - %s"), |
3839e657 TT |
822 | argv[optind - 1]); |
823 | exit(1); | |
824 | } | |
e1a0a3e3 | 825 | param.s_blocks_count = tmp2; |
3839e657 TT |
826 | } |
827 | if (optind < argc) | |
828 | usage(); | |
a418d3ad | 829 | |
a29f4d30 TT |
830 | if (raid_opts) |
831 | parse_raid_opts(raid_opts); | |
832 | ||
8ddaa66b TT |
833 | if (journal_opts) |
834 | parse_journal_opts(journal_opts); | |
835 | ||
74becf3c | 836 | if (!force) |
8ddaa66b | 837 | check_plausibility(device_name); |
63985320 | 838 | check_mount(device_name, force, _("filesystem")); |
a418d3ad | 839 | |
3839e657 TT |
840 | param.s_log_frag_size = param.s_log_block_size; |
841 | ||
50787ea2 TT |
842 | if (noaction && param.s_blocks_count) { |
843 | dev_size = param.s_blocks_count; | |
844 | retval = 0; | |
845 | } else | |
846 | retval = ext2fs_get_device_size(device_name, | |
847 | EXT2_BLOCK_SIZE(¶m), | |
848 | &dev_size); | |
a789d840 TT |
849 | if (retval && (retval != EXT2_ET_UNIMPLEMENTED)) { |
850 | com_err(program_name, retval, | |
d9c56d3c | 851 | _("while trying to determine filesystem size")); |
a789d840 TT |
852 | exit(1); |
853 | } | |
a418d3ad | 854 | if (!param.s_blocks_count) { |
a789d840 TT |
855 | if (retval == EXT2_ET_UNIMPLEMENTED) { |
856 | com_err(program_name, 0, | |
d9c56d3c | 857 | _("Couldn't determine device size; you " |
a789d840 | 858 | "must specify\nthe size of the " |
d9c56d3c | 859 | "filesystem\n")); |
a418d3ad | 860 | exit(1); |
26ab5315 TT |
861 | } else { |
862 | if (dev_size == 0) { | |
863 | com_err(program_name, 0, | |
864 | _("Device size reported to be zero. " | |
865 | "Invalid partition specified, or\n\t" | |
866 | "partition table wasn't reread " | |
867 | "after running fdisk, due to\n\t" | |
868 | "a modified partition being busy " | |
869 | "and in use. You may need to reboot\n\t" | |
870 | "to re-read your partition table.\n" | |
871 | )); | |
872 | exit(1); | |
873 | } | |
a789d840 | 874 | param.s_blocks_count = dev_size; |
26ab5315 TT |
875 | } |
876 | ||
a789d840 TT |
877 | } else if (!force && (param.s_blocks_count > dev_size)) { |
878 | com_err(program_name, 0, | |
d9c56d3c | 879 | _("Filesystem larger than apparent filesystem size.")); |
a789d840 | 880 | proceed_question(); |
a418d3ad | 881 | } |
3839e657 | 882 | |
50787ea2 TT |
883 | set_fs_defaults(fs_type, param_ext2, blocksize, &inode_ratio); |
884 | ||
521e3685 TT |
885 | if (param.s_blocks_per_group) { |
886 | if (param.s_blocks_per_group < 256 || | |
80c22c90 | 887 | param.s_blocks_per_group > group_blk_max || *tmp) { |
521e3685 | 888 | com_err(program_name, 0, |
d9c56d3c | 889 | _("blocks per group count out of range")); |
521e3685 TT |
890 | exit(1); |
891 | } | |
892 | } | |
893 | ||
3839e657 TT |
894 | /* |
895 | * Calculate number of inodes based on the inode ratio | |
896 | */ | |
5515e6b4 | 897 | param.s_inodes_count = num_inodes ? num_inodes : |
e6597048 | 898 | ((__u64) param.s_blocks_count * EXT2_BLOCK_SIZE(¶m)) |
f3db3566 | 899 | / inode_ratio; |
3839e657 TT |
900 | |
901 | /* | |
902 | * Calculate number of blocks to reserve | |
903 | */ | |
904 | param.s_r_blocks_count = (param.s_blocks_count * reserved_ratio) / 100; | |
521e3685 | 905 | |
f6f65832 TT |
906 | /* Turn off features not supported by the earlier filesystem version */ |
907 | if (param.s_rev_level == 0) { | |
908 | sparse_option = 0; | |
909 | feature_set = NULL; | |
910 | } | |
2740156b | 911 | if (sparse_option) |
521e3685 TT |
912 | param_ext2->s_feature_ro_compat |= |
913 | EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; | |
f6f65832 | 914 | |
896938d5 | 915 | if (feature_set && !strncasecmp(feature_set, "none", 4)) |
80c22c90 | 916 | feature_set = NULL; |
896938d5 TT |
917 | if (feature_set && e2p_edit_feature(feature_set, |
918 | ¶m_ext2->s_feature_compat, | |
919 | ok_features)) { | |
d9c56d3c | 920 | fprintf(stderr, _("Invalid filesystem option set: %s\n"), |
896938d5 TT |
921 | feature_set); |
922 | exit(1); | |
923 | } | |
3839e657 TT |
924 | } |
925 | ||
926 | int main (int argc, char *argv[]) | |
927 | { | |
928 | errcode_t retval = 0; | |
929 | ext2_filsys fs; | |
930 | badblocks_list bb_list = 0; | |
85ef4ae8 | 931 | int journal_blocks; |
44c09c04 | 932 | int i, val; |
d9c56d3c TT |
933 | |
934 | #ifdef ENABLE_NLS | |
935 | setlocale(LC_MESSAGES, ""); | |
936 | bindtextdomain(NLS_CAT_NAME, LOCALEDIR); | |
937 | textdomain(NLS_CAT_NAME); | |
938 | #endif | |
3839e657 TT |
939 | PRS(argc, argv); |
940 | ||
3839e657 TT |
941 | /* |
942 | * Initialize the superblock.... | |
943 | */ | |
944 | retval = ext2fs_initialize(device_name, 0, ¶m, | |
945 | unix_io_manager, &fs); | |
946 | if (retval) { | |
d9c56d3c | 947 | com_err(device_name, retval, _("while setting up superblock")); |
3839e657 TT |
948 | exit(1); |
949 | } | |
950 | ||
e41784eb TT |
951 | /* |
952 | * Wipe out the old on-disk superblock | |
953 | */ | |
954 | zap_sector(fs, 2); | |
955 | ||
1e3472c5 TT |
956 | /* |
957 | * Generate a UUID for it... | |
958 | */ | |
ef9abe5f | 959 | uuid_generate(fs->super->s_uuid); |
1e3472c5 | 960 | |
44c09c04 TT |
961 | /* |
962 | * Add "jitter" to the superblock's check interval so that we | |
963 | * don't check all the filesystems at the same time. We use a | |
964 | * kludgy hack of using the UUID to derive a random jitter value. | |
965 | */ | |
966 | for (i = 0, val = 0 ; i < sizeof(fs->super->s_uuid); i++) | |
967 | val += fs->super->s_uuid[i]; | |
968 | fs->super->s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT; | |
969 | ||
1e3472c5 TT |
970 | /* |
971 | * Override the creator OS, if applicable | |
972 | */ | |
973 | if (creator_os && !set_os(fs->super, creator_os)) { | |
d9c56d3c | 974 | com_err (program_name, 0, _("unknown os - %s"), creator_os); |
1e3472c5 TT |
975 | exit(1); |
976 | } | |
977 | ||
4ea0a110 TT |
978 | /* |
979 | * For the Hurd, we will turn off filetype since it doesn't | |
980 | * support it. | |
981 | */ | |
982 | if (fs->super->s_creator_os == EXT2_OS_HURD) | |
983 | fs->super->s_feature_incompat &= | |
984 | ~EXT2_FEATURE_INCOMPAT_FILETYPE; | |
985 | ||
1e3472c5 TT |
986 | /* |
987 | * Set the volume label... | |
988 | */ | |
989 | if (volume_label) { | |
ef9abe5f TT |
990 | memset(fs->super->s_volume_name, 0, |
991 | sizeof(fs->super->s_volume_name)); | |
992 | strncpy(fs->super->s_volume_name, volume_label, | |
993 | sizeof(fs->super->s_volume_name)); | |
1e3472c5 TT |
994 | } |
995 | ||
996 | /* | |
997 | * Set the last mount directory | |
998 | */ | |
999 | if (mount_dir) { | |
ef9abe5f TT |
1000 | memset(fs->super->s_last_mounted, 0, |
1001 | sizeof(fs->super->s_last_mounted)); | |
1002 | strncpy(fs->super->s_last_mounted, mount_dir, | |
1003 | sizeof(fs->super->s_last_mounted)); | |
1e3472c5 TT |
1004 | } |
1005 | ||
50787ea2 | 1006 | if (!quiet || noaction) |
3839e657 TT |
1007 | show_stats(fs); |
1008 | ||
50787ea2 TT |
1009 | if (noaction) |
1010 | exit(0); | |
1011 | ||
3839e657 TT |
1012 | if (bad_blocks_filename) |
1013 | read_bb_file(fs, &bb_list, bad_blocks_filename); | |
1014 | if (cflag) | |
1015 | test_disk(fs, &bb_list); | |
1016 | ||
1017 | handle_bad_blocks(fs, bb_list); | |
a29f4d30 | 1018 | fs->stride = fs_stride; |
19c78dc0 TT |
1019 | retval = ext2fs_allocate_tables(fs); |
1020 | if (retval) { | |
1021 | com_err(program_name, retval, | |
d9c56d3c | 1022 | _("while trying to allocate filesystem tables")); |
19c78dc0 TT |
1023 | exit(1); |
1024 | } | |
f3db3566 TT |
1025 | if (super_only) { |
1026 | fs->super->s_state |= EXT2_ERROR_FS; | |
1027 | fs->flags &= ~(EXT2_FLAG_IB_DIRTY|EXT2_FLAG_BB_DIRTY); | |
1028 | } else { | |
19c78dc0 | 1029 | write_inode_tables(fs); |
f3db3566 TT |
1030 | create_root_dir(fs); |
1031 | create_lost_and_found(fs); | |
1032 | reserve_inodes(fs); | |
1033 | create_bad_block_inode(fs, bb_list); | |
1e3472c5 | 1034 | #ifdef ZAP_BOOTBLOCK |
e41784eb | 1035 | zap_sector(fs, 0); |
1e3472c5 | 1036 | #endif |
f3db3566 | 1037 | } |
8ddaa66b | 1038 | |
d48755e9 | 1039 | journal_blocks = journal_size * 1024 / (fs->blocksize / 1024); |
8ddaa66b TT |
1040 | if (journal_device) { |
1041 | if (!force) | |
1042 | check_plausibility(journal_device); | |
63985320 | 1043 | check_mount(journal_device, force, _("journal")); |
8ddaa66b TT |
1044 | |
1045 | if (!quiet) | |
1046 | printf(_("Creating journal on device %s: "), | |
1047 | journal_device); | |
d48755e9 TT |
1048 | retval = ext2fs_add_journal_device(fs, journal_device, |
1049 | journal_blocks, | |
1050 | journal_flags); | |
8ddaa66b TT |
1051 | if(retval) { |
1052 | com_err (program_name, retval, | |
1053 | _("while trying to create journal on device %s"), | |
1054 | journal_device); | |
1055 | exit(1); | |
1056 | } | |
1057 | if (!quiet) | |
1058 | printf(_("done\n")); | |
1059 | } else if (journal_size) { | |
85ef4ae8 | 1060 | if (!quiet) |
16ad3334 TT |
1061 | printf(_("Creating journal (%d blocks): "), |
1062 | journal_blocks); | |
63985320 TT |
1063 | retval = ext2fs_add_journal_inode(fs, journal_blocks, |
1064 | journal_flags); | |
85ef4ae8 TT |
1065 | if (retval) { |
1066 | com_err (program_name, retval, | |
1067 | _("while trying to create journal")); | |
1068 | exit(1); | |
1069 | } | |
1070 | if (!quiet) | |
1071 | printf(_("done\n")); | |
1072 | } | |
3839e657 TT |
1073 | |
1074 | if (!quiet) | |
d9c56d3c TT |
1075 | printf(_("Writing superblocks and " |
1076 | "filesystem accounting information: ")); | |
5d45d803 TT |
1077 | retval = ext2fs_flush(fs); |
1078 | if (retval) { | |
d9c56d3c | 1079 | printf(_("\nWarning, had trouble writing out superblocks.")); |
5d45d803 | 1080 | } |
3839e657 | 1081 | if (!quiet) |
d9c56d3c | 1082 | printf(_("done\n")); |
5d45d803 | 1083 | ext2fs_close(fs); |
3839e657 TT |
1084 | return 0; |
1085 | } |