/*
 * tune2fs.c - Change the file system parameters on an ext2 file system
 *
 * Copyright (C) 1992, 1993, 1994  Remy Card <card@masi.ibp.fr>
 *                                 Laboratoire MASI, Institut Blaise Pascal
 *                                 Universite Pierre et Marie Curie (Paris VI)
 *
 * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

/*
 * History:
 * 93/06/01	- Creation
 * 93/10/31	- Added the -c option to change the maximal mount counts
 * 93/12/14	- Added -l flag to list contents of superblock
 *                M.J.E. Mol (marcel@duteca.et.tudelft.nl)
 *                F.W. ten Wolde (franky@duteca.et.tudelft.nl)
 * 93/12/29	- Added the -e option to change errors behavior
 * 94/02/27	- Ported to use the ext2fs library
 * 94/03/06	- Added the checks interval from Uwe Ohse (uwe@tirka.gun.de)
 */

#define _XOPEN_SOURCE 600 /* for inclusion of strptime() */
#include "config.h"
#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern char *optarg;
extern int optind;
#endif
#include <pwd.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>	/* for strcasecmp() */
#else
#define _BSD_SOURCE	/* for inclusion of strcasecmp() via <string.h> */
#define _DEFAULT_SOURCE	  /* since glibc 2.20 _BSD_SOURCE is deprecated */
#endif
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <libgen.h>
#include <limits.h>

#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "ext2fs/kernel-jbd.h"
#include "et/com_err.h"
#include "support/plausible.h"
#include "support/quotaio.h"
#include "uuid/uuid.h"
#include "e2p/e2p.h"
#include "util.h"
#include "blkid/blkid.h"

#include "../version.h"
#include "support/nls-enable.h"

#define QOPT_ENABLE	(1)
#define QOPT_DISABLE	(-1)

extern int ask_yn(const char *string, int def);

const char *program_name = "tune2fs";
char *device_name;
char *new_label, *new_last_mounted, *new_UUID;
char *io_options;
static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
static int m_flag, M_flag, Q_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
static int I_flag;
static int clear_mmp;
static time_t last_check_time;
static int print_label;
static int max_mount_count, mount_count, mount_flags;
static unsigned long interval;
static blk64_t reserved_blocks;
static double reserved_ratio;
static unsigned long resgid, resuid;
static unsigned short errors;
static int open_flag;
static char *features_cmd;
static char *mntopts_cmd;
static int stride, stripe_width;
static int stride_set, stripe_width_set;
static char *extended_cmd;
static unsigned long new_inode_size;
static char *ext_mount_opts;
static int quota_enable[MAXQUOTAS];
static int rewrite_checksums;
static int feature_64bit;
static int fsck_requested;
static char *undo_file;

int journal_size, journal_flags;
char *journal_device;
static blk64_t journal_location = ~0LL;

static struct list_head blk_move_list;

struct blk_move {
	struct list_head list;
	blk64_t old_loc;
	blk64_t new_loc;
};

errcode_t ext2fs_run_ext3_journal(ext2_filsys *fs);

static const char *fsck_explain = N_("\nThis operation requires a freshly checked filesystem.\n");

static const char *please_fsck = N_("Please run e2fsck -f on the filesystem.\n");
static const char *please_dir_fsck =
		N_("Please run e2fsck -fD on the filesystem.\n");

#ifdef CONFIG_BUILD_FINDFS
void do_findfs(int argc, char **argv);
#endif

#ifdef CONFIG_JBD_DEBUG		/* Enabled by configure --enable-jbd-debug */
int journal_enable_debug = -1;
#endif

static void usage(void)
{
	fprintf(stderr,
		_("Usage: %s [-c max_mounts_count] [-e errors_behavior] [-f] "
		  "[-g group]\n"
		  "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l]\n"
		  "\t[-m reserved_blocks_percent] [-o [^]mount_options[,...]]\n"
		  "\t[-r reserved_blocks_count] [-u user] [-C mount_count]\n"
		  "\t[-L volume_label] [-M last_mounted_dir]\n"
		  "\t[-O [^]feature[,...]] [-Q quota_options]\n"
		  "\t[-E extended-option[,...]] [-T last_check_time] "
		  "[-U UUID]\n\t[-I new_inode_size] [-z undo_file] device\n"),
		program_name);
	exit(1);
}

static __u32 ok_features[3] = {
	/* Compat */
	EXT3_FEATURE_COMPAT_HAS_JOURNAL |
		EXT2_FEATURE_COMPAT_DIR_INDEX,
	/* Incompat */
	EXT2_FEATURE_INCOMPAT_FILETYPE |
		EXT3_FEATURE_INCOMPAT_EXTENTS |
		EXT4_FEATURE_INCOMPAT_FLEX_BG |
		EXT4_FEATURE_INCOMPAT_EA_INODE|
		EXT4_FEATURE_INCOMPAT_MMP |
		EXT4_FEATURE_INCOMPAT_64BIT |
		EXT4_FEATURE_INCOMPAT_ENCRYPT |
		EXT4_FEATURE_INCOMPAT_CSUM_SEED |
		EXT4_FEATURE_INCOMPAT_LARGEDIR,
	/* R/O compat */
	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
		EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
		EXT4_FEATURE_RO_COMPAT_QUOTA |
		EXT4_FEATURE_RO_COMPAT_METADATA_CSUM |
		EXT4_FEATURE_RO_COMPAT_READONLY |
		EXT4_FEATURE_RO_COMPAT_PROJECT |
		EXT4_FEATURE_RO_COMPAT_VERITY
};

static __u32 clear_ok_features[3] = {
	/* Compat */
	EXT3_FEATURE_COMPAT_HAS_JOURNAL |
		EXT2_FEATURE_COMPAT_RESIZE_INODE |
		EXT2_FEATURE_COMPAT_DIR_INDEX,
	/* Incompat */
	EXT2_FEATURE_INCOMPAT_FILETYPE |
		EXT4_FEATURE_INCOMPAT_FLEX_BG |
		EXT4_FEATURE_INCOMPAT_MMP |
		EXT4_FEATURE_INCOMPAT_64BIT |
		EXT4_FEATURE_INCOMPAT_CSUM_SEED,
	/* R/O compat */
	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
		EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
		EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
		EXT4_FEATURE_RO_COMPAT_GDT_CSUM |
		EXT4_FEATURE_RO_COMPAT_QUOTA |
		EXT4_FEATURE_RO_COMPAT_PROJECT |
		EXT4_FEATURE_RO_COMPAT_METADATA_CSUM |
		EXT4_FEATURE_RO_COMPAT_READONLY
};

/**
 * Try to get journal super block if any
 */
static int get_journal_sb(ext2_filsys jfs, char buf[SUPERBLOCK_SIZE])
{
	int retval;
	journal_superblock_t *jsb;

	if (!ext2fs_has_feature_journal_dev(jfs->super)) {
		return EXT2_ET_UNSUPP_FEATURE;
	}

	/* Get the journal superblock */
	if ((retval = io_channel_read_blk64(jfs->io,
	    ext2fs_journal_sb_start(jfs->blocksize), -SUPERBLOCK_SIZE, buf))) {
		com_err(program_name, retval, "%s",
		_("while reading journal superblock"));
		return retval;
	}

	jsb = (journal_superblock_t *) buf;
	if ((jsb->s_header.h_magic != (unsigned)ntohl(JFS_MAGIC_NUMBER)) ||
	    (jsb->s_header.h_blocktype != (unsigned)ntohl(JFS_SUPERBLOCK_V2))) {
		fputs(_("Journal superblock not found!\n"), stderr);
		return EXT2_ET_BAD_MAGIC;
	}

	return 0;
}

static __u8 *journal_user(__u8 uuid[UUID_SIZE], __u8 s_users[JFS_USERS_SIZE],
			  int nr_users)
{
	int i;
	for (i = 0; i < nr_users; i++) {
		if (memcmp(uuid, &s_users[i * UUID_SIZE], UUID_SIZE) == 0)
			return &s_users[i * UUID_SIZE];
	}

	return NULL;
}

/*
 * Remove an external journal from the filesystem
 */
static int remove_journal_device(ext2_filsys fs)
{
	char		*journal_path;
	ext2_filsys	jfs;
	char		buf[SUPERBLOCK_SIZE] __attribute__ ((aligned(8)));
	journal_superblock_t	*jsb;
	int		i, nr_users;
	errcode_t	retval;
	int		commit_remove_journal = 0;
	io_manager	io_ptr;

	if (f_flag)
		commit_remove_journal = 1; /* force removal even if error */

	uuid_unparse(fs->super->s_journal_uuid, buf);
	journal_path = blkid_get_devname(NULL, "UUID", buf);

	if (!journal_path) {
		journal_path =
			ext2fs_find_block_device(fs->super->s_journal_dev);
		if (!journal_path)
			goto no_valid_journal;
	}

#ifdef CONFIG_TESTIO_DEBUG
	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
		io_ptr = test_io_manager;
		test_io_backing_manager = unix_io_manager;
	} else
#endif
		io_ptr = unix_io_manager;
	retval = ext2fs_open(journal_path, EXT2_FLAG_RW|
			     EXT2_FLAG_JOURNAL_DEV_OK, 0,
			     fs->blocksize, io_ptr, &jfs);
	if (retval) {
		com_err(program_name, retval, "%s",
			_("while trying to open external journal"));
		goto no_valid_journal;
	}

	if ((retval = get_journal_sb(jfs, buf))) {
		if (retval == EXT2_ET_UNSUPP_FEATURE)
			fprintf(stderr, _("%s is not a journal device.\n"),
				journal_path);
		goto no_valid_journal;
	}

	jsb = (journal_superblock_t *) buf;
	/* Find the filesystem UUID */
	nr_users = ntohl(jsb->s_nr_users);

	if (!journal_user(fs->super->s_uuid, jsb->s_users, nr_users)) {
		fputs(_("Filesystem's UUID not found on journal device.\n"),
		      stderr);
		commit_remove_journal = 1;
		goto no_valid_journal;
	}
	nr_users--;
	for (i = 0; i < nr_users; i++)
		memcpy(&jsb->s_users[i * 16], &jsb->s_users[(i + 1) * 16], 16);
	jsb->s_nr_users = htonl(nr_users);

	/* Write back the journal superblock */
	retval = io_channel_write_blk64(jfs->io,
					ext2fs_journal_sb_start(fs->blocksize),
					-SUPERBLOCK_SIZE, buf);
	if (retval) {
		com_err(program_name, retval,
			"while writing journal superblock.");
		goto no_valid_journal;
	}

	commit_remove_journal = 1;

no_valid_journal:
	if (commit_remove_journal == 0) {
		fputs(_("Cannot locate journal device. It was NOT removed\n"
			"Use -f option to remove missing journal device.\n"),
		      stderr);
		return 1;
	}
	fs->super->s_journal_dev = 0;
	memset(fs->super->s_jnl_blocks, 0, sizeof(fs->super->s_jnl_blocks));
	uuid_clear(fs->super->s_journal_uuid);
	ext2fs_mark_super_dirty(fs);
	fputs(_("Journal removed\n"), stdout);
	free(journal_path);

	return 0;
}

/* Helper function for remove_journal_inode */
static int release_blocks_proc(ext2_filsys fs, blk64_t *blocknr,
			       e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
			       blk64_t ref_block EXT2FS_ATTR((unused)),
			       int ref_offset EXT2FS_ATTR((unused)),
			       void *private EXT2FS_ATTR((unused)))
{
	blk64_t	block;
	int	group;

	block = *blocknr;
	ext2fs_unmark_block_bitmap2(fs->block_map, block);
	group = ext2fs_group_of_blk2(fs, block);
	ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) + 1);
	ext2fs_group_desc_csum_set(fs, group);
	ext2fs_free_blocks_count_add(fs->super, EXT2FS_CLUSTER_RATIO(fs));
	return 0;
}

/*
 * Remove the journal inode from the filesystem
 */
static errcode_t remove_journal_inode(ext2_filsys fs)
{
	struct ext2_inode	inode;
	errcode_t		retval;
	ino_t			ino = fs->super->s_journal_inum;

	retval = ext2fs_read_inode(fs, ino,  &inode);
	if (retval) {
		com_err(program_name, retval, "%s",
			_("while reading journal inode"));
		return retval;
	}
	if (ino == EXT2_JOURNAL_INO) {
		retval = ext2fs_read_bitmaps(fs);
		if (retval) {
			com_err(program_name, retval, "%s",
				_("while reading bitmaps"));
			return retval;
		}
		retval = ext2fs_block_iterate3(fs, ino,
					       BLOCK_FLAG_READ_ONLY, NULL,
					       release_blocks_proc, NULL);
		if (retval) {
			com_err(program_name, retval, "%s",
				_("while clearing journal inode"));
			return retval;
		}
		memset(&inode, 0, sizeof(inode));
		ext2fs_mark_bb_dirty(fs);
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	} else
		inode.i_flags &= ~EXT2_IMMUTABLE_FL;
	retval = ext2fs_write_inode(fs, ino, &inode);
	if (retval) {
		com_err(program_name, retval, "%s",
			_("while writing journal inode"));
		return retval;
	}
	fs->super->s_journal_inum = 0;
	memset(fs->super->s_jnl_blocks, 0, sizeof(fs->super->s_jnl_blocks));
	ext2fs_mark_super_dirty(fs);

	return 0;
}

/*
 * Update the default mount options
 */
static int update_mntopts(ext2_filsys fs, char *mntopts)
{
	struct ext2_super_block *sb = fs->super;

	if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) {
		fprintf(stderr, _("Invalid mount option set: %s\n"),
			mntopts);
		return 1;
	}
	ext2fs_mark_super_dirty(fs);

	return 0;
}

static void check_fsck_needed(ext2_filsys fs, const char *prompt)
{
	/* Refuse to modify anything but a freshly checked valid filesystem. */
	if (!(fs->super->s_state & EXT2_VALID_FS) ||
	    (fs->super->s_state & EXT2_ERROR_FS) ||
	    (fs->super->s_lastcheck < fs->super->s_mtime)) {
		puts(_(fsck_explain));
		puts(_(please_fsck));
		if (mount_flags & EXT2_MF_READONLY)
			printf("%s", _("(and reboot afterwards!)\n"));
		exit(1);
	}

	/* Give the admin a few seconds to bail out of a dangerous op. */
	if (!getenv("TUNE2FS_FORCE_PROMPT") && (!isatty(0) || !isatty(1)))
		return;

	puts(prompt);
	proceed_question(5);
}

static void request_dir_fsck_afterwards(ext2_filsys fs)
{
	static int requested;

	if (requested++)
		return;
	fsck_requested++;
	fs->super->s_state &= ~EXT2_VALID_FS;
	puts(_(fsck_explain));
	puts(_(please_dir_fsck));
	if (mount_flags & EXT2_MF_READONLY)
		printf("%s", _("(and reboot afterwards!)\n"));
}

static void request_fsck_afterwards(ext2_filsys fs)
{
	static int requested = 0;

	if (requested++)
		return;
	fsck_requested++;
	fs->super->s_state &= ~EXT2_VALID_FS;
	printf("\n%s\n", _(please_fsck));
	if (mount_flags & EXT2_MF_READONLY)
		printf("%s", _("(and reboot afterwards!)\n"));
}

static void convert_64bit(ext2_filsys fs, int direction)
{
	/*
	 * Is resize2fs going to demand a fsck run? Might as well tell the
	 * user now.
	 */
	if (!fsck_requested &&
	    ((fs->super->s_state & EXT2_ERROR_FS) ||
	     !(fs->super->s_state & EXT2_VALID_FS) ||
	     fs->super->s_lastcheck < fs->super->s_mtime))
		request_fsck_afterwards(fs);
	if (fsck_requested)
		fprintf(stderr, _("After running e2fsck, please run `resize2fs %s %s"),
			direction > 0 ? "-b" : "-s", fs->device_name);
	else
		fprintf(stderr, _("Please run `resize2fs %s %s"),
			direction > 0 ? "-b" : "-s", fs->device_name);

	if (undo_file)
		fprintf(stderr, _(" -z \"%s\""), undo_file);
	if (direction > 0)
		fprintf(stderr, _("' to enable 64-bit mode.\n"));
	else
		fprintf(stderr, _("' to disable 64-bit mode.\n"));
}

/* Rewrite extents */
static errcode_t rewrite_extents(ext2_filsys fs, ext2_ino_t ino,
				 struct ext2_inode *inode)
{
	ext2_extent_handle_t	handle;
	struct ext2fs_extent	extent;
	errcode_t		errcode;
	struct ext2_extent_info	info;

	if (!(inode->i_flags & EXT4_EXTENTS_FL) ||
	    !ext2fs_has_feature_metadata_csum(fs->super))
		return 0;

	errcode = ext2fs_extent_open(fs, ino, &handle);
	if (errcode)
		return errcode;

	errcode = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent);
	if (errcode)
		goto out;

	do {
		errcode = ext2fs_extent_get_info(handle, &info);
		if (errcode)
			break;

		/*
		 * If this is the first extent in an extent block that we
		 * haven't visited, rewrite the extent to force the ETB
		 * checksum to be rewritten.
		 */
		if (info.curr_entry == 1 && info.curr_level != 0 &&
		    !(extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)) {
			errcode = ext2fs_extent_replace(handle, 0, &extent);
			if (errcode)
				break;
		}

		/* Skip to the end of a block of leaf nodes */
		if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
			errcode = ext2fs_extent_get(handle,
						    EXT2_EXTENT_LAST_SIB,
						    &extent);
			if (errcode)
				break;
		}

		errcode = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT, &extent);
	} while (errcode == 0);

out:
	/* Ok if we run off the end */
	if (errcode == EXT2_ET_EXTENT_NO_NEXT)
		errcode = 0;
	ext2fs_extent_free(handle);
	return errcode;
}

/*
 * Rewrite directory blocks with checksums
 */
struct rewrite_dir_context {
	char *buf;
	errcode_t errcode;
	ext2_ino_t dir;
	int is_htree;
};

static int rewrite_dir_block(ext2_filsys fs,
			     blk64_t	*blocknr,
			     e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
			     blk64_t	ref_block EXT2FS_ATTR((unused)),
			     int	ref_offset EXT2FS_ATTR((unused)),
			     void	*priv_data)
{
	struct ext2_dx_countlimit *dcl = NULL;
	struct rewrite_dir_context *ctx = priv_data;
	int dcl_offset, changed = 0;

	ctx->errcode = ext2fs_read_dir_block4(fs, *blocknr, ctx->buf, 0,
					      ctx->dir);
	if (ctx->errcode)
		return BLOCK_ABORT;

	/* if htree node... */
	if (ctx->is_htree)
		ext2fs_get_dx_countlimit(fs, (struct ext2_dir_entry *)ctx->buf,
					 &dcl, &dcl_offset);
	if (dcl) {
		if (!ext2fs_has_feature_metadata_csum(fs->super)) {
			/* Ensure limit is the max size */
			int max_entries = (fs->blocksize - dcl_offset) /
					  sizeof(struct ext2_dx_entry);
			if (ext2fs_le16_to_cpu(dcl->limit) != max_entries) {
				changed = 1;
				dcl->limit = ext2fs_cpu_to_le16(max_entries);
			}
		} else {
			/* If htree block is full then rebuild the dir */
			if (ext2fs_le16_to_cpu(dcl->count) ==
			    ext2fs_le16_to_cpu(dcl->limit)) {
				request_dir_fsck_afterwards(fs);
				return 0;
			}
			/*
			 * Ensure dcl->limit is small enough to leave room for
			 * the checksum tail.
			 */
			int max_entries = (fs->blocksize - (dcl_offset +
						sizeof(struct ext2_dx_tail))) /
					  sizeof(struct ext2_dx_entry);
			if (ext2fs_le16_to_cpu(dcl->limit) != max_entries)
				dcl->limit = ext2fs_cpu_to_le16(max_entries);
			/* Always rewrite checksum */
			changed = 1;
		}
	} else {
		unsigned int rec_len, name_size;
		char *top = ctx->buf + fs->blocksize;
		struct ext2_dir_entry *de = (struct ext2_dir_entry *)ctx->buf;
		struct ext2_dir_entry *last_de = NULL, *penultimate_de = NULL;

		/* Find last and penultimate dirent */
		while ((char *)de < top) {
			penultimate_de = last_de;
			last_de = de;
			ctx->errcode = ext2fs_get_rec_len(fs, de, &rec_len);
			if (!ctx->errcode && !rec_len)
				ctx->errcode = EXT2_ET_DIR_CORRUPTED;
			if (ctx->errcode)
				return BLOCK_ABORT;
			de = (struct ext2_dir_entry *)(((char *)de) + rec_len);
		}
		ctx->errcode = ext2fs_get_rec_len(fs, last_de, &rec_len);
		if (ctx->errcode)
			return BLOCK_ABORT;
		name_size = ext2fs_dirent_name_len(last_de);

		if (!ext2fs_has_feature_metadata_csum(fs->super)) {
			if (!penultimate_de)
				return 0;
			if (last_de->inode ||
			    name_size ||
			    rec_len != sizeof(struct ext2_dir_entry_tail))
				return 0;
			/*
			 * The last dirent is unused and the right length to
			 * have stored a checksum.  Erase it.
			 */
			ctx->errcode = ext2fs_get_rec_len(fs, penultimate_de,
							  &rec_len);
			if (!rec_len)
				ctx->errcode = EXT2_ET_DIR_CORRUPTED;
			if (ctx->errcode)
				return BLOCK_ABORT;
			ext2fs_set_rec_len(fs, rec_len +
					sizeof(struct ext2_dir_entry_tail),
					penultimate_de);
			changed = 1;
		} else {
			unsigned csum_size = sizeof(struct ext2_dir_entry_tail);
			struct ext2_dir_entry_tail *t;

			/*
			 * If the last dirent looks like the tail, just update
			 * the checksum.
			 */
			if (!last_de->inode &&
			    rec_len == csum_size) {
				t = (struct ext2_dir_entry_tail *)last_de;
				t->det_reserved_name_len =
						EXT2_DIR_NAME_LEN_CSUM;
				changed = 1;
				goto out;
			}
			if (name_size & 3)
				name_size = (name_size & ~3) + 4;
			/* If there's not enough space for the tail, e2fsck */
			if (rec_len <= (8 + name_size + csum_size)) {
				request_dir_fsck_afterwards(fs);
				return 0;
			}
			/* Shorten that last de and insert the tail */
			ext2fs_set_rec_len(fs, rec_len - csum_size, last_de);
			t = EXT2_DIRENT_TAIL(ctx->buf, fs->blocksize);
			ext2fs_initialize_dirent_tail(fs, t);

			/* Always update checksum */
			changed = 1;
		}
	}

out:
	if (!changed)
		return 0;

	ctx->errcode = ext2fs_write_dir_block4(fs, *blocknr, ctx->buf,
					       0, ctx->dir);
	if (ctx->errcode)
		return BLOCK_ABORT;

	return 0;
}

static errcode_t rewrite_directory(ext2_filsys fs, ext2_ino_t dir,
				   struct ext2_inode *inode)
{
	errcode_t	retval;
	struct rewrite_dir_context ctx;

	retval = ext2fs_get_mem(fs->blocksize, &ctx.buf);
	if (retval)
		return retval;

	ctx.is_htree = (inode->i_flags & EXT2_INDEX_FL);
	ctx.dir = dir;
	ctx.errcode = 0;
	retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY |
						BLOCK_FLAG_DATA_ONLY,
				       0, rewrite_dir_block, &ctx);

	ext2fs_free_mem(&ctx.buf);
	if (retval)
		return retval;

	return ctx.errcode;
}

/*
 * Context information that does not change across rewrite_one_inode()
 * invocations.
 */
struct rewrite_context {
	ext2_filsys fs;
	struct ext2_inode *zero_inode;
	char *ea_buf;
	int inode_size;
};

#define fatal_err(code, args...)		\
	do {					\
		com_err(__func__, code, args);	\
		exit(1);			\
	} while (0);

static void update_ea_inode_hash(struct rewrite_context *ctx, ext2_ino_t ino,
				 struct ext2_inode *inode)
{
	errcode_t retval;
	ext2_file_t file;
	__u32 hash;

	retval = ext2fs_file_open(ctx->fs, ino, 0, &file);
	if (retval)
		fatal_err(retval, "open ea_inode");
	retval = ext2fs_file_read(file, ctx->ea_buf, inode->i_size,
				  NULL);
	if (retval)
		fatal_err(retval, "read ea_inode");
	retval = ext2fs_file_close(file);
	if (retval)
		fatal_err(retval, "close ea_inode");

	hash = ext2fs_crc32c_le(ctx->fs->csum_seed,
				(unsigned char *) ctx->ea_buf, inode->i_size);
	ext2fs_set_ea_inode_hash(inode, hash);
}

static int update_xattr_entry_hashes(ext2_filsys fs,
				     struct ext2_ext_attr_entry *entry,
				     struct ext2_ext_attr_entry *end)
{
	int modified = 0;
	errcode_t retval;

	while (entry < end && !EXT2_EXT_IS_LAST_ENTRY(entry)) {
		if (entry->e_value_inum) {
			retval = ext2fs_ext_attr_hash_entry2(fs, entry, NULL,
							     &entry->e_hash);
			if (retval)
				fatal_err(retval, "hash ea_inode entry");
			modified = 1;
		}
		entry = EXT2_EXT_ATTR_NEXT(entry);
	}
	return modified;
}

static void update_inline_xattr_hashes(struct rewrite_context *ctx,
				       struct ext2_inode_large *inode)
{
	struct ext2_ext_attr_entry *start, *end;
	__u32 *ea_magic;

	if (inode->i_extra_isize == 0)
		return;

	if (inode->i_extra_isize & 3 ||
	    inode->i_extra_isize > ctx->inode_size - EXT2_GOOD_OLD_INODE_SIZE)
		fatal_err(EXT2_ET_INODE_CORRUPTED, "bad i_extra_isize")

	ea_magic = (__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
				inode->i_extra_isize);
	if (*ea_magic != EXT2_EXT_ATTR_MAGIC)
		return;

	start = (struct ext2_ext_attr_entry *)(ea_magic + 1);
	end = (struct ext2_ext_attr_entry *)((char *)inode + ctx->inode_size);

	update_xattr_entry_hashes(ctx->fs, start, end);
}

static void update_block_xattr_hashes(struct rewrite_context *ctx,
				      char *block_buf)
{
	struct ext2_ext_attr_header *header;
	struct ext2_ext_attr_entry *start, *end;

	header = (struct ext2_ext_attr_header *)block_buf;
	if (header->h_magic != EXT2_EXT_ATTR_MAGIC)
		return;

	start = (struct ext2_ext_attr_entry *)(header+1);
	end = (struct ext2_ext_attr_entry *)(block_buf + ctx->fs->blocksize);

	if (update_xattr_entry_hashes(ctx->fs, start, end))
		ext2fs_ext_attr_block_rehash(header, end);
}

static void rewrite_one_inode(struct rewrite_context *ctx, ext2_ino_t ino,
			      struct ext2_inode *inode)
{
	blk64_t file_acl_block;
	errcode_t retval;

	if (!ext2fs_test_inode_bitmap2(ctx->fs->inode_map, ino)) {
		if (!memcmp(inode, ctx->zero_inode, ctx->inode_size))
			return;
		memset(inode, 0, ctx->inode_size);
	}

	if (inode->i_flags & EXT4_EA_INODE_FL)
		update_ea_inode_hash(ctx, ino, inode);

	if (ctx->inode_size != EXT2_GOOD_OLD_INODE_SIZE)
		update_inline_xattr_hashes(ctx,
					   (struct ext2_inode_large *)inode);

	retval = ext2fs_write_inode_full(ctx->fs, ino, inode, ctx->inode_size);
	if (retval)
		fatal_err(retval, "while writing inode");

	retval = rewrite_extents(ctx->fs, ino, inode);
	if (retval)
		fatal_err(retval, "while rewriting extents");

	if (LINUX_S_ISDIR(inode->i_mode) &&
	    ext2fs_inode_has_valid_blocks2(ctx->fs, inode)) {
		retval = rewrite_directory(ctx->fs, ino, inode);
		if (retval)
			fatal_err(retval, "while rewriting directories");
	}

	file_acl_block = ext2fs_file_acl_block(ctx->fs, inode);
	if (!file_acl_block)
		return;

	retval = ext2fs_read_ext_attr3(ctx->fs, file_acl_block, ctx->ea_buf,
				       ino);
	if (retval)
		fatal_err(retval, "while rewriting extended attribute");

	update_block_xattr_hashes(ctx, ctx->ea_buf);
	retval = ext2fs_write_ext_attr3(ctx->fs, file_acl_block, ctx->ea_buf,
					ino);
	if (retval)
		fatal_err(retval, "while rewriting extended attribute");
}

/*
 * Forcibly set checksums in all inodes.
 */
static void rewrite_inodes(ext2_filsys fs)
{
	ext2_inode_scan	scan;
	errcode_t	retval;
	ext2_ino_t	ino;
	struct ext2_inode *inode;
	int pass;
	struct rewrite_context ctx = {
		.fs = fs,
		.inode_size = EXT2_INODE_SIZE(fs->super),
	};

	if (fs->super->s_creator_os == EXT2_OS_HURD)
		return;

	retval = ext2fs_get_mem(ctx.inode_size, &inode);
	if (retval)
		fatal_err(retval, "while allocating memory");

	retval = ext2fs_get_memzero(ctx.inode_size, &ctx.zero_inode);
	if (retval)
		fatal_err(retval, "while allocating memory");

	retval = ext2fs_get_mem(64 * 1024, &ctx.ea_buf);
	if (retval)
		fatal_err(retval, "while allocating memory");

	/*
	 * Extended attribute inodes have a lookup hash that needs to be
	 * recalculated with the new csum_seed. Other inodes referencing xattr
	 * inodes need this value to be up to date. That's why we do two passes:
	 *
	 * pass 1: update xattr inodes to update their lookup hash as well as
	 *         other checksums.
	 *
	 * pass 2: go over other inodes to update their checksums.
	 */
	if (ext2fs_has_feature_ea_inode(fs->super))
		pass = 1;
	else
		pass = 2;
	for (;pass <= 2; pass++) {
		retval = ext2fs_open_inode_scan(fs, 0, &scan);
		if (retval)
			fatal_err(retval, "while opening inode scan");

		do {
			retval = ext2fs_get_next_inode_full(scan, &ino, inode,
							    ctx.inode_size);
			if (retval)
				fatal_err(retval, "while getting next inode");
			if (!ino)
				break;

			if (((pass == 1) &&
			     (inode->i_flags & EXT4_EA_INODE_FL)) ||
			    ((pass == 2) &&
			     !(inode->i_flags & EXT4_EA_INODE_FL)))
				rewrite_one_inode(&ctx, ino, inode);
		} while (ino);

		ext2fs_close_inode_scan(scan);
	}

	ext2fs_free_mem(&ctx.zero_inode);
	ext2fs_free_mem(&ctx.ea_buf);
	ext2fs_free_mem(&inode);
}

static void rewrite_metadata_checksums(ext2_filsys fs)
{
	errcode_t retval;
	dgrp_t i;

	fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
	ext2fs_init_csum_seed(fs);
	for (i = 0; i < fs->group_desc_count; i++)
		ext2fs_group_desc_csum_set(fs, i);
	retval = ext2fs_read_bitmaps(fs);
	if (retval)
		fatal_err(retval, "while reading bitmaps");
	rewrite_inodes(fs);
	ext2fs_mark_ib_dirty(fs);
	ext2fs_mark_bb_dirty(fs);
	ext2fs_mmp_update2(fs, 1);
	fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
	if (ext2fs_has_feature_metadata_csum(fs->super))
		fs->super->s_checksum_type = EXT2_CRC32C_CHKSUM;
	else
		fs->super->s_checksum_type = 0;
	ext2fs_mark_super_dirty(fs);
}

static void enable_uninit_bg(ext2_filsys fs)
{
	struct ext2_group_desc *gd;
	dgrp_t i;

	for (i = 0; i < fs->group_desc_count; i++) {
		gd = ext2fs_group_desc(fs, fs->group_desc, i);
		gd->bg_itable_unused = 0;
		gd->bg_flags = EXT2_BG_INODE_ZEROED;
		ext2fs_group_desc_csum_set(fs, i);
	}
	fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
}

static errcode_t zero_empty_inodes(ext2_filsys fs)
{
	int length = EXT2_INODE_SIZE(fs->super);
	struct ext2_inode *inode = NULL;
	ext2_inode_scan	scan;
	errcode_t	retval;
	ext2_ino_t	ino;

	retval = ext2fs_open_inode_scan(fs, 0, &scan);
	if (retval)
		goto out;

	retval = ext2fs_get_mem(length, &inode);
	if (retval)
		goto out;

	do {
		retval = ext2fs_get_next_inode_full(scan, &ino, inode, length);
		if (retval)
			goto out;
		if (!ino)
			break;
		if (!ext2fs_test_inode_bitmap2(fs->inode_map, ino)) {
			memset(inode, 0, length);
			retval = ext2fs_write_inode_full(fs, ino, inode,
							 length);
			if (retval)
				goto out;
		}
	} while (1);

out:
	ext2fs_free_mem(&inode);
	ext2fs_close_inode_scan(scan);
	return retval;
}

static errcode_t disable_uninit_bg(ext2_filsys fs, __u32 csum_feature_flag)
{
	struct ext2_group_desc *gd;
	dgrp_t i;
	errcode_t retval;
	blk64_t b, c, d;

	/* Load bitmaps to ensure that the uninit ones get written out */
	fs->super->s_feature_ro_compat |= csum_feature_flag;
	retval = ext2fs_read_bitmaps(fs);
	fs->super->s_feature_ro_compat &= ~csum_feature_flag;
	if (retval) {
		com_err("disable_uninit_bg", retval,
			"while reading bitmaps");
		request_fsck_afterwards(fs);
		return retval;
	}
	ext2fs_mark_ib_dirty(fs);
	ext2fs_mark_bb_dirty(fs);

	/* If we're only turning off uninit_bg, zero the inodes */
	if (csum_feature_flag == EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
		retval = zero_empty_inodes(fs);
		if (retval) {
			com_err("disable_uninit_bg", retval,
				"while zeroing unused inodes");
			request_fsck_afterwards(fs);
			return retval;
		}
	}

	/* The bbitmap is zeroed; we must mark group metadata blocks in use */
	for (i = 0; i < fs->group_desc_count; i++) {
		b = ext2fs_block_bitmap_loc(fs, i);
		ext2fs_mark_block_bitmap2(fs->block_map, b);
		b = ext2fs_inode_bitmap_loc(fs, i);
		ext2fs_mark_block_bitmap2(fs->block_map, b);

		retval = ext2fs_super_and_bgd_loc2(fs, i, &b, &c, &d, NULL);
		if (retval == 0 && b)
			ext2fs_mark_block_bitmap2(fs->block_map, b);
		if (retval == 0 && c)
			ext2fs_mark_block_bitmap2(fs->block_map, c);
		if (retval == 0 && d)
			ext2fs_mark_block_bitmap2(fs->block_map, d);
		if (retval) {
			com_err("disable_uninit_bg", retval,
				"while initializing block bitmaps");
			request_fsck_afterwards(fs);
		}

		gd = ext2fs_group_desc(fs, fs->group_desc, i);
		gd->bg_itable_unused = 0;
		gd->bg_flags = 0;
		ext2fs_group_desc_csum_set(fs, i);
	}
	fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	ext2fs_mark_super_dirty(fs);

	return 0;
}

static void
try_confirm_csum_seed_support(void)
{
	if (access("/sys/fs/ext4/features/metadata_csum_seed", R_OK))
		fputs(_("WARNING: Could not confirm kernel support for "
			"metadata_csum_seed.\n  This requires Linux >= "
			"v4.4.\n"), stderr);
}

/*
 * Update the feature set as provided by the user.
 */
static int update_feature_set(ext2_filsys fs, char *features)
{
	struct ext2_super_block *sb = fs->super;
	__u32		old_features[3];
	int		type_err;
	unsigned int	mask_err;
	errcode_t	err;
	enum quota_type qtype;

#define FEATURE_ON(type, mask) (!(old_features[(type)] & (mask)) && \
				((&sb->s_feature_compat)[(type)] & (mask)))
#define FEATURE_OFF(type, mask) ((old_features[(type)] & (mask)) && \
				 !((&sb->s_feature_compat)[(type)] & (mask)))
#define FEATURE_CHANGED(type, mask) ((mask) & \
		     (old_features[(type)] ^ (&sb->s_feature_compat)[(type)]))

	old_features[E2P_FEATURE_COMPAT] = sb->s_feature_compat;
	old_features[E2P_FEATURE_INCOMPAT] = sb->s_feature_incompat;
	old_features[E2P_FEATURE_RO_INCOMPAT] = sb->s_feature_ro_compat;

	if (e2p_edit_feature2(features, &sb->s_feature_compat,
			      ok_features, clear_ok_features,
			      &type_err, &mask_err)) {
		if (!mask_err)
			fprintf(stderr,
				_("Invalid filesystem option set: %s\n"),
				features);
		else if (type_err & E2P_FEATURE_NEGATE_FLAG)
			fprintf(stderr, _("Clearing filesystem feature '%s' "
					  "not supported.\n"),
				e2p_feature2string(type_err &
						   E2P_FEATURE_TYPE_MASK,
						   mask_err));
		else
			fprintf(stderr, _("Setting filesystem feature '%s' "
					  "not supported.\n"),
				e2p_feature2string(type_err, mask_err));
		return 1;
	}

	if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
		if ((mount_flags & EXT2_MF_MOUNTED) &&
		    !(mount_flags & EXT2_MF_READONLY)) {
			fputs(_("The has_journal feature may only be "
				"cleared when the filesystem is\n"
				"unmounted or mounted "
				"read-only.\n"), stderr);
			return 1;
		}
		if (ext2fs_has_feature_journal_needs_recovery(sb) &&
		    f_flag < 2) {
			fputs(_("The needs_recovery flag is set.  "
				"Please run e2fsck before clearing\n"
				"the has_journal flag.\n"), stderr);
			return 1;
		}
		if (sb->s_journal_inum) {
			if (remove_journal_inode(fs))
				return 1;
		}
		if (sb->s_journal_dev) {
			if (remove_journal_device(fs))
				return 1;
		}
	}

	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
		EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
		if (ext2fs_has_feature_meta_bg(sb)) {
			fputs(_("Setting filesystem feature 'sparse_super' "
				"not supported\nfor filesystems with "
				"the meta_bg feature enabled.\n"),
				stderr);
			return 1;
		}
	}

	if (FEATURE_ON(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP)) {
		int error;

		if ((mount_flags & EXT2_MF_MOUNTED) ||
		    (mount_flags & EXT2_MF_READONLY)) {
			fputs(_("The multiple mount protection feature can't\n"
				"be set if the filesystem is mounted or\n"
				"read-only.\n"), stderr);
			return 1;
		}

		error = ext2fs_mmp_init(fs);
		if (error) {
			fputs(_("\nError while enabling multiple mount "
				"protection feature."), stderr);
			return 1;
		}

		/*
		 * We want to update group desc with the new free blocks count
		 */
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;

		printf(_("Multiple mount protection has been enabled "
			 "with update interval %ds.\n"),
		       sb->s_mmp_update_interval);
	}

	if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP)) {
		int error;

		if (mount_flags & EXT2_MF_READONLY) {
			fputs(_("The multiple mount protection feature cannot\n"
				"be disabled if the filesystem is readonly.\n"),
				stderr);
			return 1;
		}

		error = ext2fs_read_bitmaps(fs);
		if (error) {
			fputs(_("Error while reading bitmaps\n"), stderr);
			return 1;
		}

		error = ext2fs_mmp_read(fs, sb->s_mmp_block, NULL);
		if (error) {
			struct mmp_struct *mmp_cmp = fs->mmp_cmp;

			if (error == EXT2_ET_MMP_MAGIC_INVALID)
				printf(_("Magic number in MMP block does not "
					 "match. expected: %x, actual: %x\n"),
					 EXT4_MMP_MAGIC, mmp_cmp->mmp_magic);
			else
				com_err(program_name, error, "%s",
					_("while reading MMP block."));
			goto mmp_error;
		}

		/* We need to force out the group descriptors as well */
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
		ext2fs_block_alloc_stats2(fs, sb->s_mmp_block, -1);
mmp_error:
		sb->s_mmp_block = 0;
		sb->s_mmp_update_interval = 0;
	}

	if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
		/*
		 * If adding a journal flag, let the create journal
		 * code below handle setting the flag and creating the
		 * journal.  We supply a default size if necessary.
		 */
		if (!journal_size)
			journal_size = -1;
		ext2fs_clear_feature_journal(sb);
	}

	if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX)) {
		if (!sb->s_def_hash_version)
			sb->s_def_hash_version = EXT2_HASH_HALF_MD4;
		if (uuid_is_null((unsigned char *) sb->s_hash_seed))
			uuid_generate((unsigned char *) sb->s_hash_seed);
	}

	if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
		if (ext2fs_check_desc(fs)) {
			fputs(_("Clearing the flex_bg flag would "
				"cause the the filesystem to be\n"
				"inconsistent.\n"), stderr);
			return 1;
		}
	}

	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
			    EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
		if ((mount_flags & EXT2_MF_MOUNTED) &&
		    !(mount_flags & EXT2_MF_READONLY)) {
			fputs(_("The huge_file feature may only be "
				"cleared when the filesystem is\n"
				"unmounted or mounted "
				"read-only.\n"), stderr);
			return 1;
		}
	}

	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
		       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
		check_fsck_needed(fs,
			_("Enabling checksums could take some time."));
		if (mount_flags & EXT2_MF_MOUNTED) {
			fputs(_("Cannot enable metadata_csum on a mounted "
				"filesystem!\n"), stderr);
			exit(1);
		}
		if (!ext2fs_has_feature_extents(fs->super))
			printf("%s",
			       _("Extents are not enabled.  The file extent "
				 "tree can be checksummed, whereas block maps "
				 "cannot.  Not enabling extents reduces the "
				 "coverage of metadata checksumming.  "
				 "Re-run with -O extent to rectify.\n"));
		if (!ext2fs_has_feature_64bit(fs->super))
			printf("%s",
			       _("64-bit filesystem support is not enabled.  "
				 "The larger fields afforded by this feature "
				 "enable full-strength checksumming.  "
				 "Run resize2fs -b to rectify.\n"));
		rewrite_checksums = 1;
		/* metadata_csum supersedes uninit_bg */
		ext2fs_clear_feature_gdt_csum(fs->super);

		/* if uninit_bg was previously off, rewrite group desc */
		if (!(old_features[E2P_FEATURE_RO_INCOMPAT] &
		      EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
			enable_uninit_bg(fs);

		/*
		 * Since metadata_csum supersedes uninit_bg, pretend like
		 * uninit_bg has been off all along.
		 */
		old_features[E2P_FEATURE_RO_INCOMPAT] &=
			~EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
	}

	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
			EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
		__u32	test_features[3];

		check_fsck_needed(fs,
			_("Disabling checksums could take some time."));
		if (mount_flags & EXT2_MF_MOUNTED) {
			fputs(_("Cannot disable metadata_csum on a mounted "
				"filesystem!\n"), stderr);
			exit(1);
		}
		rewrite_checksums = 1;

		/* Enable uninit_bg unless the user expressly turned it off */
		memcpy(test_features, old_features, sizeof(test_features));
		test_features[E2P_FEATURE_RO_INCOMPAT] |=
						EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
		e2p_edit_feature2(features, test_features, ok_features,
				  clear_ok_features, NULL, NULL);
		if (test_features[E2P_FEATURE_RO_INCOMPAT] &
						EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
			ext2fs_set_feature_gdt_csum(fs->super);

		/*
		 * If we're turning off metadata_csum and not turning on
		 * uninit_bg, rewrite group desc.
		 */
		if (!ext2fs_has_feature_gdt_csum(fs->super)) {
			err = disable_uninit_bg(fs,
					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM);
			if (err)
				return 1;
		} else
			/*
			 * metadata_csum previously provided uninit_bg, so if
			 * we're also setting the uninit_bg feature bit,
			 * pretend like it was previously enabled.  Checksums
			 * will be rewritten with crc16 later.
			 */
			old_features[E2P_FEATURE_RO_INCOMPAT] |=
				EXT4_FEATURE_RO_COMPAT_GDT_CSUM;
		fs->super->s_checksum_seed = 0;
		ext2fs_clear_feature_csum_seed(fs->super);
	}

	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
		       EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
		/* Do not enable uninit_bg when metadata_csum enabled */
		if (ext2fs_has_feature_metadata_csum(fs->super))
			ext2fs_clear_feature_gdt_csum(fs->super);
		else
			enable_uninit_bg(fs);
	}

	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
			EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
		err = disable_uninit_bg(fs,
				EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
		if (err)
			return 1;
	}

	/*
	 * We don't actually toggle 64bit; resize2fs does that.  But this
	 * must come after the metadata_csum feature_on so that it won't
	 * complain about the lack of 64bit.
	 */
	if (FEATURE_ON(E2P_FEATURE_INCOMPAT,
		       EXT4_FEATURE_INCOMPAT_64BIT)) {
		if (mount_flags & EXT2_MF_MOUNTED) {
			fprintf(stderr, _("Cannot enable 64-bit mode "
					  "while mounted!\n"));
			exit(1);
		}
		ext2fs_clear_feature_64bit(sb);
		feature_64bit = 1;
	}
	if (FEATURE_OFF(E2P_FEATURE_INCOMPAT,
			EXT4_FEATURE_INCOMPAT_64BIT)) {
		if (mount_flags & EXT2_MF_MOUNTED) {
			fprintf(stderr, _("Cannot disable 64-bit mode "
					  "while mounted!\n"));
			exit(1);
		}
		ext2fs_set_feature_64bit(sb);
		feature_64bit = -1;
	}

	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
				EXT4_FEATURE_RO_COMPAT_QUOTA)) {
		/*
		 * Set the Q_flag here and handle the quota options in the code
		 * below.
		 */
		if (!Q_flag) {
			Q_flag = 1;
			/* Enable usr/grp quota by default */
			for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
				if (qtype != PRJQUOTA)
					quota_enable[qtype] = QOPT_ENABLE;
				else
					quota_enable[qtype] = QOPT_DISABLE;
			}
		}
		ext2fs_clear_feature_quota(sb);
	}

	if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
		       EXT4_FEATURE_RO_COMPAT_PROJECT)) {
		if (fs->super->s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
			fprintf(stderr, _("Cannot enable project feature; "
					  "inode size too small.\n"));
			exit(1);
		}
		Q_flag = 1;
		quota_enable[PRJQUOTA] = QOPT_ENABLE;
	}

	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
			EXT4_FEATURE_RO_COMPAT_PROJECT)) {
		Q_flag = 1;
		quota_enable[PRJQUOTA] = QOPT_DISABLE;
	}

	if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
				EXT4_FEATURE_RO_COMPAT_QUOTA)) {
		/*
		 * Set the Q_flag here and handle the quota options in the code
		 * below.
		 */
		if (Q_flag)
			fputs(_("\nWarning: '^quota' option overrides '-Q'"
				"arguments.\n"), stderr);
		Q_flag = 1;
		/* Disable all quota by default */
		for (qtype = 0; qtype < MAXQUOTAS; qtype++)
			quota_enable[qtype] = QOPT_DISABLE;
	}

	if (FEATURE_ON(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_ENCRYPT)) {
		fs->super->s_encrypt_algos[0] =
			EXT4_ENCRYPTION_MODE_AES_256_XTS;
		fs->super->s_encrypt_algos[1] =
			EXT4_ENCRYPTION_MODE_AES_256_CTS;
	}

	if (FEATURE_ON(E2P_FEATURE_INCOMPAT,
		EXT4_FEATURE_INCOMPAT_CSUM_SEED)) {
		if (!ext2fs_has_feature_metadata_csum(sb)) {
			fputs(_("Setting feature 'metadata_csum_seed' "
				"is only supported\non filesystems with "
				"the metadata_csum feature enabled.\n"),
				stderr);
			return 1;
		}
		try_confirm_csum_seed_support();
		fs->super->s_checksum_seed = fs->csum_seed;
	}

	if (FEATURE_OFF(E2P_FEATURE_INCOMPAT,
		EXT4_FEATURE_INCOMPAT_CSUM_SEED)) {
		__le32 uuid_seed;

		uuid_seed = ext2fs_crc32c_le(~0, fs->super->s_uuid,
					sizeof(fs->super->s_uuid));
		if (fs->super->s_checksum_seed != uuid_seed) {
			if (mount_flags & (EXT2_MF_BUSY|EXT2_MF_MOUNTED)) {
				fputs(_("UUID has changed since enabling "
		"metadata_csum.  Filesystem must be unmounted "
		"\nto safely rewrite all metadata to match the new UUID.\n"),
				      stderr);
				return 1;
			}
			check_fsck_needed(fs, _("Recalculating checksums "
						"could take some time."));
			rewrite_checksums = 1;
		}
	}

	if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
	    (sb->s_feature_compat || sb->s_feature_ro_compat ||
	     sb->s_feature_incompat))
		ext2fs_update_dynamic_rev(fs);

	if (FEATURE_CHANGED(E2P_FEATURE_RO_INCOMPAT,
			    EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
	    FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
			EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
	    FEATURE_CHANGED(E2P_FEATURE_INCOMPAT,
			    EXT2_FEATURE_INCOMPAT_FILETYPE) ||
	    FEATURE_CHANGED(E2P_FEATURE_COMPAT,
			    EXT2_FEATURE_COMPAT_RESIZE_INODE) ||
	    FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
			EXT2_FEATURE_RO_COMPAT_LARGE_FILE))
		request_fsck_afterwards(fs);

	if ((old_features[E2P_FEATURE_COMPAT] != sb->s_feature_compat) ||
	    (old_features[E2P_FEATURE_INCOMPAT] != sb->s_feature_incompat) ||
	    (old_features[E2P_FEATURE_RO_INCOMPAT] != sb->s_feature_ro_compat))
		ext2fs_mark_super_dirty(fs);

	return 0;
}

/*
 * Add a journal to the filesystem.
 */
static int add_journal(ext2_filsys fs)
{
	unsigned long journal_blocks;
	errcode_t	retval;
	ext2_filsys	jfs;
	io_manager	io_ptr;

	if (ext2fs_has_feature_journal(fs->super)) {
		fputs(_("The filesystem already has a journal.\n"), stderr);
		goto err;
	}
	if (journal_device) {
		if (!check_plausibility(journal_device, CHECK_BLOCK_DEV,
					NULL))
			proceed_question(-1);
		check_mount(journal_device, 0, _("journal"));
#ifdef CONFIG_TESTIO_DEBUG
		if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
			io_ptr = test_io_manager;
			test_io_backing_manager = unix_io_manager;
		} else
#endif
			io_ptr = unix_io_manager;
		retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
				     EXT2_FLAG_JOURNAL_DEV_OK, 0,
				     fs->blocksize, io_ptr, &jfs);
		if (retval) {
			com_err(program_name, retval,
				_("\n\twhile trying to open journal on %s\n"),
				journal_device);
			goto err;
		}
		printf(_("Creating journal on device %s: "),
		       journal_device);
		fflush(stdout);

		retval = ext2fs_add_journal_device(fs, jfs);
		ext2fs_close_free(&jfs);
		if (retval) {
			com_err(program_name, retval,
				_("while adding filesystem to journal on %s"),
				journal_device);
			goto err;
		}
		fputs(_("done\n"), stdout);
	} else if (journal_size) {
		fputs(_("Creating journal inode: "), stdout);
		fflush(stdout);
		journal_blocks = figure_journal_size(journal_size, fs);

		if (journal_location_string)
			journal_location =
				parse_num_blocks2(journal_location_string,
						  fs->super->s_log_block_size);
		retval = ext2fs_add_journal_inode2(fs, journal_blocks,
						   journal_location,
						   journal_flags);
		if (retval) {
			fprintf(stderr, "\n");
			com_err(program_name, retval, "%s",
				_("\n\twhile trying to create journal file"));
			return retval;
		} else
			fputs(_("done\n"), stdout);
		/*
		 * If the filesystem wasn't mounted, we need to force
		 * the block group descriptors out.
		 */
		if ((mount_flags & EXT2_MF_MOUNTED) == 0)
			fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	}
	print_check_message(fs->super->s_max_mnt_count,
			    fs->super->s_checkinterval);
	return 0;

err:
	free(journal_device);
	return 1;
}

static void handle_quota_options(ext2_filsys fs)
{
	errcode_t retval;
	quota_ctx_t qctx;
	ext2_ino_t qf_ino;
	enum quota_type qtype;
	unsigned int qtype_bits = 0;
	int need_dirty = 0;

	for (qtype = 0 ; qtype < MAXQUOTAS; qtype++)
		if (quota_enable[qtype] != 0)
			break;
	if (qtype == MAXQUOTAS)
		/* Nothing to do. */
		return;

	if (quota_enable[PRJQUOTA] == QOPT_ENABLE &&
	    fs->super->s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
		fprintf(stderr, _("Cannot enable project quota; "
				  "inode size too small.\n"));
		exit(1);
	}

	for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
		if (quota_enable[qtype] == QOPT_ENABLE)
			qtype_bits |= 1 << qtype;
	}

	retval = quota_init_context(&qctx, fs, qtype_bits);
	if (retval) {
		com_err(program_name, retval,
			_("while initializing quota context in support library"));
		exit(1);
	}

	if (qtype_bits)
		quota_compute_usage(qctx);

	for (qtype = 0 ; qtype < MAXQUOTAS; qtype++) {
		if (quota_enable[qtype] == QOPT_ENABLE &&
		    *quota_sb_inump(fs->super, qtype) == 0) {
			if ((qf_ino = quota_file_exists(fs, qtype)) > 0) {
				retval = quota_update_limits(qctx, qf_ino,
							     qtype);
				if (retval) {
					com_err(program_name, retval,
						_("while updating quota limits (%d)"),
						qtype);
					exit(1);
				}
			}
			retval = quota_write_inode(qctx, 1 << qtype);
			if (retval) {
				com_err(program_name, retval,
					_("while writing quota file (%d)"),
					qtype);
				exit(1);
			}
			/* Enable Quota feature if one of quota enabled */
			if (!ext2fs_has_feature_quota(fs->super)) {
				ext2fs_set_feature_quota(fs->super);
				need_dirty = 1;
			}
			if (qtype == PRJQUOTA &&
			    !ext2fs_has_feature_project(fs->super)) {
				ext2fs_set_feature_project(fs->super);
				need_dirty = 1;
			}
		} else if (quota_enable[qtype] == QOPT_DISABLE) {
			retval = quota_remove_inode(fs, qtype);
			if (retval) {
				com_err(program_name, retval,
					_("while removing quota file (%d)"),
					qtype);
				exit(1);
			}
			if (qtype == PRJQUOTA) {
				ext2fs_clear_feature_project(fs->super);
				need_dirty = 1;
			}
		}
	}

	quota_release_context(&qctx);
	/* Clear Quota feature if all quota types disabled. */
	if (!qtype_bits) {
		for (qtype = 0 ; qtype < MAXQUOTAS; qtype++)
			if (*quota_sb_inump(fs->super, qtype))
				break;
		if (qtype == MAXQUOTAS) {
			ext2fs_clear_feature_quota(fs->super);
			need_dirty = 1;
		}

	}
	if (need_dirty)
		ext2fs_mark_super_dirty(fs);
	return;
}

static int option_handle_function(char *token)
{
	if (strncmp(token, "usr", 3) == 0) {
		quota_enable[USRQUOTA] = QOPT_ENABLE;
	} else if (strncmp(token, "^usr", 4) == 0) {
		quota_enable[USRQUOTA] = QOPT_DISABLE;
	} else if (strncmp(token, "grp", 3) == 0) {
		quota_enable[GRPQUOTA] = QOPT_ENABLE;
	} else if (strncmp(token, "^grp", 4) == 0) {
		quota_enable[GRPQUOTA] = QOPT_DISABLE;
	} else if (strncmp(token, "prj", 3) == 0) {
		quota_enable[PRJQUOTA] = QOPT_ENABLE;
	} else if (strncmp(token, "^prj", 4) == 0) {
		quota_enable[PRJQUOTA] = QOPT_DISABLE;
	} else {
		fputs(_("\nBad quota options specified.\n\n"
			"Following valid quota options are available "
			"(pass by separating with comma):\n"
			"\t[^]usr[quota]\n"
			"\t[^]grp[quota]\n"
			"\t[^]prj[quota]\n"
			"\n\n"), stderr);
		return 1;
	}
	return 0;
}

static void parse_e2label_options(int argc, char ** argv)
{
	if ((argc < 2) || (argc > 3)) {
		fputs(_("Usage: e2label device [newlabel]\n"), stderr);
		exit(1);
	}
	io_options = strchr(argv[1], '?');
	if (io_options)
		*io_options++ = 0;
	device_name = blkid_get_devname(NULL, argv[1], NULL);
	if (!device_name) {
		com_err("e2label", 0, _("Unable to resolve '%s'"),
			argv[1]);
		exit(1);
	}
	open_flag = EXT2_FLAG_JOURNAL_DEV_OK;
	if (argc == 3) {
		open_flag |= EXT2_FLAG_RW;
		L_flag = 1;
		new_label = argv[2];
	} else
		print_label++;
}

static time_t parse_time(char *str)
{
	struct	tm	ts;

	if (strcmp(str, "now") == 0) {
		return (time(0));
	}
	memset(&ts, 0, sizeof(ts));
#ifdef HAVE_STRPTIME
	strptime(str, "%Y%m%d%H%M%S", &ts);
#else
	sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
	       &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
	ts.tm_year -= 1900;
	ts.tm_mon -= 1;
	if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
	    ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
	    ts.tm_min > 59 || ts.tm_sec > 61)
		ts.tm_mday = 0;
#endif
	if (ts.tm_mday == 0) {
		com_err(program_name, 0,
			_("Couldn't parse date/time specifier: %s"),
			str);
		usage();
	}
	ts.tm_isdst = -1;
	return (mktime(&ts));
}

static void parse_tune2fs_options(int argc, char **argv)
{
	int c;
	char *tmp;
	struct group *gr;
	struct passwd *pw;
	int ret;
	char optstring[100] = "c:e:fg:i:jlm:o:r:s:u:C:E:I:J:L:M:O:T:U:z:Q:";

	open_flag = 0;
	printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
	while ((c = getopt(argc, argv, optstring)) != EOF)
		switch (c) {
		case 'c':
			max_mount_count = strtol(optarg, &tmp, 0);
			if (*tmp || max_mount_count > 16000) {
				com_err(program_name, 0,
					_("bad mounts count - %s"),
					optarg);
				usage();
			}
			if (max_mount_count == 0)
				max_mount_count = -1;
			c_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'C':
			mount_count = strtoul(optarg, &tmp, 0);
			if (*tmp || mount_count > 16000) {
				com_err(program_name, 0,
					_("bad mounts count - %s"),
					optarg);
				usage();
			}
			C_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'e':
			if (strcmp(optarg, "continue") == 0)
				errors = EXT2_ERRORS_CONTINUE;
			else if (strcmp(optarg, "remount-ro") == 0)
				errors = EXT2_ERRORS_RO;
			else if (strcmp(optarg, "panic") == 0)
				errors = EXT2_ERRORS_PANIC;
			else {
				com_err(program_name, 0,
					_("bad error behavior - %s"),
					optarg);
				usage();
			}
			e_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'E':
			extended_cmd = optarg;
			open_flag |= EXT2_FLAG_RW;
			break;
		case 'f': /* Force */
			f_flag++;
			break;
		case 'g':
			resgid = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				gr = getgrnam(optarg);
				if (gr == NULL)
					tmp = optarg;
				else {
					resgid = gr->gr_gid;
					*tmp = 0;
				}
			}
			if (*tmp) {
				com_err(program_name, 0,
					_("bad gid/group name - %s"),
					optarg);
				usage();
			}
			g_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'i':
			interval = strtoul(optarg, &tmp, 0);
			switch (*tmp) {
			case 's':
				tmp++;
				break;
			case '\0':
			case 'd':
			case 'D': /* days */
				interval *= 86400;
				if (*tmp != '\0')
					tmp++;
				break;
			case 'm':
			case 'M': /* months! */
				interval *= 86400 * 30;
				tmp++;
				break;
			case 'w':
			case 'W': /* weeks */
				interval *= 86400 * 7;
				tmp++;
				break;
			}
			if (*tmp) {
				com_err(program_name, 0,
					_("bad interval - %s"), optarg);
				usage();
			}
			i_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'j':
			if (!journal_size)
				journal_size = -1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'J':
			parse_journal_opts(optarg);
			open_flag = EXT2_FLAG_RW;
			break;
		case 'l':
			l_flag = 1;
			break;
		case 'L':
			new_label = optarg;
			L_flag = 1;
			open_flag |= EXT2_FLAG_RW |
				EXT2_FLAG_JOURNAL_DEV_OK;
			break;
		case 'm':
			reserved_ratio = strtod(optarg, &tmp);
			if (*tmp || reserved_ratio > 50 ||
			    reserved_ratio < 0) {
				com_err(program_name, 0,
					_("bad reserved block ratio - %s"),
					optarg);
				usage();
			}
			m_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'M':
			new_last_mounted = optarg;
			M_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'o':
			if (mntopts_cmd) {
				com_err(program_name, 0, "%s",
					_("-o may only be specified once"));
				usage();
			}
			mntopts_cmd = optarg;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'O':
			if (features_cmd) {
				com_err(program_name, 0, "%s",
					_("-O may only be specified once"));
				usage();
			}
			features_cmd = optarg;
			open_flag = EXT2_FLAG_RW;
			break;
		case 'Q':
			Q_flag = 1;
			ret = parse_quota_opts(optarg, option_handle_function);
			if (ret)
				exit(1);
			open_flag = EXT2_FLAG_RW;
			break;
		case 'r':
			reserved_blocks = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(program_name, 0,
					_("bad reserved blocks count - %s"),
					optarg);
				usage();
			}
			r_flag = 1;
			open_flag = EXT2_FLAG_RW;
			break;
		case 's': /* Deprecated */
			s_flag = atoi(optarg);
			open_flag = EXT2_FLAG_RW;
			break;
		case 'T':
			T_flag = 1;
			last_check_time = parse_time(optarg);
			open_flag = EXT2_FLAG_RW;
			break;
		case 'u':
				resuid = strtoul(optarg, &tmp, 0);
				if (*tmp) {
					pw = getpwnam(optarg);
					if (pw == NULL)
						tmp = optarg;
					else {
						resuid = pw->pw_uid;
						*tmp = 0;
					}
				}
				if (*tmp) {
					com_err(program_name, 0,
						_("bad uid/user name - %s"),
						optarg);
					usage();
				}
				u_flag = 1;
				open_flag = EXT2_FLAG_RW;
				break;
		case 'U':
			new_UUID = optarg;
			U_flag = 1;
			open_flag = EXT2_FLAG_RW |
				EXT2_FLAG_JOURNAL_DEV_OK;
			break;
		case 'I':
			new_inode_size = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(program_name, 0,
					_("bad inode size - %s"),
					optarg);
				usage();
			}
			if (!((new_inode_size &
			       (new_inode_size - 1)) == 0)) {
				com_err(program_name, 0,
					_("Inode size must be a "
					  "power of two- %s"),
					optarg);
				usage();
			}
			open_flag = EXT2_FLAG_RW;
			I_flag = 1;
			break;
		case 'z':
			undo_file = optarg;
			break;
		default:
			usage();
		}
	if (optind < argc - 1 || optind == argc)
		usage();
	if (!open_flag && !l_flag)
		usage();
	io_options = strchr(argv[optind], '?');
	if (io_options)
		*io_options++ = 0;
	device_name = blkid_get_devname(NULL, argv[optind], NULL);
	if (!device_name) {
		com_err(program_name, 0, _("Unable to resolve '%s'"),
			argv[optind]);
		exit(1);
	}
}

#ifdef CONFIG_BUILD_FINDFS
void do_findfs(int argc, char **argv)
{
	char	*dev;

	if ((argc != 2) ||
	    (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5))) {
		fprintf(stderr, "Usage: findfs LABEL=<label>|UUID=<uuid>\n");
		exit(2);
	}
	dev = blkid_get_devname(NULL, argv[1], NULL);
	if (!dev) {
		com_err("findfs", 0, _("Unable to resolve '%s'"),
			argv[1]);
		exit(1);
	}
	puts(dev);
	exit(0);
}
#endif

static int parse_extended_opts(ext2_filsys fs, const char *opts)
{
	char	*buf, *token, *next, *p, *arg;
	int	len, hash_alg;
	int	r_usage = 0;

	len = strlen(opts);
	buf = malloc(len+1);
	if (!buf) {
		fprintf(stderr, "%s",
			_("Couldn't allocate memory to parse options!\n"));
		return 1;
	}
	strcpy(buf, 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, "clear-mmp") == 0 ||
		    strcmp(token, "clear_mmp") == 0) {
			clear_mmp = 1;
		} else if (strcmp(token, "mmp_update_interval") == 0) {
			unsigned long intv;
			if (!arg) {
				r_usage++;
				continue;
			}
			intv = strtoul(arg, &p, 0);
			if (*p) {
				fprintf(stderr,
					_("Invalid mmp_update_interval: %s\n"),
					arg);
				r_usage++;
				continue;
			}
			if (intv == 0) {
				intv = EXT4_MMP_UPDATE_INTERVAL;
			} else if (intv > EXT4_MMP_MAX_UPDATE_INTERVAL) {
				fprintf(stderr,
					_("mmp_update_interval too big: %lu\n"),
					intv);
				r_usage++;
				continue;
			}
			printf(P_("Setting multiple mount protection update "
				  "interval to %lu second\n",
				  "Setting multiple mount protection update "
				  "interval to %lu seconds\n", intv),
			       intv);
			fs->super->s_mmp_update_interval = intv;
			ext2fs_mark_super_dirty(fs);
		} else if (!strcmp(token, "test_fs")) {
			fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS;
			printf("Setting test filesystem flag\n");
			ext2fs_mark_super_dirty(fs);
		} else if (!strcmp(token, "^test_fs")) {
			fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS;
			printf("Clearing test filesystem flag\n");
			ext2fs_mark_super_dirty(fs);
		} else if (strcmp(token, "stride") == 0) {
			if (!arg) {
				r_usage++;
				continue;
			}
			stride = strtoul(arg, &p, 0);
			if (*p) {
				fprintf(stderr,
					_("Invalid RAID stride: %s\n"),
					arg);
				r_usage++;
				continue;
			}
			stride_set = 1;
		} else if (strcmp(token, "stripe-width") == 0 ||
			   strcmp(token, "stripe_width") == 0) {
			if (!arg) {
				r_usage++;
				continue;
			}
			stripe_width = strtoul(arg, &p, 0);
			if (*p) {
				fprintf(stderr,
					_("Invalid RAID stripe-width: %s\n"),
					arg);
				r_usage++;
				continue;
			}
			stripe_width_set = 1;
		} else if (strcmp(token, "hash_alg") == 0 ||
			   strcmp(token, "hash-alg") == 0) {
			if (!arg) {
				r_usage++;
				continue;
			}
			hash_alg = e2p_string2hash(arg);
			if (hash_alg < 0) {
				fprintf(stderr,
					_("Invalid hash algorithm: %s\n"),
					arg);
				r_usage++;
				continue;
			}
			fs->super->s_def_hash_version = hash_alg;
			printf(_("Setting default hash algorithm "
				 "to %s (%d)\n"),
			       arg, hash_alg);
			ext2fs_mark_super_dirty(fs);
		} else if (!strcmp(token, "mount_opts")) {
			if (!arg) {
				r_usage++;
				continue;
			}
			if (strlen(arg) >= sizeof(fs->super->s_mount_opts)) {
				fprintf(stderr,
					"Extended mount options too long\n");
				continue;
			}
			ext_mount_opts = strdup(arg);
		} else
			r_usage++;
	}
	if (r_usage) {
		fprintf(stderr, "%s", _("\nBad options specified.\n\n"
			"Extended options are separated by commas, "
			"and may take an argument which\n"
			"\tis set off by an equals ('=') sign.\n\n"
			"Valid extended options are:\n"
			"\tclear_mmp\n"
			"\thash_alg=<hash algorithm>\n"
			"\tmount_opts=<extended default mount options>\n"
			"\tmmp_update_interval=<mmp update interval in seconds>\n"
			"\tstride=<RAID per-disk chunk size in blocks>\n"
			"\tstripe_width=<RAID stride*data disks in blocks>\n"
			"\ttest_fs\n"
			"\t^test_fs\n"));
		free(buf);
		return 1;
	}
	free(buf);

	return 0;
}

/*
 * Fill in the block bitmap bmap with the information regarding the
 * blocks to be moved
 */
static int get_move_bitmaps(ext2_filsys fs, int new_ino_blks_per_grp,
			    ext2fs_block_bitmap bmap)
{
	dgrp_t i;
	int retval;
	ext2_badblocks_list bb_list = 0;
	blk64_t j, needed_blocks = 0;
	blk64_t start_blk, end_blk;

	retval = ext2fs_read_bb_inode(fs, &bb_list);
	if (retval)
		return retval;

	for (i = 0; i < fs->group_desc_count; i++) {
		start_blk = ext2fs_inode_table_loc(fs, i) +
					fs->inode_blocks_per_group;

		end_blk = ext2fs_inode_table_loc(fs, i) +
					new_ino_blks_per_grp;

		for (j = start_blk; j < end_blk; j++) {
			if (ext2fs_test_block_bitmap2(fs->block_map, j)) {
				/*
				 * IF the block is a bad block we fail
				 */
				if (ext2fs_badblocks_list_test(bb_list, j)) {
					ext2fs_badblocks_list_free(bb_list);
					return ENOSPC;
				}

				ext2fs_mark_block_bitmap2(bmap, j);
			} else {
				/*
				 * We are going to use this block for
				 * inode table. So mark them used.
				 */
				ext2fs_mark_block_bitmap2(fs->block_map, j);
			}
		}
		needed_blocks += end_blk - start_blk;
	}

	ext2fs_badblocks_list_free(bb_list);
	if (needed_blocks > ext2fs_free_blocks_count(fs->super))
		return ENOSPC;

	return 0;
}

static int ext2fs_is_meta_block(ext2_filsys fs, blk64_t blk)
{
	dgrp_t group;
	group = ext2fs_group_of_blk2(fs, blk);
	if (ext2fs_block_bitmap_loc(fs, group) == blk)
		return 1;
	if (ext2fs_inode_bitmap_loc(fs, group) == blk)
		return 1;
	return 0;
}

static int ext2fs_is_block_in_group(ext2_filsys fs, dgrp_t group, blk64_t blk)
{
	blk64_t start_blk, end_blk;
	start_blk = fs->super->s_first_data_block +
			EXT2_GROUPS_TO_BLOCKS(fs->super, group);
	/*
	 * We cannot get new block beyond end_blk for for the last block group
	 * so we can check with EXT2_BLOCKS_PER_GROUP even for last block group
	 */
	end_blk   = start_blk + EXT2_BLOCKS_PER_GROUP(fs->super);
	if (blk >= start_blk && blk <= end_blk)
		return 1;
	return 0;
}

static int move_block(ext2_filsys fs, ext2fs_block_bitmap bmap)
{

	char *buf;
	dgrp_t group = 0;
	errcode_t retval;
	int meta_data = 0;
	blk64_t blk, new_blk, goal;
	struct blk_move *bmv;

	retval = ext2fs_get_mem(fs->blocksize, &buf);
	if (retval)
		return retval;

	for (new_blk = blk = fs->super->s_first_data_block;
	     blk < ext2fs_blocks_count(fs->super); blk++) {
		if (!ext2fs_test_block_bitmap2(bmap, blk))
			continue;

		if (ext2fs_is_meta_block(fs, blk)) {
			/*
			 * If the block is mapping a fs meta data block
			 * like group desc/block bitmap/inode bitmap. We
			 * should find a block in the same group and fix
			 * the respective fs metadata pointers. Otherwise
			 * fail
			 */
			group = ext2fs_group_of_blk2(fs, blk);
			goal = ext2fs_group_first_block2(fs, group);
			meta_data = 1;

		} else {
			goal = new_blk;
		}
		retval = ext2fs_new_block2(fs, goal, NULL, &new_blk);
		if (retval)
			goto err_out;

		/* new fs meta data block should be in the same group */
		if (meta_data && !ext2fs_is_block_in_group(fs, group, new_blk)) {
			retval = ENOSPC;
			goto err_out;
		}

		/* Mark this block as allocated */
		ext2fs_mark_block_bitmap2(fs->block_map, new_blk);

		/* Add it to block move list */
		retval = ext2fs_get_mem(sizeof(struct blk_move), &bmv);
		if (retval)
			goto err_out;

		bmv->old_loc = blk;
		bmv->new_loc = new_blk;

		list_add(&(bmv->list), &blk_move_list);

		retval = io_channel_read_blk64(fs->io, blk, 1, buf);
		if (retval)
			goto err_out;

		retval = io_channel_write_blk64(fs->io, new_blk, 1, buf);
		if (retval)
			goto err_out;
	}

err_out:
	ext2fs_free_mem(&buf);
	return retval;
}

static blk64_t translate_block(blk64_t blk)
{
	struct list_head *entry;
	struct blk_move *bmv;

	list_for_each(entry, &blk_move_list) {
		bmv = list_entry(entry, struct blk_move, list);
		if (bmv->old_loc == blk)
			return bmv->new_loc;
	}

	return 0;
}

static int process_block(ext2_filsys fs EXT2FS_ATTR((unused)),
			 blk64_t *block_nr,
			 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
			 blk64_t ref_block EXT2FS_ATTR((unused)),
			 int ref_offset EXT2FS_ATTR((unused)),
			 void *priv_data)
{
	int ret = 0;
	blk64_t new_blk;
	ext2fs_block_bitmap bmap = (ext2fs_block_bitmap) priv_data;

	if (!ext2fs_test_block_bitmap2(bmap, *block_nr))
		return 0;
	new_blk = translate_block(*block_nr);
	if (new_blk) {
		*block_nr = new_blk;
		/*
		 * This will force the ext2fs_write_inode in the iterator
		 */
		ret |= BLOCK_CHANGED;
	}

	return ret;
}

static int inode_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap)
{
	errcode_t retval = 0;
	ext2_ino_t ino;
	blk64_t blk;
	char *block_buf = 0;
	struct ext2_inode inode;
	ext2_inode_scan	scan = NULL;

	retval = ext2fs_get_mem(fs->blocksize * 3, &block_buf);
	if (retval)
		return retval;

	retval = ext2fs_open_inode_scan(fs, 0, &scan);
	if (retval)
		goto err_out;

	while (1) {
		retval = ext2fs_get_next_inode(scan, &ino, &inode);
		if (retval)
			goto err_out;

		if (!ino)
			break;

		if (inode.i_links_count == 0)
			continue; /* inode not in use */

		/* FIXME!!
		 * If we end up modifying the journal inode
		 * the sb->s_jnl_blocks will differ. But a
		 * subsequent e2fsck fixes that.
		 * Do we need to fix this ??
		 */

		if (ext2fs_file_acl_block(fs, &inode) &&
		    ext2fs_test_block_bitmap2(bmap,
					ext2fs_file_acl_block(fs, &inode))) {
			blk = translate_block(ext2fs_file_acl_block(fs,
								    &inode));
			if (!blk)
				continue;

			ext2fs_file_acl_block_set(fs, &inode, blk);

			/*
			 * Write the inode to disk so that inode table
			 * resizing can work
			 */
			retval = ext2fs_write_inode(fs, ino, &inode);
			if (retval)
				goto err_out;
		}

		if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
			continue;

		retval = ext2fs_block_iterate3(fs, ino, 0, block_buf,
					       process_block, bmap);
		if (retval)
			goto err_out;

	}

err_out:
	ext2fs_free_mem(&block_buf);
	ext2fs_close_inode_scan(scan);

	return retval;
}

/*
 * We need to scan for inode and block bitmaps that may need to be
 * moved.  This can take place if the filesystem was formatted for
 * RAID arrays using the mke2fs's extended option "stride".
 */
static int group_desc_scan_and_fix(ext2_filsys fs, ext2fs_block_bitmap bmap)
{
	dgrp_t i;
	blk64_t blk, new_blk;

	for (i = 0; i < fs->group_desc_count; i++) {
		blk = ext2fs_block_bitmap_loc(fs, i);
		if (ext2fs_test_block_bitmap2(bmap, blk)) {
			new_blk = translate_block(blk);
			if (!new_blk)
				continue;
			ext2fs_block_bitmap_loc_set(fs, i, new_blk);
		}

		blk = ext2fs_inode_bitmap_loc(fs, i);
		if (ext2fs_test_block_bitmap2(bmap, blk)) {
			new_blk = translate_block(blk);
			if (!new_blk)
				continue;
			ext2fs_inode_bitmap_loc_set(fs, i, new_blk);
		}
	}
	return 0;
}

static int expand_inode_table(ext2_filsys fs, unsigned long new_ino_size)
{
	dgrp_t i;
	blk64_t blk;
	errcode_t retval;
	int new_ino_blks_per_grp;
	unsigned int j;
	char *old_itable = NULL, *new_itable = NULL;
	char *tmp_old_itable = NULL, *tmp_new_itable = NULL;
	unsigned long old_ino_size;
	int old_itable_size, new_itable_size;

	old_itable_size = fs->inode_blocks_per_group * fs->blocksize;
	old_ino_size = EXT2_INODE_SIZE(fs->super);

	new_ino_blks_per_grp = ext2fs_div_ceil(
					EXT2_INODES_PER_GROUP(fs->super) *
					new_ino_size,
					fs->blocksize);

	new_itable_size = new_ino_blks_per_grp * fs->blocksize;

	retval = ext2fs_get_mem(old_itable_size, &old_itable);
	if (retval)
		return retval;

	retval = ext2fs_get_mem(new_itable_size, &new_itable);
	if (retval)
		goto err_out;

	tmp_old_itable = old_itable;
	tmp_new_itable = new_itable;

	for (i = 0; i < fs->group_desc_count; i++) {
		blk = ext2fs_inode_table_loc(fs, i);
		retval = io_channel_read_blk64(fs->io, blk,
				fs->inode_blocks_per_group, old_itable);
		if (retval)
			goto err_out;

		for (j = 0; j < EXT2_INODES_PER_GROUP(fs->super); j++) {
			memcpy(new_itable, old_itable, old_ino_size);

			memset(new_itable+old_ino_size, 0,
					new_ino_size - old_ino_size);

			new_itable += new_ino_size;
			old_itable += old_ino_size;
		}

		/* reset the pointer */
		old_itable = tmp_old_itable;
		new_itable = tmp_new_itable;

		retval = io_channel_write_blk64(fs->io, blk,
					new_ino_blks_per_grp, new_itable);
		if (retval)
			goto err_out;
	}

	/* Update the meta data */
	fs->inode_blocks_per_group = new_ino_blks_per_grp;
	ext2fs_free_inode_cache(fs->icache);
	fs->icache = 0;
	fs->super->s_inode_size = new_ino_size;

err_out:
	if (old_itable)
		ext2fs_free_mem(&old_itable);

	if (new_itable)
		ext2fs_free_mem(&new_itable);

	return retval;
}

static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
{
	blk64_t		blk;
	ext2_ino_t	ino;
	unsigned int	group = 0;
	unsigned int	count = 0;
	int		total_free = 0;
	int		group_free = 0;

	/*
	 * First calculate the block statistics
	 */
	for (blk = fs->super->s_first_data_block;
	     blk < ext2fs_blocks_count(fs->super); blk++) {
		if (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk)) {
			group_free++;
			total_free++;
		}
		count++;
		if ((count == fs->super->s_blocks_per_group) ||
		    (blk == ext2fs_blocks_count(fs->super)-1)) {
			ext2fs_bg_free_blocks_count_set(fs, group++,
							group_free);
			count = 0;
			group_free = 0;
		}
	}
	total_free = EXT2FS_C2B(fs, total_free);
	ext2fs_free_blocks_count_set(fs->super, total_free);

	/*
	 * Next, calculate the inode statistics
	 */
	group_free = 0;
	total_free = 0;
	count = 0;
	group = 0;

	/* Protect loop from wrap-around if s_inodes_count maxed */
	for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) {
		if (!ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) {
			group_free++;
			total_free++;
		}
		count++;
		if ((count == fs->super->s_inodes_per_group) ||
		    (ino == fs->super->s_inodes_count)) {
			ext2fs_bg_free_inodes_count_set(fs, group++,
							group_free);
			count = 0;
			group_free = 0;
		}
	}
	fs->super->s_free_inodes_count = total_free;
	ext2fs_mark_super_dirty(fs);
	return 0;
}

#define list_for_each_safe(pos, pnext, head) \
	for (pos = (head)->next, pnext = pos->next; pos != (head); \
	     pos = pnext, pnext = pos->next)

static void free_blk_move_list(void)
{
	struct list_head *entry, *tmp;
	struct blk_move *bmv;

	list_for_each_safe(entry, tmp, &blk_move_list) {
		bmv = list_entry(entry, struct blk_move, list);
		list_del(entry);
		ext2fs_free_mem(&bmv);
	}
	return;
}

static int resize_inode(ext2_filsys fs, unsigned long new_size)
{
	errcode_t retval;
	int new_ino_blks_per_grp;
	ext2fs_block_bitmap bmap;

	retval = ext2fs_read_inode_bitmap(fs);
	if (retval) {
		fputs(_("Failed to read inode bitmap\n"), stderr);
		return retval;
	}
	retval = ext2fs_read_block_bitmap(fs);
	if (retval) {
		fputs(_("Failed to read block bitmap\n"), stderr);
		return retval;
	}
	INIT_LIST_HEAD(&blk_move_list);


	new_ino_blks_per_grp = ext2fs_div_ceil(
					EXT2_INODES_PER_GROUP(fs->super)*
					new_size,
					fs->blocksize);

	/* We may change the file system.
	 * Mark the file system as invalid so that
	 * the user is prompted to run fsck.
	 */
	fs->super->s_state &= ~EXT2_VALID_FS;

	retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
						&bmap);
	if (retval) {
		fputs(_("Failed to allocate block bitmap when "
				"increasing inode size\n"), stderr);
		return retval;
	}
	retval = get_move_bitmaps(fs, new_ino_blks_per_grp, bmap);
	if (retval) {
		fputs(_("Not enough space to increase inode size \n"), stderr);
		goto err_out;
	}
	retval = move_block(fs, bmap);
	if (retval) {
		fputs(_("Failed to relocate blocks during inode resize \n"),
		      stderr);
		goto err_out;
	}
	retval = inode_scan_and_fix(fs, bmap);
	if (retval)
		goto err_out_undo;

	retval = group_desc_scan_and_fix(fs, bmap);
	if (retval)
		goto err_out_undo;

	retval = expand_inode_table(fs, new_size);
	if (retval)
		goto err_out_undo;

	ext2fs_calculate_summary_stats(fs);

	fs->super->s_state |= EXT2_VALID_FS;
	/* mark super block and block bitmap as dirty */
	ext2fs_mark_super_dirty(fs);
	ext2fs_mark_bb_dirty(fs);

err_out:
	free_blk_move_list();
	ext2fs_free_block_bitmap(bmap);

	return retval;

err_out_undo:
	free_blk_move_list();
	ext2fs_free_block_bitmap(bmap);
	fputs(_("Error in resizing the inode size.\n"
			"Run e2undo to undo the "
			"file system changes. \n"), stderr);

	return retval;
}

static int tune2fs_setup_tdb(const char *name, io_manager *io_ptr)
{
	errcode_t retval = 0;
	const char *tdb_dir;
	char *tdb_file = NULL;
	char *dev_name, *tmp_name;

	/* (re)open a specific undo file */
	if (undo_file && undo_file[0] != 0) {
		retval = set_undo_io_backing_manager(*io_ptr);
		if (retval)
			goto err;
		*io_ptr = undo_io_manager;
		retval = set_undo_io_backup_file(undo_file);
		if (retval)
			goto err;
		printf(_("Overwriting existing filesystem; this can be undone "
			 "using the command:\n"
			 "    e2undo %s %s\n\n"),
			 undo_file, name);
		return retval;
	}

	/*
	 * Configuration via a conf file would be
	 * nice
	 */
	tdb_dir = getenv("E2FSPROGS_UNDO_DIR");
	if (!tdb_dir)
		tdb_dir = "/var/lib/e2fsprogs";

	if (!strcmp(tdb_dir, "none") || (tdb_dir[0] == 0) ||
	    access(tdb_dir, W_OK))
		return 0;

	tmp_name = strdup(name);
	if (!tmp_name)
		goto errout;
	dev_name = basename(tmp_name);
	tdb_file = malloc(strlen(tdb_dir) + 9 + strlen(dev_name) + 7 + 1);
	if (!tdb_file) {
		free(tmp_name);
		goto errout;
	}
	sprintf(tdb_file, "%s/tune2fs-%s.e2undo", tdb_dir, dev_name);
	free(tmp_name);

	if ((unlink(tdb_file) < 0) && (errno != ENOENT)) {
		retval = errno;
		com_err(program_name, retval,
			_("while trying to delete %s"), tdb_file);
		goto errout;
	}

	retval = set_undo_io_backing_manager(*io_ptr);
	if (retval)
		goto errout;
	*io_ptr = undo_io_manager;
	retval = set_undo_io_backup_file(tdb_file);
	if (retval)
		goto errout;
	printf(_("Overwriting existing filesystem; this can be undone "
		 "using the command:\n"
		 "    e2undo %s %s\n\n"),
		 tdb_file, name);

	free(tdb_file);
	return 0;
errout:
	free(tdb_file);
err:
	com_err("tune2fs", retval, "while trying to setup undo file\n");
	return retval;
}

static int
fs_update_journal_user(struct ext2_super_block *sb, __u8 old_uuid[UUID_SIZE])
{
	int retval, nr_users, start;
	journal_superblock_t *jsb;
	ext2_filsys jfs;
	__u8 *j_uuid;
	char *journal_path;
	char uuid[UUID_STR_SIZE];
	char buf[SUPERBLOCK_SIZE] __attribute__ ((aligned(8)));

	if (!ext2fs_has_feature_journal(sb) || uuid_is_null(sb->s_journal_uuid))
		return 0;

	uuid_unparse(sb->s_journal_uuid, uuid);
	journal_path = blkid_get_devname(NULL, "UUID", uuid);
	if (!journal_path)
		return 0;

	retval = ext2fs_open2(journal_path, io_options,
			      EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_RW,
			      0, 0, unix_io_manager, &jfs);
	if (retval) {
		com_err(program_name, retval,
			_("while trying to open %s"),
			journal_path);
		return retval;
	}

	retval = get_journal_sb(jfs, buf);
	if (retval != 0) {
		if (retval == EXT2_ET_UNSUPP_FEATURE)
			fprintf(stderr, _("%s is not a journal device.\n"),
				journal_path);
		return retval;
	}

	jsb = (journal_superblock_t *) buf;
	/* Find the filesystem UUID */
	nr_users = ntohl(jsb->s_nr_users);

	j_uuid = journal_user(old_uuid, jsb->s_users, nr_users);
	if (j_uuid == NULL) {
		fputs(_("Filesystem's UUID not found on journal device.\n"),
		      stderr);
		return EXT2_ET_LOAD_EXT_JOURNAL;
	}

	memcpy(j_uuid, sb->s_uuid, UUID_SIZE);

	start = ext2fs_journal_sb_start(jfs->blocksize);
	/* Write back the journal superblock */
	retval = io_channel_write_blk64(jfs->io, start, -SUPERBLOCK_SIZE, buf);
	if (retval != 0) {
		com_err(program_name, retval,
			"while writing journal superblock.");
		return retval;
	}

	ext2fs_close(jfs);

	return 0;
}

#ifndef BUILD_AS_LIB
int main(int argc, char **argv)
#else
int tune2fs_main(int argc, char **argv)
#endif  /* BUILD_AS_LIB */
{
	errcode_t retval;
	ext2_filsys fs;
	struct ext2_super_block *sb;
	io_manager io_ptr, io_ptr_orig = NULL;
	int rc = 0;
	char default_undo_file[1] = { 0 };

#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
	set_com_err_gettext(gettext);
#endif
	if (argc && *argv)
		program_name = *argv;
	add_error_table(&et_ext2_error_table);

#ifdef CONFIG_BUILD_FINDFS
	if (strcmp(get_progname(argv[0]), "findfs") == 0)
		do_findfs(argc, argv);
#endif
	if (strcmp(get_progname(argv[0]), "e2label") == 0)
		parse_e2label_options(argc, argv);
	else
		parse_tune2fs_options(argc, argv);

#ifdef CONFIG_TESTIO_DEBUG
	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_DEBUG")) {
		io_ptr = test_io_manager;
		test_io_backing_manager = unix_io_manager;
	} else
#endif
		io_ptr = unix_io_manager;

retry_open:
	if ((open_flag & EXT2_FLAG_RW) == 0 || f_flag)
		open_flag |= EXT2_FLAG_SKIP_MMP;

	open_flag |= EXT2_FLAG_64BITS | EXT2_FLAG_JOURNAL_DEV_OK;

	/* keep the filesystem struct around to dump MMP data */
	open_flag |= EXT2_FLAG_NOFREE_ON_ERROR;

	retval = ext2fs_open2(device_name, io_options, open_flag,
			      0, 0, io_ptr, &fs);
	if (retval) {
		com_err(program_name, retval,
			_("while trying to open %s"),
			device_name);
		if (retval == EXT2_ET_MMP_FSCK_ON ||
		    retval == EXT2_ET_MMP_UNKNOWN_SEQ)
			dump_mmp_msg(fs->mmp_buf,
				     _("If you are sure the filesystem "
				       "is not in use on any node, run:\n"
				       "'tune2fs -f -E clear_mmp {device}'\n"));
		else if (retval == EXT2_ET_MMP_FAILED)
			dump_mmp_msg(fs->mmp_buf, NULL);
		else if (retval == EXT2_ET_MMP_MAGIC_INVALID)
			fprintf(stderr,
				_("MMP block magic is bad. Try to fix it by "
				  "running:\n'e2fsck -f %s'\n"), device_name);
		else if (retval == EXT2_ET_BAD_MAGIC)
			check_plausibility(device_name, CHECK_FS_EXIST, NULL);
		else if (retval != EXT2_ET_MMP_FAILED)
			fprintf(stderr, "%s",
			     _("Couldn't find valid filesystem superblock.\n"));

		ext2fs_free(fs);
		exit(1);
	}
	if (ext2fs_has_feature_journal_dev(fs->super)) {
		fprintf(stderr, "%s", _("Cannot modify a journal device.\n"));
		ext2fs_free(fs);
		exit(1);
	}
	fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;

	if (I_flag) {
		/*
		 * Check the inode size is right so we can issue an
		 * error message and bail before setting up the tdb
		 * file.
		 */
		if (new_inode_size == EXT2_INODE_SIZE(fs->super)) {
			fprintf(stderr, _("The inode size is already %lu\n"),
				new_inode_size);
			rc = 1;
			goto closefs;
		}
		if (new_inode_size < EXT2_INODE_SIZE(fs->super)) {
			fprintf(stderr, "%s",
				_("Shrinking inode size is not supported\n"));
			rc = 1;
			goto closefs;
		}
		if (new_inode_size > fs->blocksize) {
			fprintf(stderr, _("Invalid inode size %lu (max %d)\n"),
				new_inode_size, fs->blocksize);
			rc = 1;
			goto closefs;
		}
		check_fsck_needed(fs,
			_("Resizing inodes could take some time."));
		/*
		 * If inode resize is requested use the
		 * Undo I/O manager
		 */
		undo_file = default_undo_file;
	}

	/* Set up an undo file */
	if (undo_file && io_ptr_orig == NULL) {
		io_ptr_orig = io_ptr;
		retval = tune2fs_setup_tdb(device_name, &io_ptr);
		if (retval) {
			rc = 1;
			goto closefs;
		}
		if (io_ptr != io_ptr_orig) {
			ext2fs_close_free(&fs);
			goto retry_open;
		}
	}

	sb = fs->super;
	fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;

	if (print_label) {
		/* For e2label emulation */
		printf("%.*s\n", (int) sizeof(sb->s_volume_name),
		       sb->s_volume_name);
		remove_error_table(&et_ext2_error_table);
		goto closefs;
	}

	retval = ext2fs_check_if_mounted(device_name, &mount_flags);
	if (retval) {
		com_err("ext2fs_check_if_mount", retval,
			_("while determining whether %s is mounted."),
			device_name);
		rc = 1;
		goto closefs;
	}

#ifdef NO_RECOVERY
	/* Warn if file system needs recovery and it is opened for writing. */
	if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
	    (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
	    (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
		fprintf(stderr,
_("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
  "\te2fsck -E journal_only %s\n\n"
  "then rerun this command.  Otherwise, any changes made may be overwritten\n"
  "by journal recovery.\n"), device_name);
	}
#else
	/* Recover the journal if possible. */
	if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
	    ext2fs_has_feature_journal_needs_recovery(fs->super)) {
		errcode_t err;

		printf(_("Recovering journal.\n"));
		err = ext2fs_run_ext3_journal(&fs);
		if (err) {
			com_err("tune2fs", err, "while recovering journal.\n");
			printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
			if (fs)
				ext2fs_close_free(&fs);
			exit(1);
		}
		sb = fs->super;
	}
#endif

	/* Normally we only need to write out the superblock */
	fs->flags |= EXT2_FLAG_SUPER_ONLY;

	if (c_flag) {
		sb->s_max_mnt_count = max_mount_count;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting maximal mount count to %d\n"),
		       max_mount_count);
	}
	if (C_flag) {
		sb->s_mnt_count = mount_count;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting current mount count to %d\n"), mount_count);
	}
	if (e_flag) {
		sb->s_errors = errors;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting error behavior to %d\n"), errors);
	}
	if (g_flag) {
		sb->s_def_resgid = resgid;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting reserved blocks gid to %lu\n"), resgid);
	}
	if (i_flag) {
		if ((unsigned long long)interval >= (1ULL << 32)) {
			com_err(program_name, 0,
				_("interval between checks is too big (%lu)"),
				interval);
			rc = 1;
			goto closefs;
		}
		sb->s_checkinterval = interval;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting interval between checks to %lu seconds\n"),
		       interval);
	}
	if (m_flag) {
		ext2fs_r_blocks_count_set(sb, reserved_ratio *
					  ext2fs_blocks_count(sb) / 100.0);
		ext2fs_mark_super_dirty(fs);
		printf (_("Setting reserved blocks percentage to %g%% (%llu blocks)\n"),
			reserved_ratio, ext2fs_r_blocks_count(sb));
	}
	if (r_flag) {
		if (reserved_blocks > ext2fs_blocks_count(sb)/2) {
			com_err(program_name, 0,
				_("reserved blocks count is too big (%llu)"),
				reserved_blocks);
			rc = 1;
			goto closefs;
		}
		ext2fs_r_blocks_count_set(sb, reserved_blocks);
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting reserved blocks count to %llu\n"),
		       reserved_blocks);
	}
	if (s_flag == 1) {
		if (ext2fs_has_feature_sparse_super(sb)) {
			fputs(_("\nThe filesystem already has sparse "
				"superblocks.\n"), stderr);
		} else if (ext2fs_has_feature_meta_bg(sb)) {
			fputs(_("\nSetting the sparse superblock flag not "
				"supported\nfor filesystems with "
				"the meta_bg feature enabled.\n"),
				stderr);
			rc = 1;
			goto closefs;
		} else {
			ext2fs_set_feature_sparse_super(sb);
			sb->s_state &= ~EXT2_VALID_FS;
			ext2fs_mark_super_dirty(fs);
			printf(_("\nSparse superblock flag set.  %s"),
			       _(please_fsck));
		}
	}
	if (s_flag == 0) {
		fputs(_("\nClearing the sparse superblock flag not supported.\n"),
		      stderr);
		rc = 1;
		goto closefs;
	}
	if (T_flag) {
		sb->s_lastcheck = last_check_time;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting time filesystem last checked to %s\n"),
		       ctime(&last_check_time));
	}
	if (u_flag) {
		sb->s_def_resuid = resuid;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting reserved blocks uid to %lu\n"), resuid);
	}
	if (L_flag) {
		if (strlen(new_label) > sizeof(sb->s_volume_name))
			fputs(_("Warning: label too long, truncating.\n"),
			      stderr);
		memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
		strncpy(sb->s_volume_name, new_label,
			sizeof(sb->s_volume_name));
		ext2fs_mark_super_dirty(fs);
	}
	if (M_flag) {
		memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
		strncpy(sb->s_last_mounted, new_last_mounted,
			sizeof(sb->s_last_mounted));
		ext2fs_mark_super_dirty(fs);
	}
	if (mntopts_cmd) {
		rc = update_mntopts(fs, mntopts_cmd);
		if (rc)
			goto closefs;
	}
	if (features_cmd) {
		rc = update_feature_set(fs, features_cmd);
		if (rc)
			goto closefs;
	}
	if (extended_cmd) {
		rc = parse_extended_opts(fs, extended_cmd);
		if (rc)
			goto closefs;
		if (clear_mmp && !f_flag) {
			fputs(_("Error in using clear_mmp. "
				"It must be used with -f\n"),
			      stderr);
			goto closefs;
		}
	}
	if (clear_mmp) {
		rc = ext2fs_mmp_clear(fs);
		goto closefs;
	}
	if (journal_size || journal_device) {
		rc = add_journal(fs);
		if (rc)
			goto closefs;
	}

	if (Q_flag) {
		if (mount_flags & EXT2_MF_MOUNTED) {
			fputs(_("The quota feature may only be changed when "
				"the filesystem is unmounted.\n"), stderr);
			rc = 1;
			goto closefs;
		}
		handle_quota_options(fs);
	}

	if (U_flag) {
		int set_csum = 0;
		dgrp_t i;
		char buf[SUPERBLOCK_SIZE] __attribute__ ((aligned(8)));
		__u8 old_uuid[UUID_SIZE];

		if (ext2fs_has_group_desc_csum(fs)) {
			/*
			 * Changing the UUID on a metadata_csum FS requires
			 * rewriting all metadata, which can race with a
			 * mounted fs.  Don't allow that unless we're saving
			 * the checksum seed.
			 */
			if ((mount_flags & EXT2_MF_MOUNTED) &&
			    !ext2fs_has_feature_csum_seed(fs->super) &&
			    ext2fs_has_feature_metadata_csum(fs->super)) {
				fputs(_("The UUID may only be "
					"changed when the filesystem is "
					"unmounted.\n"), stderr);
				fputs(_("If you only use kernels newer than "
					"v4.4, run 'tune2fs -O "
					"metadata_csum_seed' and re-run this "
					"command.\n"), stderr);
				try_confirm_csum_seed_support();
				exit(1);
			}
			if (!ext2fs_has_feature_csum_seed(fs->super))
				check_fsck_needed(fs,
					_("Setting UUID on a checksummed "
					  "filesystem could take some time."));

			/*
			 * Determine if the block group checksums are
			 * correct so we know whether or not to set
			 * them later on.
			 */
			for (i = 0; i < fs->group_desc_count; i++)
				if (!ext2fs_group_desc_csum_verify(fs, i))
					break;
			if (i >= fs->group_desc_count)
				set_csum = 1;
		}

		memcpy(old_uuid, sb->s_uuid, UUID_SIZE);
		if ((strcasecmp(new_UUID, "null") == 0) ||
		    (strcasecmp(new_UUID, "clear") == 0)) {
			uuid_clear(sb->s_uuid);
		} else if (strcasecmp(new_UUID, "time") == 0) {
			uuid_generate_time(sb->s_uuid);
		} else if (strcasecmp(new_UUID, "random") == 0) {
			uuid_generate(sb->s_uuid);
		} else if (uuid_parse(new_UUID, sb->s_uuid)) {
			com_err(program_name, 0, "%s",
				_("Invalid UUID format\n"));
			rc = 1;
			goto closefs;
		}
		ext2fs_init_csum_seed(fs);
		if (set_csum) {
			for (i = 0; i < fs->group_desc_count; i++)
				ext2fs_group_desc_csum_set(fs, i);
			fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
		}

		/* If this is a journal dev, we need to copy UUID into jsb */
		if (!(rc = get_journal_sb(fs, buf))) {
			journal_superblock_t *jsb;

			jsb = (journal_superblock_t *) buf;
			fputs(_("Need to update journal superblock.\n"), stdout);
			memcpy(jsb->s_uuid, sb->s_uuid, sizeof(sb->s_uuid));

			/* Writeback the journal superblock */
			if ((rc = io_channel_write_blk64(fs->io,
				ext2fs_journal_sb_start(fs->blocksize),
					-SUPERBLOCK_SIZE, buf)))
				goto closefs;
		} else if (rc != EXT2_ET_UNSUPP_FEATURE)
			goto closefs;
		else {
			rc = 0; /** Reset rc to avoid ext2fs_mmp_stop() */

			if ((rc = fs_update_journal_user(sb, old_uuid)))
				goto closefs;
		}

		ext2fs_mark_super_dirty(fs);
		if (!ext2fs_has_feature_csum_seed(fs->super) &&
		    (ext2fs_has_feature_metadata_csum(fs->super) ||
		     ext2fs_has_feature_ea_inode(fs->super)))
			rewrite_checksums = 1;
	}

	if (I_flag) {
		if (mount_flags & EXT2_MF_MOUNTED) {
			fputs(_("The inode size may only be "
				"changed when the filesystem is "
				"unmounted.\n"), stderr);
			rc = 1;
			goto closefs;
		}
		if (ext2fs_has_feature_flex_bg(fs->super)) {
			fputs(_("Changing the inode size not supported for "
				"filesystems with the flex_bg\n"
				"feature enabled.\n"),
			      stderr);
			rc = 1;
			goto closefs;
		}
		/*
		 * We want to update group descriptor also
		 * with the new free inode count
		 */
		if (rewrite_checksums)
			fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
		retval = resize_inode(fs, new_inode_size);
		if (rewrite_checksums)
			fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
		if (retval == 0) {
			printf(_("Setting inode size %lu\n"),
							new_inode_size);
			rewrite_checksums = 1;
		} else {
			printf("%s", _("Failed to change inode size\n"));
			rc = 1;
			goto closefs;
		}
	}

	if (rewrite_checksums)
		rewrite_metadata_checksums(fs);

	if (l_flag)
		list_super(sb);
	if (stride_set) {
		sb->s_raid_stride = stride;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting stride size to %d\n"), stride);
	}
	if (stripe_width_set) {
		sb->s_raid_stripe_width = stripe_width;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting stripe width to %d\n"), stripe_width);
	}
	if (ext_mount_opts) {
		strncpy((char *)(fs->super->s_mount_opts), ext_mount_opts,
			sizeof(fs->super->s_mount_opts));
		fs->super->s_mount_opts[sizeof(fs->super->s_mount_opts)-1] = 0;
		ext2fs_mark_super_dirty(fs);
		printf(_("Setting extended default mount options to '%s'\n"),
		       ext_mount_opts);
		free(ext_mount_opts);
	}

	free(device_name);
	remove_error_table(&et_ext2_error_table);

closefs:
	if (rc) {
		ext2fs_mmp_stop(fs);
#ifndef BUILD_AS_LIB
		exit(1);
#endif
	}

	if (feature_64bit)
		convert_64bit(fs, feature_64bit);
	return (ext2fs_close_free(&fs) ? 1 : 0);
}
