X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=misc%2Fmke2fs.c;h=562549615474cde67ec9ed86ff77d1faca25d2c0;hb=503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3;hp=a52d63242d3ec75aad7609f1322c9852f90df5cd;hpb=16ed5b3af43c72f60991222b9d7ab65cf53f203d;p=tools%2Fe2fsprogs.git diff --git a/misc/mke2fs.c b/misc/mke2fs.c index a52d632..5625496 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -20,7 +20,7 @@ #include #include #include -#ifdef linux +#ifdef __linux__ #include #endif #ifdef HAVE_GETOPT_H @@ -44,8 +44,7 @@ extern int optind; #include #include -#include - +#include "ext2fs/ext2_fs.h" #include "et/com_err.h" #include "uuid/uuid.h" #include "e2p/e2p.h" @@ -85,15 +84,16 @@ char *mount_dir; char *journal_device; int sync_kludge; /* Set using the MKE2FS_SYNC env. option */ +int sys_page_size = 4096; + static void usage(void) { fprintf(stderr, _("Usage: %s [-c|-t|-l filename] [-b block-size] " - "[-f fragment-size]\n\t[-i bytes-per-inode] [-j journal-options]" + "[-f fragment-size]\n\t[-i bytes-per-inode] [-j] [-J journal-options]" " [-N number-of-inodes]\n\t[-m reserved-blocks-percentage] " "[-o creator-os] [-g blocks-per-group]\n\t[-L volume-label] " "[-M last-mounted-directory] [-O feature[,...]]\n\t" - "[-r fs-revision] [-R raid_opts] [-s sparse-super-flag]\n\t" - "[-qvSV] device [blocks-count]\n"), + "[-r fs-revision] [-R raid_opts] [-qvSV] device [blocks-count]\n"), program_name); exit(1); } @@ -127,6 +127,7 @@ static int int_log10(unsigned int arg) * of zero meaning that it is the default parameter for the type. * Note that order is important in the table below. */ +#define DEF_MAX_BLOCKSIZE -1 static char default_str[] = "default"; struct mke2fs_defaults { const char *type; @@ -137,21 +138,22 @@ struct mke2fs_defaults { { default_str, 0, 4096, 8192 }, { default_str, 512, 1024, 4096 }, { default_str, 3, 1024, 8192 }, + { "journal", 0, 4096, 8192 }, { "news", 0, 4096, 4096 }, - { "largefile", 0, 4096, 1024 * 1024 }, - { "largefile4", 0, 4096, 4096 * 1024 }, + { "largefile", 0, DEF_MAX_BLOCKSIZE, 1024 * 1024 }, + { "largefile4", 0, DEF_MAX_BLOCKSIZE, 4096 * 1024 }, { 0, 0, 0, 0}, }; -static void set_fs_defaults(char *fs_type, struct ext2_super_block *super, +static void set_fs_defaults(const char *fs_type, + struct ext2_super_block *super, int blocksize, int *inode_ratio) { int megs; int ratio = 0; struct mke2fs_defaults *p; - megs = (super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / - 1024); + megs = super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / 1024; if (inode_ratio) ratio = *inode_ratio; if (!fs_type) @@ -164,8 +166,11 @@ static void set_fs_defaults(char *fs_type, struct ext2_super_block *super, (megs > p->size)) continue; if (ratio == 0) - *inode_ratio = p->inode_ratio; + *inode_ratio = p->inode_ratio < blocksize ? + blocksize : p->inode_ratio; if (blocksize == 0) { + if (p->blocksize == DEF_MAX_BLOCKSIZE) + p->blocksize = sys_page_size; super->s_log_frag_size = super->s_log_block_size = int_log2(p->blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); } @@ -179,7 +184,7 @@ static void set_fs_defaults(char *fs_type, struct ext2_super_block *super, */ static void invalid_block(ext2_filsys fs, blk_t blk) { - printf(_("Bad block %u out of range; ignored.\n"), blk); + fprintf(stderr, _("Bad block %u out of range; ignored.\n"), blk); return; } @@ -216,9 +221,9 @@ static void test_disk(ext2_filsys fs, badblocks_list *bb_list) errcode_t retval; char buf[1024]; - sprintf(buf, "badblocks -b %d %s%s %d", fs->blocksize, - quiet ? "" : "-s ", fs->device_name, - fs->super->s_blocks_count); + sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize, + quiet ? "" : "-s ", (cflag > 1) ? "-w " : "", + fs->device_name, fs->super->s_blocks_count); if (verbose) printf(_("Running command: %s\n"), buf); f = popen(buf, "r"); @@ -256,7 +261,7 @@ static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list) */ must_be_good = fs->super->s_first_data_block + 1 + fs->desc_blocks; for (i = fs->super->s_first_data_block; i <= must_be_good; i++) { - if (badblocks_list_test(bb_list, i)) { + if (ext2fs_badblocks_list_test(bb_list, i)) { fprintf(stderr, _("Block %d in primary " "superblock/group descriptor area bad.\n"), i); fprintf(stderr, _("Blocks %d through %d must be good " @@ -278,8 +283,8 @@ static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list) for (i = 1; i < fs->group_desc_count; i++) { group_bad = 0; for (j=0; j < fs->desc_blocks+1; j++) { - if (badblocks_list_test(bb_list, group_block + - j)) { + if (ext2fs_badblocks_list_test(bb_list, + group_block + j)) { if (!group_bad) fprintf(stderr, _("Warning: the backup superblock/group descriptors at block %d contain\n" @@ -297,15 +302,15 @@ _("Warning: the backup superblock/group descriptors at block %d contain\n" /* * Mark all the bad blocks as used... */ - retval = badblocks_list_iterate_begin(bb_list, &bb_iter); + retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter); if (retval) { - com_err("badblocks_list_iterate_begin", retval, + com_err("ext2fs_badblocks_list_iterate_begin", retval, _("while marking bad blocks as used")); exit(1); } - while (badblocks_list_iterate(bb_iter, &blk)) + while (ext2fs_badblocks_list_iterate(bb_iter, &blk)) ext2fs_mark_block_bitmap(fs->block_map, blk); - badblocks_list_iterate_end(bb_iter); + ext2fs_badblocks_list_iterate_end(bb_iter); } /* @@ -318,7 +323,7 @@ struct progress_struct { }; static void progress_init(struct progress_struct *progress, - char *label,__u32 max) + const char *label,__u32 max) { int i; @@ -440,9 +445,9 @@ static void write_inode_tables(ext2_filsys fs) retval = zero_blocks(fs, blk, num, 0, &blk, &num); if (retval) { - printf(_("\nCould not write %d blocks " - "in inode table starting at %d: %s\n"), - num, blk, error_message(retval)); + fprintf(stderr, _("\nCould not write %d blocks " + "in inode table starting at %d: %s\n"), + num, blk, error_message(retval)); exit(1); } if (sync_kludge) { @@ -493,6 +498,7 @@ static void create_lost_and_found(ext2_filsys fs) int i; int lpf_size = 0; + fs->umask = 077; retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name); if (retval) { com_err("ext2fs_mkdir", retval, @@ -516,7 +522,7 @@ static void create_lost_and_found(ext2_filsys fs) _("while expanding /lost+found")); exit(1); } - } + } } static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list) @@ -549,19 +555,46 @@ static void reserve_inodes(ext2_filsys fs) ext2fs_mark_ib_dirty(fs); } -static void zap_sector(ext2_filsys fs, int sect) +#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ +#define BSD_MAGICDISK (0x57455682UL) /* The disk magic number reversed */ +#define BSD_LABEL_OFFSET 64 + +static void zap_sector(ext2_filsys fs, int sect, int nsect) { - char buf[512]; + char *buf; int retval; + unsigned int *magic; + + buf = malloc(512*nsect); + if (!buf) { + printf(_("Out of memory erasing sectors %d-%d\n"), + sect, sect + nsect - 1); + exit(1); + } + memset(buf, 0, 512*nsect); + + if (sect == 0) { + /* Check for a BSD disklabel, and don't erase it if so */ + retval = io_channel_read_blk(fs->io, 0, -512, buf); + if (retval) + fprintf(stderr, + _("Warning: could not read block 0: %s\n"), + error_message(retval)); + else { + magic = (unsigned int *) (buf + BSD_LABEL_OFFSET); + if ((*magic == BSD_DISKMAGIC) || + (*magic == BSD_MAGICDISK)) + return; + } + } - memset(buf, 0, 512); - io_channel_set_blksize(fs->io, 512); - retval = io_channel_write_blk(fs->io, sect, -512, buf); + retval = io_channel_write_blk(fs->io, sect, -512*nsect, buf); io_channel_set_blksize(fs->io, fs->blocksize); + free(buf); if (retval) - printf(_("Warning: could not erase sector %d: %s\n"), sect, - error_message(retval)); + fprintf(stderr, _("Warning: could not erase sector %d: %s\n"), + sect, error_message(retval)); } static void create_journal_dev(ext2_filsys fs) @@ -569,32 +602,35 @@ static void create_journal_dev(ext2_filsys fs) struct progress_struct progress; errcode_t retval; char *buf; + blk_t blk; + int count; + retval = ext2fs_create_journal_superblock(fs, + fs->super->s_blocks_count, 0, &buf); + if (retval) { + com_err("create_journal_dev", retval, + _("while initializing journal superblock")); + exit(1); + } if (quiet) memset(&progress, 0, sizeof(progress)); else progress_init(&progress, _("Zeroing journal device: "), fs->super->s_blocks_count); -#if 0 retval = zero_blocks(fs, 0, fs->super->s_blocks_count, &progress, &blk, &count); if (retval) { com_err("create_journal_dev", retval, - "while zeroing journal device (block %u, count %d", + _("while zeroing journal device (block %u, count %d)"), blk, count); exit(1); } - zero_blocks(0, 0, 0, 0, 0); -#endif - retval = ext2fs_create_journal_superblock(fs, - fs->super->s_blocks_count, 0, &buf); - if (retval) { - com_err("create_journal_dev", retval, - _("while initialization journal superblock")); - exit(1); - } - retval = io_channel_write_blk(fs->io, 1, 1, buf); + zero_blocks(0, 0, 0, 0, 0, 0); + + retval = io_channel_write_blk(fs->io, + fs->super->s_first_data_block+1, + 1, buf); if (retval) { com_err("create_journal_dev", retval, _("while writing journal superblock")); @@ -611,7 +647,7 @@ static void show_stats(ext2_filsys fs) int i, need, col_left; if (param.s_blocks_count != s->s_blocks_count) - printf(_("warning: %d blocks unused.\n\n"), + fprintf(stderr, _("warning: %d blocks unused.\n\n"), param.s_blocks_count - s->s_blocks_count); memset(buf, 0, sizeof(buf)); @@ -742,7 +778,7 @@ static void parse_raid_opts(const char *opts) } static __u32 ok_features[3] = { - 0, /* Compat */ + EXT3_FEATURE_COMPAT_HAS_JOURNAL, /* Compat */ EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */ @@ -757,29 +793,20 @@ static void PRS(int argc, char *argv[]) blk_t group_blk_max = 8192; int blocksize = 0; int inode_ratio = 0; + int inode_size = 0; int reserved_ratio = 5; ext2_ino_t num_inodes = 0; errcode_t retval; - int sparse_option = 1; char * oldpath = getenv("PATH"); - struct ext2_super_block *param_ext2 = ¶m; char * raid_opts = 0; - char * journal_opts = 0; - char * fs_type = 0; - const char * feature_set = "filetype"; + const char * fs_type = 0; + int default_features = 1; blk_t dev_size; -#ifdef linux +#ifdef __linux__ struct utsname ut; - - if (uname(&ut)) { - perror("uname"); - exit(1); - } - if ((ut.release[0] == '1') || - (ut.release[0] == '2' && ut.release[1] == '.' && - ut.release[2] < '2' && ut.release[3] == '.')) - feature_set = NULL; #endif + long sysval; + /* Update our PATH to include /sbin */ if (oldpath) { char *newpath; @@ -795,39 +822,79 @@ static void PRS(int argc, char *argv[]) tmp = getenv("MKE2FS_SYNC"); if (tmp) sync_kludge = atoi(tmp); + + /* Determine the system page size if possible */ +#ifdef HAVE_SYSCONF +#if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE)) +#define _SC_PAGESIZE _SC_PAGE_SIZE +#endif +#ifdef _SC_PAGESIZE + sysval = sysconf(_SC_PAGESIZE); + if (sysval > 0) + sys_page_size = sysval; +#endif /* _SC_PAGESIZE */ +#endif /* HAVE_SYSCONF */ setbuf(stdout, NULL); setbuf(stderr, NULL); initialize_ext2_error_table(); memset(¶m, 0, sizeof(struct ext2_super_block)); param.s_rev_level = 1; /* Create revision 1 filesystems now */ - - fprintf (stderr, _("mke2fs %s, %s for EXT2 FS %s, %s\n"), - E2FSPROGS_VERSION, E2FSPROGS_DATE, - EXT2FS_VERSION, EXT2FS_DATE); - if (argc && *argv) - program_name = *argv; + param.s_feature_incompat |= EXT2_FEATURE_INCOMPAT_FILETYPE; + param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; + +#ifdef __linux__ + if (uname(&ut)) { + perror("uname"); + exit(1); + } + if ((ut.release[0] == '1') || + (ut.release[0] == '2' && ut.release[1] == '.' && + ut.release[2] < '2' && ut.release[3] == '.')) { + param.s_rev_level = 0; + param.s_feature_incompat = 0; + param.s_feature_compat = 0; + param.s_feature_ro_compat = 0; + } +#endif + fprintf (stderr, "mke2fs %s (%s)\n", + E2FSPROGS_VERSION, E2FSPROGS_DATE); + + if (argc && *argv) { + program_name = get_progname(*argv); + + /* If called as mkfs.ext3, create a journal inode */ + if (!strcmp(program_name, "mkfs.ext3")) + journal_size = -1; + } + while ((c = getopt (argc, argv, - "b:cf:g:i:j:l:m:no:qr:R:s:tvI:ST:FL:M:N:O:V")) != EOF) + "b:cf:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF) switch (c) { case 'b': blocksize = strtoul(optarg, &tmp, 0); - if (blocksize < 1024 || blocksize > 4096 || *tmp) { + if (blocksize < EXT2_MIN_BLOCK_SIZE || + blocksize > EXT2_MAX_BLOCK_SIZE || *tmp) { com_err(program_name, 0, _("bad block size - %s"), optarg); exit(1); } + if (blocksize > 4096) + fprintf(stderr, _("Warning: blocksize %d not " + "usable on most systems.\n"), + blocksize); param.s_log_block_size = int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); group_blk_max = blocksize * 8; break; - case 'c': - case 't': /* Check for bad blocks */ - cflag = 1; + case 'c': /* Check for bad blocks */ + case 't': /* deprecated */ + cflag++; break; case 'f': size = strtoul(optarg, &tmp, 0); - if (size < 1024 || size > 4096 || *tmp) { + if (size < EXT2_MIN_BLOCK_SIZE || + size > EXT2_MAX_BLOCK_SIZE || *tmp) { com_err(program_name, 0, _("bad fragment size - %s"), optarg); @@ -835,7 +902,7 @@ static void PRS(int argc, char *argv[]) } param.s_log_frag_size = int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE); - printf(_("Warning: fragments not supported. " + fprintf(stderr, _("Warning: fragments not supported. " "Ignoring -f option\n")); break; case 'g': @@ -853,15 +920,24 @@ static void PRS(int argc, char *argv[]) break; case 'i': inode_ratio = strtoul(optarg, &tmp, 0); - if (inode_ratio < 1024 || inode_ratio > 4096 * 1024 || + if (inode_ratio < EXT2_MIN_BLOCK_SIZE || + inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024 || *tmp) { com_err(program_name, 0, - _("bad inode ratio - %s"), optarg); + _("bad inode ratio %s (min %d/max %d"), + optarg, EXT2_MIN_BLOCK_SIZE, + EXT2_MAX_BLOCK_SIZE); exit(1); } break; + case 'J': + parse_journal_opts(optarg); + break; case 'j': - journal_opts = optarg; + param.s_feature_compat |= + EXT3_FEATURE_COMPAT_HAS_JOURNAL; + if (!journal_size) + journal_size = -1; break; case 'l': bad_blocks_filename = malloc(strlen(optarg)+1); @@ -889,13 +965,28 @@ static void PRS(int argc, char *argv[]) break; case 'r': param.s_rev_level = atoi(optarg); + if (param.s_rev_level == EXT2_GOOD_OLD_REV) { + param.s_feature_incompat = 0; + param.s_feature_compat = 0; + param.s_feature_ro_compat = 0; + } break; - case 's': - sparse_option = atoi(optarg); + case 's': /* deprecated */ + if (atoi(optarg)) + param.s_feature_ro_compat |= + EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; + else + param.s_feature_ro_compat &= + ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; break; #ifdef EXT2_DYNAMIC_REV case 'I': - param.s_inode_size = atoi(optarg); + inode_size = strtoul(optarg, &tmp, 0); + if (*tmp) { + com_err(program_name, 0, + _("bad inode size - %s"), optarg); + exit(1); + } break; #endif case 'N': @@ -917,7 +1008,21 @@ static void PRS(int argc, char *argv[]) mount_dir = optarg; break; case 'O': - feature_set = optarg; + if (!strcmp(optarg, "none") || default_features) { + param.s_feature_compat = 0; + param.s_feature_incompat = 0; + param.s_feature_ro_compat = 0; + default_features = 0; + } + if (!strcmp(optarg, "none")) + break; + if (e2p_edit_feature(optarg, + ¶m.s_feature_compat, + ok_features)) { + fprintf(stderr, + _("Invalid filesystem option set: %s\n"), optarg); + exit(1); + } break; case 'R': raid_opts = optarg; @@ -956,9 +1061,53 @@ static void PRS(int argc, char *argv[]) if (raid_opts) parse_raid_opts(raid_opts); - if (journal_opts) - parse_journal_opts(journal_opts); - + /* + * If there's no blocksize specified and there is a journal + * device, use it to figure out the blocksize + */ + if (blocksize == 0 && journal_device) { + ext2_filsys jfs; + + retval = ext2fs_open(journal_device, + EXT2_FLAG_JOURNAL_DEV_OK, 0, + 0, unix_io_manager, &jfs); + if (retval) { + com_err(program_name, retval, + _("while trying to open journal device %s\n"), + journal_device); + exit(1); + } + blocksize = jfs->blocksize; + param.s_log_block_size = + int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); + ext2fs_close(jfs); + } + + if (blocksize > sys_page_size) { + if (!force) { + com_err(program_name, 0, + _("%d-byte blocks too big for system (max %d)"), + blocksize, sys_page_size); + proceed_question(); + } + fprintf(stderr, _("Warning: %d-byte blocks too big for system " + "(max %d), forced to continue\n"), + blocksize, sys_page_size); + } + + if (param.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { + if (!fs_type) + fs_type = "journal"; + reserved_ratio = 0; + param.s_feature_incompat = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV; + param.s_feature_compat = 0; + param.s_feature_ro_compat = 0; + } + if (param.s_rev_level == EXT2_GOOD_OLD_REV && + (param.s_feature_compat || param.s_feature_ro_compat || + param.s_feature_incompat)) + param.s_rev_level = 1; /* Create a revision 1 filesystem */ + if (!force) check_plausibility(device_name); check_mount(device_name, force, _("filesystem")); @@ -1006,7 +1155,15 @@ static void PRS(int argc, char *argv[]) proceed_question(); } - set_fs_defaults(fs_type, param_ext2, blocksize, &inode_ratio); + /* + * If the user asked for HAS_JOURNAL, then make sure a journal + * gets created. + */ + if ((param.s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && + !journal_size) + journal_size = -1; + + set_fs_defaults(fs_type, ¶m, blocksize, &inode_ratio); if (param.s_blocks_per_group) { if (param.s_blocks_per_group < 256 || @@ -1017,6 +1174,23 @@ static void PRS(int argc, char *argv[]) } } + if (inode_size) { + if (inode_size < EXT2_GOOD_OLD_INODE_SIZE || + inode_size > EXT2_BLOCK_SIZE(¶m) || + inode_size & (inode_size - 1)) { + com_err(program_name, 0, + _("bad inode size %d (min %d/max %d)"), + inode_size, EXT2_GOOD_OLD_INODE_SIZE, + EXT2_BLOCK_SIZE(¶m)); + exit(1); + } + if (inode_size != EXT2_GOOD_OLD_INODE_SIZE) + fprintf(stderr, _("Warning: %d-byte inodes not usable " + "on most systems\n"), + inode_size); + param.s_inode_size = inode_size; + } + /* * Calculate number of inodes based on the inode ratio */ @@ -1029,24 +1203,6 @@ static void PRS(int argc, char *argv[]) */ param.s_r_blocks_count = (param.s_blocks_count * reserved_ratio) / 100; - /* Turn off features not supported by the earlier filesystem version */ - if (param.s_rev_level == 0) { - sparse_option = 0; - feature_set = NULL; - } - if (sparse_option) - param_ext2->s_feature_ro_compat |= - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - - if (feature_set && !strncasecmp(feature_set, "none", 4)) - feature_set = NULL; - if (feature_set && e2p_edit_feature(feature_set, - ¶m_ext2->s_feature_compat, - ok_features)) { - fprintf(stderr, _("Invalid filesystem option set: %s\n"), - feature_set); - exit(1); - } } int main (int argc, char *argv[]) @@ -1059,6 +1215,7 @@ int main (int argc, char *argv[]) #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); + setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif @@ -1077,7 +1234,8 @@ int main (int argc, char *argv[]) /* * Wipe out the old on-disk superblock */ - zap_sector(fs, 2); + if (!noaction) + zap_sector(fs, 2, 6); /* * Generate a UUID for it... @@ -1138,8 +1296,7 @@ int main (int argc, char *argv[]) if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { create_journal_dev(fs); - ext2fs_close(fs); - exit(0); + exit(ext2fs_close(fs) ? 1 : 0); } if (bad_blocks_filename) @@ -1159,17 +1316,41 @@ int main (int argc, char *argv[]) fs->super->s_state |= EXT2_ERROR_FS; fs->flags &= ~(EXT2_FLAG_IB_DIRTY|EXT2_FLAG_BB_DIRTY); } else { + /* rsv must be a power of two (64kB is MD RAID sb alignment) */ + int rsv = 65536 / fs->blocksize; + unsigned long blocks = fs->super->s_blocks_count; + unsigned long start; + blk_t ret_blk; + +#ifdef ZAP_BOOTBLOCK + zap_sector(fs, 0, 2); +#endif + + /* + * Wipe out any old MD RAID (or other) metadata at the end + * of the device. This will also verify that the device is + * as large as we think. Be careful with very small devices. + */ + start = (blocks & ~(rsv - 1)); + if (start > rsv) + start -= rsv; + if (start > 0) + retval = zero_blocks(fs, start, blocks - start, + NULL, &ret_blk, NULL); + + if (retval) { + com_err(program_name, retval, + _("zeroing block %u at end of filesystem"), + ret_blk); + exit(1); + } write_inode_tables(fs); create_root_dir(fs); create_lost_and_found(fs); reserve_inodes(fs); create_bad_block_inode(fs, bb_list); -#ifdef ZAP_BOOTBLOCK - zap_sector(fs, 0); -#endif } - journal_blocks = journal_size * 1024 / (fs->blocksize / 1024); if (journal_device) { ext2_filsys jfs; @@ -1186,43 +1367,59 @@ int main (int argc, char *argv[]) journal_device); exit(1); } - if (!quiet) - printf(_("Creating journal on device %s: "), + if (!quiet) { + printf(_("Adding journal to device %s: "), journal_device); + fflush(stdout); + } retval = ext2fs_add_journal_device(fs, jfs); if(retval) { com_err (program_name, retval, - _("while trying to add journal to device %s"), + _("\n\twhile trying to add journal to device %s"), journal_device); exit(1); } if (!quiet) printf(_("done\n")); ext2fs_close(jfs); + free(journal_device); } else if (journal_size) { - if (!quiet) + journal_blocks = figure_journal_size(journal_size, fs); + + if (!journal_blocks) { + fs->super->s_feature_compat &= + ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; + goto no_journal; + } + if (!quiet) { printf(_("Creating journal (%d blocks): "), journal_blocks); + fflush(stdout); + } retval = ext2fs_add_journal_inode(fs, journal_blocks, journal_flags); if (retval) { com_err (program_name, retval, - _("while trying to create journal")); + _("\n\twhile trying to create journal")); exit(1); } if (!quiet) printf(_("done\n")); } - +no_journal: + if (!quiet) printf(_("Writing superblocks and " "filesystem accounting information: ")); retval = ext2fs_flush(fs); if (retval) { - printf(_("\nWarning, had trouble writing out superblocks.")); + fprintf(stderr, + _("\nWarning, had trouble writing out superblocks.")); } - if (!quiet) - printf(_("done\n")); - ext2fs_close(fs); - return 0; + if (!quiet) { + printf(_("done\n\n")); + print_check_message(fs); + } + val = ext2fs_close(fs); + return (retval || val) ? 1 : 0; }