/*
 * mke2fs.c - Make a ext2fs filesystem.
 *
 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
 *	2003, 2004, 2005 by Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

/* Usage: mke2fs [options] device
 *
 * The device may be a block device or a image of one, but this isn't
 * enforced (but it's not much fun on a character device :-).
 */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <mntent.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include "e2fsbb.h"
#include "ext2fs/ext2_fs.h"
#include "uuid/uuid.h"
#include "e2p/e2p.h"
#include "ext2fs/ext2fs.h"
#include "util.h"

#define STRIDE_LENGTH 8

#ifndef __sparc__
#define ZAP_BOOTBLOCK
#endif

static const char * device_name /* = NULL */;

/* Command line options */
static int	cflag;
static int	quiet;
static int	super_only;
static int	force;
static int	noaction;
static int	journal_size;
static int	journal_flags;
static const char *bad_blocks_filename;
static __u32	fs_stride;

static struct ext2_super_block param;
static char *creator_os;
static char *volume_label;
static char *mount_dir;
static char *journal_device;
static int	sync_kludge; /* Set using the MKE2FS_SYNC env. option */

static int sys_page_size = 4096;
static int linux_version_code = 0;

static int int_log2(int arg)
{
	int	l = 0;

	arg >>= 1;
	while (arg) {
		l++;
		arg >>= 1;
	}
	return l;
}

static int int_log10(unsigned int arg)
{
	int	l;

	for (l=0; arg ; l++)
		arg = arg / 10;
	return l;
}

/*
 * This function sets the default parameters for a filesystem
 *
 * The type is specified by the user.  The size is the maximum size
 * (in megabytes) for which a set of parameters applies, with a 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 const char default_str[] = "default";
struct mke2fs_defaults {
	const char	*type;
	int		size;
	int		blocksize;
	int		inode_ratio;
};

static const struct mke2fs_defaults settings[] = {
	{ 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 },
	{ 0, 		 0,    0, 0},
};

static void set_fs_defaults(const char *fs_type,
			    struct ext2_super_block *super,
			    int blocksize, int sector_size,
			    int *inode_ratio)
{
	int	megs;
	int	ratio = 0;
	const struct mke2fs_defaults *p;
	int	use_bsize = 1024;

	megs = super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / 1024;
	if (inode_ratio)
		ratio = *inode_ratio;
	if (!fs_type)
		fs_type = default_str;
	for (p = settings; p->type; p++) {
		if ((strcmp(p->type, fs_type) != 0) &&
		    (strcmp(p->type, default_str) != 0))
			continue;
		if ((p->size != 0) && (megs > p->size))
			continue;
		if (ratio == 0)
			*inode_ratio = p->inode_ratio < blocksize ?
				blocksize : p->inode_ratio;
		use_bsize = p->blocksize;
	}
	if (blocksize <= 0) {
		if (use_bsize == DEF_MAX_BLOCKSIZE) {
			use_bsize = sys_page_size;
			if ((linux_version_code < (2*65536 + 6*256)) &&
			    (use_bsize > 4096))
				use_bsize = 4096;
		}
		if (sector_size && use_bsize < sector_size)
			use_bsize = sector_size;
		if ((blocksize < 0) && (use_bsize < (-blocksize)))
			use_bsize = -blocksize;
		blocksize = use_bsize;
		super->s_blocks_count /= blocksize / 1024;
	}
	super->s_log_frag_size = super->s_log_block_size =
		int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
}


/*
 * Helper function for read_bb_file and test_disk
 */
static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk)
{
	bb_error_msg("Bad block %u out of range; ignored", blk);
	return;
}

/*
 * Reads the bad blocks list from a file
 */
static void read_bb_file(ext2_filsys fs, badblocks_list *bb_list,
			 const char *bad_blocks_file)
{
	FILE		*f;
	errcode_t	retval;

	f = fopen(bad_blocks_file, "r");
	if (!f) {
		bb_perror_msg_and_die("Could not read bad blocks file %s", bad_blocks_file);
	}
	retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block);
	fclose (f);
	if (retval) {
		bb_error_msg_and_die("Could not read bad blocks list");
	}
}

/*
 * Runs the badblocks program to test the disk
 */
static void test_disk(ext2_filsys fs, badblocks_list *bb_list)
{
	FILE		*f;
	errcode_t	retval;
	char		buf[1024];

	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 (!quiet)
		printf("Running command: %s\n", buf);
	f = popen(buf, "r");
	if (!f) {
		bb_perror_msg_and_die("Could not run '%s'", buf);
	}
	retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block);
	pclose(f);
	if (retval) {
		bb_error_msg_and_die(
			"Could not get list of bad blocks from program");
	}
}

static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list)
{
	dgrp_t			i;
	blk_t			j;
	unsigned		must_be_good;
	blk_t			blk;
	badblocks_iterate	bb_iter;
	errcode_t		retval;
	blk_t			group_block;
	int			group;
	int			group_bad;

	if (!bb_list)
		return;

	/*
	 * The primary superblock and group descriptors *must* be
	 * good; if not, abort.
	 */
	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 (ext2fs_badblocks_list_test(bb_list, i)) {
			bb_error_msg_and_die(
				"Block %d in primary superblock/group descriptor area bad\n"
				"Blocks %d through %d must be good in order to build a filesystem\n"
				"Aborting ...", i, fs->super->s_first_data_block, must_be_good);
		}
	}

	/*
	 * See if any of the bad blocks are showing up in the backup
	 * superblocks and/or group descriptors.  If so, issue a
	 * warning and adjust the block counts appropriately.
	 */
	group_block = fs->super->s_first_data_block +
		fs->super->s_blocks_per_group;

	for (i = 1; i < fs->group_desc_count; i++) {
		group_bad = 0;
		for (j=0; j < fs->desc_blocks+1; j++) {
			if (ext2fs_badblocks_list_test(bb_list,
						       group_block + j)) {
				if (!group_bad)
					bb_error_msg(
						"Warning: the backup superblock/group descriptors at block %d contain\n"
						"       bad blocks\n", group_block);
				group_bad++;
				group = ext2fs_group_of_blk(fs, group_block+j);
				fs->group_desc[group].bg_free_blocks_count++;
				fs->super->s_free_blocks_count++;
			}
		}
		group_block += fs->super->s_blocks_per_group;
	}

	/*
	 * Mark all the bad blocks as used...
	 */
	retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter);
	if (retval) {
		bb_error_msg_and_die("while marking bad blocks as used");
	}
	while (ext2fs_badblocks_list_iterate(bb_iter, &blk))
		ext2fs_mark_block_bitmap(fs->block_map, blk);
	ext2fs_badblocks_list_iterate_end(bb_iter);
}

/*
 * These functions implement a generalized progress meter.
 */
struct progress_struct {
	char		format[20];
	char		backup[80];
	__u32		max;
	int		skip_progress;
};

static void progress_init(struct progress_struct *progress,
			  const char *label,__u32 max)
{
	int	i;

	memset(progress, 0, sizeof(struct progress_struct));
	if (quiet)
		return;

	/*
	 * Figure out how many digits we need
	 */
	i = int_log10(max);
	sprintf(progress->format, "%%%dd/%%%dld", i, i);
	memset(progress->backup, '\b', sizeof(progress->backup)-1);
	progress->backup[sizeof(progress->backup)-1] = 0;
	if ((2*i)+1 < (int) sizeof(progress->backup))
		progress->backup[(2*i)+1] = 0;
	progress->max = max;

	progress->skip_progress = 0;
	if (getenv("MKE2FS_SKIP_PROGRESS"))
		progress->skip_progress++;

	fputs(label, stdout);
	fflush(stdout);
}

static void progress_update(struct progress_struct *progress, __u32 val)
{
	if ((progress->format[0] == 0) || progress->skip_progress)
		return;
	printf(progress->format, val, progress->max);
	fputs(progress->backup, stdout);
}

static void progress_close(struct progress_struct *progress)
{
	if (progress->format[0] == 0)
		return;
	fputs("done                            \n", stdout);
}


/*
 * Helper function which zeros out _num_ blocks starting at _blk_.  In
 * case of an error, the details of the error is returned via _ret_blk_
 * and _ret_count_ if they are non-NULL pointers.  Returns 0 on
 * success, and an error code on an error.
 *
 * As a special case, if the first argument is NULL, then it will
 * attempt to free the static zeroizing buffer.  (This is to keep
 * programs that check for memory leaks happy.)
 */
static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num,
			     struct progress_struct *progress,
			     blk_t *ret_blk, int *ret_count)
{
	int		j, count, next_update, next_update_incr;
	static char	*buf;
	errcode_t	retval;

	/* If fs is null, clean up the static buffer and return */
	if (!fs) {
		if (buf) {
			free(buf);
			buf = 0;
		}
		return 0;
	}
	/* Allocate the zeroizing buffer if necessary */
	if (!buf) {
		buf = xcalloc(fs->blocksize, STRIDE_LENGTH);
	}
	/* OK, do the write loop */
	next_update = 0;
	next_update_incr = num / 100;
	if (next_update_incr < 1)
		next_update_incr = 1;
	for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
		count = num - j;
		if (count > STRIDE_LENGTH)
			count = STRIDE_LENGTH;
		retval = io_channel_write_blk(fs->io, blk, count, buf);
		if (retval) {
			if (ret_count)
				*ret_count = count;
			if (ret_blk)
				*ret_blk = blk;
			return retval;
		}
		if (progress && j > next_update) {
			next_update += num / 100;
			progress_update(progress, blk);
		}
	}
	return 0;
}

static void write_inode_tables(ext2_filsys fs)
{
	errcode_t	retval;
	blk_t		blk;
	dgrp_t		i;
	int		num;
	struct progress_struct progress;

	if (quiet)
		memset(&progress, 0, sizeof(progress));
	else
		progress_init(&progress, "Writing inode tables: ",
			      fs->group_desc_count);

	for (i = 0; i < fs->group_desc_count; i++) {
		progress_update(&progress, i);

		blk = fs->group_desc[i].bg_inode_table;
		num = fs->inode_blocks_per_group;

		retval = zero_blocks(fs, blk, num, 0, &blk, &num);
		if (retval) {
			bb_error_msg_and_die(
				"\nCould not write %d blocks "
				"in inode table starting at %d.",
				num, blk);
		}
		if (sync_kludge) {
			if (sync_kludge == 1)
				sync();
			else if ((i % sync_kludge) == 0)
				sync();
		}
	}
	zero_blocks(0, 0, 0, 0, 0, 0);
	progress_close(&progress);
}

static void create_root_dir(ext2_filsys fs)
{
	errcode_t		retval;
	struct ext2_inode	inode;

	retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0);
	if (retval) {
		bb_error_msg_and_die("Could not create root dir");
	}
	if (geteuid()) {
		retval = ext2fs_read_inode(fs, EXT2_ROOT_INO, &inode);
		if (retval) {
			bb_error_msg_and_die("Could not read root inode");
		}
		inode.i_uid = getuid();
		if (inode.i_uid)
			inode.i_gid = getgid();
		retval = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
		if (retval) {
			bb_error_msg_and_die("Could not set root inode ownership");
		}
	}
}

static void create_lost_and_found(ext2_filsys fs)
{
	errcode_t		retval;
	ext2_ino_t		ino;
	const char		*name = "lost+found";
	int			i;
	int			lpf_size = 0;

	fs->umask = 077;
	retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name);
	if (retval) {
		bb_error_msg_and_die("Could not create lost+found");
	}

	retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name, strlen(name), 0, &ino);
	if (retval) {
		bb_error_msg_and_die("Could not look up lost+found");
	}

	for (i=1; i < EXT2_NDIR_BLOCKS; i++) {
		if ((lpf_size += fs->blocksize) >= 16*1024)
			break;
		retval = ext2fs_expand_dir(fs, ino);
		if (retval) {
			bb_error_msg_and_die("Could not expand lost+found");
		}
	}
}

static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list)
{
	errcode_t	retval;

	ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_BAD_INO);
	fs->group_desc[0].bg_free_inodes_count--;
	fs->super->s_free_inodes_count--;
	retval = ext2fs_update_bb_inode(fs, bb_list);
	if (retval) {
		bb_error_msg_and_die("Could not set bad block inode");
	}

}

static void reserve_inodes(ext2_filsys fs)
{
	ext2_ino_t	i;
	int		group;

	for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->super); i++) {
		ext2fs_mark_inode_bitmap(fs->inode_map, i);
		group = ext2fs_group_of_ino(fs, i);
		fs->group_desc[group].bg_free_inodes_count--;
		fs->super->s_free_inodes_count--;
	}
	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 = xmalloc(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)
			bb_error_msg("Warning: could not read block 0");
		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)
		bb_error_msg("Warning: could not erase sector %d", sect);
}

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) {
		bb_error_msg_and_die("Could not init journal superblock");
	}
	if (quiet)
		memset(&progress, 0, sizeof(progress));
	else
		progress_init(&progress, "Zeroing journal device: ",
			      fs->super->s_blocks_count);

	retval = zero_blocks(fs, 0, fs->super->s_blocks_count,
			     &progress, &blk, &count);
	if (retval) {
		bb_error_msg_and_die("Could not zero journal device (block %u, count %d)",
			blk, count);
	}
	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) {
		bb_error_msg_and_die("Could not write journal superblock");
	}
	progress_close(&progress);
}

static void show_stats(ext2_filsys fs)
{
	struct ext2_super_block *s = fs->super;
	char			buf[80];
	char			*os;
	blk_t			group_block;
	dgrp_t			i;
	int			need, col_left;

	if (param.s_blocks_count != s->s_blocks_count)
		bb_error_msg("warning: %d blocks unused\n",
		       param.s_blocks_count - s->s_blocks_count);

	memset(buf, 0, sizeof(buf));
	strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
	printf("Filesystem label=%s\n", buf);
	fputs("OS type: ", stdout);
	os = e2p_os2string(fs->super->s_creator_os);
	fputs(os, stdout);
	free(os);
	printf("\nBlock size=%u (log=%u)\n", fs->blocksize,
		s->s_log_block_size);
	printf("Fragment size=%u (log=%u)\n", fs->fragsize,
		s->s_log_frag_size);
	printf("%u inodes, %u blocks\n", s->s_inodes_count,
	       s->s_blocks_count);
	printf("%u blocks (%2.2f%%) reserved for the super user\n",
		s->s_r_blocks_count,
	       100.0 * s->s_r_blocks_count / s->s_blocks_count);
	printf("First data block=%u\n", s->s_first_data_block);
	if (s->s_reserved_gdt_blocks)
		printf("Maximum filesystem blocks=%lu\n",
		       (s->s_reserved_gdt_blocks + fs->desc_blocks) *
		       (fs->blocksize / sizeof(struct ext2_group_desc)) *
		       s->s_blocks_per_group);
	if (fs->group_desc_count > 1)
		printf("%u block groups\n", fs->group_desc_count);
	else
		printf("%u block group\n", fs->group_desc_count);
	printf("%u blocks per group, %u fragments per group\n",
	       s->s_blocks_per_group, s->s_frags_per_group);
	printf("%u inodes per group\n", s->s_inodes_per_group);

	if (fs->group_desc_count == 1) {
		printf("\n");
		return;
	}

	printf("Superblock backups stored on blocks: ");
	group_block = s->s_first_data_block;
	col_left = 0;
	for (i = 1; i < fs->group_desc_count; i++) {
		group_block += s->s_blocks_per_group;
		if (!ext2fs_bg_has_super(fs, i))
			continue;
		if (i != 1)
			printf(", ");
		need = int_log10(group_block) + 2;
		if (need > col_left) {
			printf("\n\t");
			col_left = 72;
		}
		col_left -= need;
		printf("%u", group_block);
	}
	printf("\n\n");
}

/*
 * Set the S_CREATOR_OS field.  Return true if OS is known,
 * otherwise, 0.
 */
static int set_os(struct ext2_super_block *sb, char *os)
{
	if (isdigit (*os))
		sb->s_creator_os = atoi (os);
	else if (strcasecmp(os, "linux") == 0)
		sb->s_creator_os = EXT2_OS_LINUX;
	else if (strcasecmp(os, "GNU") == 0 || strcasecmp(os, "hurd") == 0)
		sb->s_creator_os = EXT2_OS_HURD;
	else if (strcasecmp(os, "masix") == 0)
		sb->s_creator_os = EXT2_OS_MASIX;
	else if (strcasecmp(os, "freebsd") == 0)
		sb->s_creator_os = EXT2_OS_FREEBSD;
	else if (strcasecmp(os, "lites") == 0)
		sb->s_creator_os = EXT2_OS_LITES;
	else
		return 0;

	return 1;
}

#define PATH_SET "PATH=/sbin"

static void parse_extended_opts(struct ext2_super_block *sb_param,
				const char *opts)
{
	char	*buf, *token, *next, *p, *arg;
	int	r_usage = 0;

	buf = bb_xstrdup(opts);
	for (token = buf; token && *token; token = next) {
		p = strchr(token, ',');
		next = 0;
		if (p) {
			*p = 0;
			next = p+1;
		}
		arg = strchr(token, '=');
		if (arg) {
			*arg = 0;
			arg++;
		}
		if (strcmp(token, "stride") == 0) {
			if (!arg) {
				r_usage++;
				continue;
			}
			fs_stride = strtoul(arg, &p, 0);
			if (*p || (fs_stride == 0)) {
				bb_error_msg("Invalid stride parameter");
				r_usage++;
				continue;
			}
		} else if (!strcmp(token, "resize")) {
			unsigned long resize, bpg, rsv_groups;
			unsigned long group_desc_count, desc_blocks;
			unsigned int gdpb, blocksize;
			int rsv_gdb;

			if (!arg) {
				r_usage++;
				continue;
			}

			resize = parse_num_blocks(arg,
						  sb_param->s_log_block_size);

			if (resize == 0) {
				bb_error_msg("Invalid resize parameter: %s", arg);
				r_usage++;
				continue;
			}
			if (resize <= sb_param->s_blocks_count) {
				bb_error_msg("The resize maximum must be greater than the filesystem size");
				r_usage++;
				continue;
			}

			blocksize = EXT2_BLOCK_SIZE(sb_param);
			bpg = sb_param->s_blocks_per_group;
			if (!bpg)
				bpg = blocksize * 8;
			gdpb = blocksize / sizeof(struct ext2_group_desc);
			group_desc_count = (sb_param->s_blocks_count +
					    bpg - 1) / bpg;
			desc_blocks = (group_desc_count +
				       gdpb - 1) / gdpb;
			rsv_groups = (resize + bpg - 1) / bpg;
			rsv_gdb = (rsv_groups + gdpb - 1) / gdpb -
				desc_blocks;
			if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb_param))
				rsv_gdb = EXT2_ADDR_PER_BLOCK(sb_param);

			if (rsv_gdb > 0) {
				sb_param->s_feature_compat |=
					EXT2_FEATURE_COMPAT_RESIZE_INODE;

				sb_param->s_reserved_gdt_blocks = rsv_gdb;
			}
		} else
			r_usage++;
	}
	if (r_usage) {
		bb_error_msg_and_die(
			"\nBad options specified.\n\n"
			"Options are separated by commas, "
			"and may take an argument which\n"
			"\tis set off by an equals ('=') sign.\n\n"
			"Valid raid options are:\n"
			"\tstride=<stride length in blocks>\n"
			"\tresize=<resize maximum size in blocks>\n");
	}
}

static __u32 ok_features[3] = {
	EXT3_FEATURE_COMPAT_HAS_JOURNAL |
		EXT2_FEATURE_COMPAT_RESIZE_INODE |
		EXT2_FEATURE_COMPAT_DIR_INDEX,  /* Compat */
	EXT2_FEATURE_INCOMPAT_FILETYPE|         /* Incompat */
		EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
		EXT2_FEATURE_INCOMPAT_META_BG,
	EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER     /* R/O compat */
};


static int PRS(int argc, char *argv[])
{
	int		b, c;
	int		size;
	char *		tmp;
	int		blocksize = 0;
	int		inode_ratio = 0;
	int		inode_size = 0;
	int		reserved_ratio = 5;
	int		sector_size = 0;
	int		show_version_only = 0;
	ext2_ino_t	num_inodes = 0;
	errcode_t	retval;
	char *		oldpath = getenv("PATH");
	char *		extended_opts = 0;
	const char *	fs_type = 0;
	blk_t		dev_size;
	long		sysval;

	/* Update our PATH to include /sbin  */
	if (oldpath) {
		char *newpath;

		bb_xasprintf(&newpath, "%s:%s", PATH_SET, oldpath);
	} else
		putenv (PATH_SET);

	tmp = getenv("MKE2FS_SYNC");
	if (tmp)
		sync_kludge = atoi(tmp);

	/* Determine the system page size if possible */
#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 */

	setbuf(stdout, NULL);
	setbuf(stderr, NULL);
	memset(&param, 0, sizeof(struct ext2_super_block));
	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;
#if 0
	param.s_feature_compat |= EXT2_FEATURE_COMPAT_DIR_INDEX;
#endif

#ifdef __linux__
	linux_version_code = get_kernel_revision();
	if (linux_version_code && linux_version_code < (2*65536 + 2*256)) {
		param.s_rev_level = 0;
		param.s_feature_incompat = 0;
		param.s_feature_compat = 0;
		param.s_feature_ro_compat = 0;
	}
#endif

	if (argc && *argv) {
		/* If called as mkfs.ext3, create a journal inode */
		if (!strcmp(*argv + strlen(*argv) - 9, "mkfs.ext3"))
			journal_size = -1;
	}

	while ((c = getopt (argc, argv,
		    "b:cE:f:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF) {
		switch (c) {
		case 'b':
			blocksize = strtol(optarg, &tmp, 0);
			b = (blocksize > 0) ? blocksize : -blocksize;
			if (b < EXT2_MIN_BLOCK_SIZE ||
			    b > EXT2_MAX_BLOCK_SIZE || *tmp) {
				bb_error_msg_and_die("bad block size - %s", optarg);
			}
			if (blocksize > 4096)
				bb_error_msg(
					"Warning: blocksize %d not usable on most systems",
					blocksize);
			if (blocksize > 0)
				param.s_log_block_size =
					int_log2(blocksize >>
						 EXT2_MIN_BLOCK_LOG_SIZE);
			break;
		case 'c':	/* Check for bad blocks */
		case 't':	/* deprecated */
			cflag++;
			break;
		case 'f':
			size = strtoul(optarg, &tmp, 0);
			if (size < EXT2_MIN_BLOCK_SIZE ||
			    size > EXT2_MAX_BLOCK_SIZE || *tmp) {
				bb_error_msg_and_die("bad fragment size - %s", optarg);
			}
			param.s_log_frag_size =
				int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
			bb_error_msg(
				"Warning: fragments not supported.  "
				"Ignoring -f option");
			break;
		case 'g':
			param.s_blocks_per_group = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				bb_error_msg_and_die("Illegal number for blocks per group");
			}
			if ((param.s_blocks_per_group % 8) != 0) {
				bb_error_msg_and_die("blocks per group must be multiple of 8");
			}
			break;
		case 'i':
			inode_ratio = strtoul(optarg, &tmp, 0);
			if (inode_ratio < EXT2_MIN_BLOCK_SIZE ||
			    inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024 ||
			    *tmp) {
				bb_error_msg_and_die("bad inode ratio %s (min %d/max %d",
					optarg, EXT2_MIN_BLOCK_SIZE,
					EXT2_MAX_BLOCK_SIZE);
			}
			break;
		case 'J':
			parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg);
			break;
		case 'j':
			param.s_feature_compat |=
				EXT3_FEATURE_COMPAT_HAS_JOURNAL;
			if (!journal_size)
				journal_size = -1;
			break;
		case 'l':
			bad_blocks_filename = optarg;
			break;
		case 'm':
			reserved_ratio = strtoul(optarg, &tmp, 0);
			if (reserved_ratio > 50 || *tmp) {
				bb_error_msg_and_die("bad reserved blocks percent - %s", optarg);
			}
			break;
		case 'n':
			noaction++;
			break;
		case 'o':
			creator_os = optarg;
			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':	/* 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':
			inode_size = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				bb_error_msg_and_die("bad inode size - %s", optarg);
			}
			break;
#endif
		case 'N':
			num_inodes = atoi(optarg);
			break;
		case 'v':
			quiet = 0;
			break;
		case 'q':
			quiet = 1;
			break;
		case 'F':
			force = 1;
			break;
		case 'L':
			volume_label = optarg;
			break;
		case 'M':
			mount_dir = optarg;
			break;
		case 'O':
			if (!strcmp(optarg, "none")) {
				param.s_feature_compat = 0;
				param.s_feature_incompat = 0;
				param.s_feature_ro_compat = 0;
				break;
			}
			if (e2p_edit_feature(optarg,
					    &param.s_feature_compat,
					    ok_features)) {
				bb_error_msg_and_die("Invalid filesystem option set: %s", optarg);
			}
			break;
		case 'E':
		case 'R':
			extended_opts = optarg;
			break;
		case 'S':
			super_only = 1;
			break;
		case 'T':
			fs_type = optarg;
			break;
		case 'V':
			/* Print version number and exit */
			show_version_only++;
			break;
		default:
			bb_show_usage();
		}
	}
	if ((optind == argc) && !show_version_only)
		bb_show_usage();
	device_name = argv[optind++];

	if (!quiet || show_version_only)
		bb_error_msg("mke2fs %s (%s)", E2FSPROGS_VERSION,
			 E2FSPROGS_DATE);

	if (show_version_only) {
		return 0;
	}

	/*
	 * 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;
		io_manager      io_ptr;

#ifdef CONFIG_TESTIO_DEBUG
		io_ptr = test_io_manager;
		test_io_backing_manager = unix_io_manager;
#else
		io_ptr = unix_io_manager;
#endif
		retval = ext2fs_open(journal_device,
				     EXT2_FLAG_JOURNAL_DEV_OK, 0,
				     0, io_ptr, &jfs);
		if (retval) {
			bb_error_msg_and_die("Could not open journal device %s", journal_device);
		}
		if ((blocksize < 0) && (jfs->blocksize < (unsigned) (-blocksize))) {
			bb_error_msg_and_die(
				"Journal dev blocksize (%d) smaller than "
				"minimum blocksize %d\n", jfs->blocksize,
				-blocksize);
		}
		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) {
			bb_error_msg("%d-byte blocks too big for system (max %d)",
				blocksize, sys_page_size);
			proceed_question();
		}
		bb_error_msg(
			"Warning: %d-byte blocks too big for system "
			"(max %d), forced to continue",
			blocksize, sys_page_size);
	}
	if ((blocksize > 4096) &&
	    (param.s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
		bb_error_msg(
			"\nWarning: some 2.4 kernels do not support "
			"blocksizes greater than 4096 \n\tusing ext3."
			"  Use -b 4096 if this is an issue for you\n");

	if (optind < argc) {
		param.s_blocks_count = parse_num_blocks(argv[optind++],
				param.s_log_block_size);
		if (!param.s_blocks_count) {
			bb_error_msg_and_die("bad blocks count - %s", argv[optind - 1]);
		}
	}
	if (optind < argc)
		bb_show_usage();

	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");

	param.s_log_frag_size = param.s_log_block_size;

	if (noaction && param.s_blocks_count) {
		dev_size = param.s_blocks_count;
		retval = 0;
	} else {
	retry:
		retval = ext2fs_get_device_size(device_name,
						EXT2_BLOCK_SIZE(&param),
						&dev_size);
		if ((retval == EFBIG) &&
		    (blocksize == 0) &&
		    (param.s_log_block_size == 0)) {
			param.s_log_block_size = 2;
			blocksize = 4096;
			goto retry;
		}
	}

	if (retval && (retval != EXT2_ET_UNIMPLEMENTED)) {
		bb_error_msg_and_die("Could not determine filesystem size");
	}
	if (!param.s_blocks_count) {
		if (retval == EXT2_ET_UNIMPLEMENTED) {
			bb_error_msg_and_die(
				"Couldn't determine device size; you "
				"must specify\nthe size of the "
				"filesystem");
		} else {
			if (dev_size == 0) {
				bb_error_msg_and_die(
					"Device size reported to be zero.  "
					"Invalid partition specified, or\n\t"
					"partition table wasn't reread "
					"after running fdisk, due to\n\t"
					"a modified partition being busy "
					"and in use.  You may need to reboot\n\t"
					"to re-read your partition table.\n"
				);
			}
			param.s_blocks_count = dev_size;
			if (sys_page_size > EXT2_BLOCK_SIZE(&param))
				param.s_blocks_count &= ~((sys_page_size /
							   EXT2_BLOCK_SIZE(&param))-1);
		}

	} else if (!force && (param.s_blocks_count > dev_size)) {
		bb_error_msg("Filesystem larger than apparent device size");
		proceed_question();
	}

	/*
	 * 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 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);

	/* Get the hardware sector size, if available */
	retval = ext2fs_get_device_sectsize(device_name, &sector_size);
	if (retval) {
		bb_error_msg_and_die("Could not determine hardware sector size");
	}

	if ((tmp = getenv("MKE2FS_DEVICE_SECTSIZE")) != NULL)
		sector_size = atoi(tmp);

	set_fs_defaults(fs_type, &param, blocksize, sector_size, &inode_ratio);
	blocksize = EXT2_BLOCK_SIZE(&param);

	if (extended_opts)
		parse_extended_opts(&param, extended_opts);

	/* Since sparse_super is the default, we would only have a problem
	 * here if it was explicitly disabled.
	 */
	if ((param.s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE) &&
	    !(param.s_feature_ro_compat&EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
		bb_error_msg_and_die("reserved online resize blocks not supported "
			  "on non-sparse filesystem");
	}

	if (param.s_blocks_per_group) {
		if (param.s_blocks_per_group < 256 ||
		    param.s_blocks_per_group > 8 * (unsigned) blocksize) {
			bb_error_msg_and_die("blocks per group count out of range");
		}
	}

	if (inode_size) {
		if (inode_size < EXT2_GOOD_OLD_INODE_SIZE ||
		    inode_size > EXT2_BLOCK_SIZE(&param) ||
		    inode_size & (inode_size - 1)) {
			bb_error_msg_and_die("bad inode size %d (min %d/max %d)",
				inode_size, EXT2_GOOD_OLD_INODE_SIZE,
				blocksize);
		}
		if (inode_size != EXT2_GOOD_OLD_INODE_SIZE)
			bb_error_msg(
				"Warning: %d-byte inodes not usable on most systems",
				inode_size);
		param.s_inode_size = inode_size;
	}

	/*
	 * Calculate number of inodes based on the inode ratio
	 */
	param.s_inodes_count = num_inodes ? num_inodes :
		((__u64) param.s_blocks_count * blocksize)
			/ inode_ratio;

	/*
	 * Calculate number of blocks to reserve
	 */
	param.s_r_blocks_count = (param.s_blocks_count * reserved_ratio) / 100;
	return 1;
}

int mke2fs_main (int argc, char *argv[])
{
	errcode_t	retval;
	ext2_filsys	fs;
	badblocks_list	bb_list = 0;
	int		journal_blocks;
	unsigned int	i;
	int		val;
	io_manager	io_ptr;

	if(!PRS(argc, argv))
		return 0;

#ifdef CONFIG_TESTIO_DEBUG
	io_ptr = test_io_manager;
	test_io_backing_manager = unix_io_manager;
#else
	io_ptr = unix_io_manager;
#endif

	/*
	 * Initialize the superblock....
	 */
	retval = ext2fs_initialize(device_name, 0, &param,
				   io_ptr, &fs);
	if (retval) {
		bb_error_msg_and_die("Could not set up superblock");
	}

	/*
	 * Wipe out the old on-disk superblock
	 */
	if (!noaction)
		zap_sector(fs, 2, 6);

	/*
	 * Generate a UUID for it...
	 */
	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.
	 */
	for (i = 0, val = 0 ; i < sizeof(fs->super->s_uuid); i++)
		val += fs->super->s_uuid[i];
	fs->super->s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT;

	/*
	 * Override the creator OS, if applicable
	 */
	if (creator_os && !set_os(fs->super, creator_os)) {
		bb_error_msg_and_die("unknown os - %s", creator_os);
	}

	/*
	 * For the Hurd, we will turn off filetype since it doesn't
	 * support it.
	 */
	if (fs->super->s_creator_os == EXT2_OS_HURD)
		fs->super->s_feature_incompat &=
			~EXT2_FEATURE_INCOMPAT_FILETYPE;

	/*
	 * Set the volume label...
	 */
	if (volume_label) {
		memset(fs->super->s_volume_name, 0,
		       sizeof(fs->super->s_volume_name));
		strncpy(fs->super->s_volume_name, volume_label,
			sizeof(fs->super->s_volume_name));
	}

	/*
	 * Set the last mount directory
	 */
	if (mount_dir) {
		memset(fs->super->s_last_mounted, 0,
		       sizeof(fs->super->s_last_mounted));
		strncpy(fs->super->s_last_mounted, mount_dir,
			sizeof(fs->super->s_last_mounted));
	}

	if (!quiet || noaction)
		show_stats(fs);

	if (noaction)
		return 0;

	if (fs->super->s_feature_incompat &
	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
		create_journal_dev(fs);
		return (ext2fs_close(fs) ? 1 : 0);
	}

	if (bad_blocks_filename)
		read_bb_file(fs, &bb_list, bad_blocks_filename);
	if (cflag)
		test_disk(fs, &bb_list);

	handle_bad_blocks(fs, bb_list);
	fs->stride = fs_stride;
	retval = ext2fs_allocate_tables(fs);
	if (retval) {
		bb_error_msg_and_die("Could not allocate filesystem tables");
	}
	if (super_only) {
		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) */
		unsigned 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) {
			bb_error_msg("Could not zero block %u at end of filesystem", ret_blk);
		}
		write_inode_tables(fs);
		create_root_dir(fs);
		create_lost_and_found(fs);
		reserve_inodes(fs);
		create_bad_block_inode(fs, bb_list);
		if (fs->super->s_feature_compat &
		    EXT2_FEATURE_COMPAT_RESIZE_INODE) {
			retval = ext2fs_create_resize_inode(fs);
			if (retval) {
				bb_error_msg_and_die("Could not reserve blocks for online resize");
			}
		}
	}

	if (journal_device) {
		ext2_filsys     jfs;

		if (!force)
			check_plausibility(journal_device);
		check_mount(journal_device, force, "journal");

		retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
				     EXT2_FLAG_JOURNAL_DEV_OK, 0,
				     fs->blocksize, unix_io_manager, &jfs);
		if (retval) {
			bb_error_msg_and_die("Could not open journal device %s", journal_device);
		}
		if (!quiet) {
			printf("Adding journal to device %s: ", journal_device);
			fflush(stdout);
		}
		retval = ext2fs_add_journal_device(fs, jfs);
		if(retval) {
			bb_error_msg_and_die("Could not add journal to device %s", journal_device);
		}
		if (!quiet)
			printf("done\n");
		ext2fs_close(jfs);
		free(journal_device);
	} else if (journal_size) {
		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) {
			bb_error_msg_and_die("Could not create journal");
		}
		if (!quiet)
			printf("done\n");
	}
no_journal:

	if (!quiet)
		printf("Writing superblocks and "
		       "filesystem accounting information: ");
	retval = ext2fs_flush(fs);
	if (retval) {
		bb_error_msg("\nWarning, had trouble writing out superblocks");
	}
	if (!quiet) {
		printf("done\n\n");
		if (!getenv("MKE2FS_SKIP_CHECK_MSG"))
			print_check_message(fs);
	}
	val = ext2fs_close(fs);
	return (retval || val) ? 1 : 0;
}
