#include <fcntl.h>
#include <ctype.h>
#include <time.h>
-#ifdef linux
+#ifdef __linux__
#include <sys/utsname.h>
#endif
#ifdef HAVE_GETOPT_H
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] "
* 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;
{ 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)
(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);
}
*/
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;
}
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");
};
static void progress_init(struct progress_struct *progress,
- char *label,__u32 max)
+ const char *label,__u32 max)
{
int i;
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) {
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,
_("while expanding /lost+found"));
exit(1);
}
- }
+ }
}
static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list)
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)
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));
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;
char * oldpath = getenv("PATH");
char * raid_opts = 0;
- char * fs_type = 0;
+ 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) {
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);
param.s_feature_incompat |= EXT2_FEATURE_INCOMPAT_FILETYPE;
param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
-#ifdef linux
+#ifdef __linux__
if (uname(&ut)) {
perror("uname");
exit(1);
param.s_feature_ro_compat = 0;
}
#endif
- 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;
+ 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: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);
}
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':
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;
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':
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";
}
}
+ 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
*/
#ifdef ENABLE_NLS
setlocale(LC_MESSAGES, "");
+ setlocale(LC_CTYPE, "");
bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
textdomain(NLS_CAT_NAME);
#endif
/*
* Wipe out the old on-disk superblock
*/
- if (!noaction) {
- zap_sector(fs, 2);
- zap_sector(fs, 3);
- }
+ if (!noaction)
+ zap_sector(fs, 2, 6);
/*
* Generate a UUID for it...
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)
fs->super->s_state |= EXT2_ERROR_FS;
fs->flags &= ~(EXT2_FLAG_IB_DIRTY|EXT2_FLAG_BB_DIRTY);
} else {
- int rsv = 65536 / EXT2_BLOCK_SIZE(fs->super);
+ /* 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 = (blocks & ~(rsv - 1)) - rsv;
+ unsigned long start;
blk_t ret_blk;
#ifdef ZAP_BOOTBLOCK
- zap_sector(fs, 0);
+ 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 it is.
+ * as large as we think. Be careful with very small devices.
*/
- retval = zero_blocks(fs, start, blocks - start,
- NULL, &ret_blk, NULL);
+ 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"),
if (!quiet)
printf(_("done\n"));
ext2fs_close(jfs);
+ free(journal_device);
} else if (journal_size) {
journal_blocks = figure_journal_size(journal_size, fs);
"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"));
print_check_message(fs);
}
- ext2fs_close(fs);
- return 0;
+ val = ext2fs_close(fs);
+ return (retval || val) ? 1 : 0;
}