X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=misc%2Fmke2fs.c;h=f0183ed0ea03311ce9aebf7e00998e67b7fa1a52;hb=5e804b72b66c04eb597fc9f6a45226eb8e71eccd;hp=92f3463d4b93c8cba648006a5f23c32f750a2e52;hpb=6a525069a99787ef3ae1156f12230044b3568f4b;p=tools%2Fe2fsprogs.git diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 92f3463..f0183ed 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 @@ -84,6 +84,8 @@ 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] " @@ -125,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,8 +140,8 @@ struct mke2fs_defaults { { 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}, }; @@ -150,8 +153,7 @@ static void set_fs_defaults(const char *fs_type, 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(const char *fs_type, (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(const char *fs_type, */ 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"); @@ -399,10 +404,9 @@ static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num, if (next_update_incr < 1) next_update_incr = 1; for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { - if (num-j > STRIDE_LENGTH) + count = num - j; + if (count > STRIDE_LENGTH) count = STRIDE_LENGTH; - else - count = num - j; retval = io_channel_write_blk(fs->io, blk, count, buf); if (retval) { if (ret_count) @@ -440,9 +444,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) { @@ -550,10 +554,15 @@ static void reserve_inodes(ext2_filsys fs) ext2fs_mark_ib_dirty(fs); } +#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; int retval; + unsigned int *magic; buf = malloc(512*nsect); if (!buf) { @@ -561,15 +570,30 @@ static void zap_sector(ext2_filsys fs, int sect, int nsect) sect, sect + nsect - 1); exit(1); } + + 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*nsect); - io_channel_set_blksize(fs->io, 512); 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) @@ -622,7 +646,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)); @@ -753,9 +777,11 @@ static void parse_raid_opts(const char *opts) } static __u32 ok_features[3] = { - EXT3_FEATURE_COMPAT_HAS_JOURNAL, /* Compat */ + EXT3_FEATURE_COMPAT_HAS_JOURNAL | + EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */ EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */ - EXT3_FEATURE_INCOMPAT_JOURNAL_DEV, + EXT3_FEATURE_INCOMPAT_JOURNAL_DEV| + EXT2_FEATURE_INCOMPAT_META_BG, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */ }; @@ -765,9 +791,9 @@ static void PRS(int argc, char *argv[]) int c; int size; char * tmp; - 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; @@ -776,9 +802,10 @@ static void PRS(int argc, char *argv[]) const char * fs_type = 0; int default_features = 1; blk_t dev_size; -#ifdef linux +#ifdef __linux__ struct utsname ut; #endif + long sysval; /* Update our PATH to include /sbin */ if (oldpath) { @@ -795,6 +822,18 @@ 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); @@ -803,8 +842,11 @@ static void PRS(int argc, char *argv[]) param.s_rev_level = 1; /* Create revision 1 filesystems now */ param.s_feature_incompat |= EXT2_FEATURE_INCOMPAT_FILETYPE; param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - -#ifdef linux +#if 0 + param.s_feature_compat |= EXT2_FEATURE_COMPAT_DIR_INDEX; +#endif + +#ifdef __linux__ if (uname(&ut)) { perror("uname"); exit(1); @@ -820,29 +862,41 @@ static void PRS(int argc, char *argv[]) #endif fprintf (stderr, "mke2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); - if (argc && *argv) - program_name = *argv; + + 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: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': /* Check for bad blocks */ case 't': /* deprecated */ - cflag = 1; + 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); @@ -850,7 +904,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': @@ -868,10 +922,13 @@ 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; @@ -926,7 +983,12 @@ static void PRS(int argc, char *argv[]) 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': @@ -1023,6 +1085,18 @@ static void PRS(int argc, char *argv[]) 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"; @@ -1091,17 +1165,40 @@ static void PRS(int argc, char *argv[]) !journal_size) journal_size = -1; + /* Set first meta blockgroup via an environment variable */ + /* (this is mostly for debugging purposes) */ + if ((param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) && + ((tmp = getenv("MKE2FS_FIRST_META_BG")))) + param.s_first_meta_bg = atoi(tmp); + set_fs_defaults(fs_type, ¶m, blocksize, &inode_ratio); if (param.s_blocks_per_group) { if (param.s_blocks_per_group < 256 || - param.s_blocks_per_group > group_blk_max || *tmp) { + param.s_blocks_per_group > 8 * EXT2_BLOCK_SIZE(¶m)) { com_err(program_name, 0, _("blocks per group count out of range")); exit(1); } } + 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 */ @@ -1126,6 +1223,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 @@ -1153,6 +1251,12 @@ int main (int argc, char *argv[]) uuid_generate(fs->super->s_uuid); /* + * Initialize the directory index variables + */ + fs->super->s_def_hash_version = EXT2_HASH_TEA; + uuid_generate((unsigned char *) fs->super->s_hash_seed); + + /* * Add "jitter" to the superblock's check interval so that we * don't check all the filesystems at the same time. We use a * kludgy hack of using the UUID to derive a random jitter value. @@ -1250,9 +1354,8 @@ int main (int argc, char *argv[]) if (retval) { com_err(program_name, retval, - _("zeroing block %u at end of filesystem"), + _("while zeroing block %u at end of filesystem"), ret_blk); - exit(1); } write_inode_tables(fs); create_root_dir(fs); @@ -1323,7 +1426,8 @@ no_journal: "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\n"));