/*
 * resize2fs.c --- ext2 main routine
 *
 * Copyright (C) 1997, 1998 by Theodore Ts'o and
 * 	PowerQuest, Inc.
 *
 * Copyright (C) 1999, 2000 by Theodore Ts'o
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

/*
 * Resizing a filesystem consists of the following phases:
 *
 *	1.  Adjust superblock and write out new parts of the inode
 * 		table
 * 	2.  Determine blocks which need to be relocated, and copy the
 * 		contents of blocks from their old locations to the new ones.
 * 	3.  Scan the inode table, doing the following:
 * 		a.  If blocks have been moved, update the block
 * 			pointers in the inodes and indirect blocks to
 * 			point at the new block locations.
 * 		b.  If parts of the inode table need to be evacuated,
 * 			copy inodes from their old locations to their
 * 			new ones.
 * 		c.  If (b) needs to be done, note which blocks contain
 * 			directory information, since we will need to
 * 			update the directory information.
 * 	4.  Update the directory blocks with the new inode locations.
 * 	5.  Move the inode tables, if necessary.
 */

#include "config.h"
#include "resize2fs.h"
#include <time.h>

#ifdef __linux__			/* Kludge for debugging */
#define RESIZE2FS_DEBUG
#endif

static void fix_uninit_block_bitmaps(ext2_filsys fs);
static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size);
static errcode_t blocks_to_move(ext2_resize_t rfs);
static errcode_t block_mover(ext2_resize_t rfs);
static errcode_t inode_scan_and_fix(ext2_resize_t rfs);
static errcode_t inode_ref_fix(ext2_resize_t rfs);
static errcode_t move_itables(ext2_resize_t rfs);
static errcode_t fix_resize_inode(ext2_filsys fs);
static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
static errcode_t fix_sb_journal_backup(ext2_filsys fs);
static errcode_t mark_table_blocks(ext2_filsys fs,
				   ext2fs_block_bitmap bmap);
static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
						 ext2fs_block_bitmap meta_bmap);
static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size);
static errcode_t move_bg_metadata(ext2_resize_t rfs);
static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs);

/*
 * Some helper functions to check if a block is in a metadata area
 */
static inline int is_block_bm(ext2_filsys fs, unsigned int grp, blk64_t blk)
{
	return blk == ext2fs_block_bitmap_loc(fs, grp);
}

static inline int is_inode_bm(ext2_filsys fs, unsigned int grp, blk64_t blk)
{
	return blk == ext2fs_inode_bitmap_loc(fs, grp);
}

static int is_inode_tb(ext2_filsys fs, unsigned int grp, blk64_t blk)
{
	return blk >= ext2fs_inode_table_loc(fs, grp) &&
	       blk < (ext2fs_inode_table_loc(fs, grp) +
		      fs->inode_blocks_per_group);
}

/* Some bigalloc helper macros which are more succinct... */
#define B2C(x)	EXT2FS_B2C(fs, (x))
#define C2B(x)	EXT2FS_C2B(fs, (x))
#define EQ_CLSTR(x, y) (B2C(x) == B2C(y))
#define LE_CLSTR(x, y) (B2C(x) <= B2C(y))
#define LT_CLSTR(x, y) (B2C(x) <  B2C(y))
#define GE_CLSTR(x, y) (B2C(x) >= B2C(y))
#define GT_CLSTR(x, y) (B2C(x) >  B2C(y))

static int lazy_itable_init;

/*
 * This is the top-level routine which does the dirty deed....
 */
errcode_t resize_fs(ext2_filsys fs, blk64_t *new_size, int flags,
	    errcode_t (*progress)(ext2_resize_t rfs, int pass,
					  unsigned long cur,
					  unsigned long max_val))
{
	ext2_resize_t	rfs;
	errcode_t	retval;
	struct resource_track	rtrack, overall_track;

	/*
	 * Create the data structure
	 */
	retval = ext2fs_get_mem(sizeof(struct ext2_resize_struct), &rfs);
	if (retval)
		return retval;

	memset(rfs, 0, sizeof(struct ext2_resize_struct));
	fs->priv_data = rfs;
	rfs->old_fs = fs;
	rfs->flags = flags;
	rfs->itable_buf	 = 0;
	rfs->progress = progress;

	init_resource_track(&overall_track, "overall resize2fs", fs->io);
	init_resource_track(&rtrack, "read_bitmaps", fs->io);
	retval = ext2fs_read_bitmaps(fs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	fs->super->s_state |= EXT2_ERROR_FS;
	ext2fs_mark_super_dirty(fs);
	ext2fs_flush(fs);

	init_resource_track(&rtrack, "fix_uninit_block_bitmaps 1", fs->io);
	fix_uninit_block_bitmaps(fs);
	print_resource_track(rfs, &rtrack, fs->io);
	retval = ext2fs_dup_handle(fs, &rfs->new_fs);
	if (retval)
		goto errout;

	init_resource_track(&rtrack, "resize_group_descriptors", fs->io);
	retval = resize_group_descriptors(rfs, *new_size);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "move_bg_metadata", fs->io);
	retval = move_bg_metadata(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "zero_high_bits_in_metadata", fs->io);
	retval = zero_high_bits_in_inodes(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "adjust_superblock", fs->io);
	retval = adjust_superblock(rfs, *new_size);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "fix_uninit_block_bitmaps 2", fs->io);
	fix_uninit_block_bitmaps(rfs->new_fs);
	print_resource_track(rfs, &rtrack, fs->io);
	/* Clear the block bitmap uninit flag for the last block group */
	ext2fs_bg_flags_clear(rfs->new_fs, rfs->new_fs->group_desc_count - 1,
			     EXT2_BG_BLOCK_UNINIT);

	*new_size = ext2fs_blocks_count(rfs->new_fs->super);

	init_resource_track(&rtrack, "blocks_to_move", fs->io);
	retval = blocks_to_move(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

#ifdef RESIZE2FS_DEBUG
	if (rfs->flags & RESIZE_DEBUG_BMOVE)
		printf("Number of free blocks: %llu/%llu, Needed: %llu\n",
		       ext2fs_free_blocks_count(rfs->old_fs->super),
		       ext2fs_free_blocks_count(rfs->new_fs->super),
		       rfs->needed_blocks);
#endif

	init_resource_track(&rtrack, "block_mover", fs->io);
	retval = block_mover(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "inode_scan_and_fix", fs->io);
	retval = inode_scan_and_fix(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "inode_ref_fix", fs->io);
	retval = inode_ref_fix(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "move_itables", fs->io);
	retval = move_itables(rfs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	retval = clear_sparse_super2_last_group(rfs);
	if (retval)
		goto errout;

	init_resource_track(&rtrack, "calculate_summary_stats", fs->io);
	retval = ext2fs_calculate_summary_stats(rfs->new_fs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "fix_resize_inode", fs->io);
	retval = fix_resize_inode(rfs->new_fs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	init_resource_track(&rtrack, "fix_sb_journal_backup", fs->io);
	retval = fix_sb_journal_backup(rfs->new_fs);
	if (retval)
		goto errout;
	print_resource_track(rfs, &rtrack, fs->io);

	retval = ext2fs_set_gdt_csum(rfs->new_fs);
	if (retval)
		goto errout;

	rfs->new_fs->super->s_state &= ~EXT2_ERROR_FS;
	rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;

	print_resource_track(rfs, &overall_track, fs->io);
	retval = ext2fs_close_free(&rfs->new_fs);
	if (retval)
		goto errout;

	rfs->flags = flags;

	ext2fs_free(rfs->old_fs);
	rfs->old_fs = NULL;
	if (rfs->itable_buf)
		ext2fs_free_mem(&rfs->itable_buf);
	if (rfs->reserve_blocks)
		ext2fs_free_block_bitmap(rfs->reserve_blocks);
	if (rfs->move_blocks)
		ext2fs_free_block_bitmap(rfs->move_blocks);
	ext2fs_free_mem(&rfs);

	return 0;

errout:
	if (rfs->new_fs) {
		ext2fs_free(rfs->new_fs);
		rfs->new_fs = NULL;
	}
	if (rfs->itable_buf)
		ext2fs_free_mem(&rfs->itable_buf);
	ext2fs_free_mem(&rfs);
	return retval;
}

/* Keep the size of the group descriptor region constant */
static void adjust_reserved_gdt_blocks(ext2_filsys old_fs, ext2_filsys fs)
{
	if (ext2fs_has_feature_resize_inode(fs->super) &&
	    (old_fs->desc_blocks != fs->desc_blocks)) {
		int new;

		new = ((int) fs->super->s_reserved_gdt_blocks) +
			(old_fs->desc_blocks - fs->desc_blocks);
		if (new < 0)
			new = 0;
		if (new > (int) fs->blocksize/4)
			new = fs->blocksize/4;
		fs->super->s_reserved_gdt_blocks = new;
	}
}

/* Toggle 64bit mode */
static errcode_t resize_group_descriptors(ext2_resize_t rfs, blk64_t new_size)
{
	void *o, *n, *new_group_desc;
	dgrp_t i;
	int copy_size;
	errcode_t retval;

	if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
		return 0;

	if (new_size != ext2fs_blocks_count(rfs->new_fs->super) ||
	    ext2fs_blocks_count(rfs->new_fs->super) >= (1ULL << 32) ||
	    (rfs->flags & RESIZE_DISABLE_64BIT &&
	     rfs->flags & RESIZE_ENABLE_64BIT))
		return EXT2_ET_INVALID_ARGUMENT;

	if (rfs->flags & RESIZE_DISABLE_64BIT) {
		ext2fs_clear_feature_64bit(rfs->new_fs->super);
		rfs->new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE;
	} else if (rfs->flags & RESIZE_ENABLE_64BIT) {
		ext2fs_set_feature_64bit(rfs->new_fs->super);
		rfs->new_fs->super->s_desc_size = EXT2_MIN_DESC_SIZE_64BIT;
	}

	if (EXT2_DESC_SIZE(rfs->old_fs->super) ==
	    EXT2_DESC_SIZE(rfs->new_fs->super))
		return 0;

	o = rfs->new_fs->group_desc;
	rfs->new_fs->desc_blocks = ext2fs_div_ceil(
			rfs->old_fs->group_desc_count,
			EXT2_DESC_PER_BLOCK(rfs->new_fs->super));
	retval = ext2fs_get_arrayzero(rfs->new_fs->desc_blocks,
				      rfs->old_fs->blocksize, &new_group_desc);
	if (retval)
		return retval;

	n = new_group_desc;

	if (EXT2_DESC_SIZE(rfs->old_fs->super) <=
	    EXT2_DESC_SIZE(rfs->new_fs->super))
		copy_size = EXT2_DESC_SIZE(rfs->old_fs->super);
	else
		copy_size = EXT2_DESC_SIZE(rfs->new_fs->super);
	for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
		memcpy(n, o, copy_size);
		n = (char *)n + EXT2_DESC_SIZE(rfs->new_fs->super);
		o = (char *)o + EXT2_DESC_SIZE(rfs->old_fs->super);
	}

	ext2fs_free_mem(&rfs->new_fs->group_desc);
	rfs->new_fs->group_desc = new_group_desc;

	for (i = 0; i < rfs->old_fs->group_desc_count; i++)
		ext2fs_group_desc_csum_set(rfs->new_fs, i);

	adjust_reserved_gdt_blocks(rfs->old_fs, rfs->new_fs);

	return 0;
}

/* Move bitmaps/inode tables out of the way. */
static errcode_t move_bg_metadata(ext2_resize_t rfs)
{
	dgrp_t i;
	blk64_t b, c, d, old_desc_blocks, new_desc_blocks, j;
	ext2fs_block_bitmap old_map, new_map;
	int old, new;
	errcode_t retval;
	int cluster_ratio;

	if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
		return 0;

	retval = ext2fs_allocate_block_bitmap(rfs->old_fs, "oldfs", &old_map);
	if (retval)
		return retval;

	retval = ext2fs_allocate_block_bitmap(rfs->new_fs, "newfs", &new_map);
	if (retval)
		goto out;

	if (ext2fs_has_feature_meta_bg(rfs->old_fs->super)) {
		old_desc_blocks = rfs->old_fs->super->s_first_meta_bg;
		new_desc_blocks = rfs->new_fs->super->s_first_meta_bg;
	} else {
		old_desc_blocks = rfs->old_fs->desc_blocks +
				rfs->old_fs->super->s_reserved_gdt_blocks;
		new_desc_blocks = rfs->new_fs->desc_blocks +
				rfs->new_fs->super->s_reserved_gdt_blocks;
	}

	/* Construct bitmaps of super/descriptor blocks in old and new fs */
	for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
		retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, i, &b, &c, &d,
						   NULL);
		if (retval)
			goto out;
		if (b)
			ext2fs_mark_block_bitmap2(old_map, b);
		for (j = 0; c != 0 && j < old_desc_blocks; j++)
			ext2fs_mark_block_bitmap2(old_map, c + j);
		if (d)
			ext2fs_mark_block_bitmap2(old_map, d);

		retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, i, &b, &c, &d,
						   NULL);
		if (retval)
			goto out;
		if (b)
			ext2fs_mark_block_bitmap2(new_map, b);
		for (j = 0; c != 0 && j < new_desc_blocks; j++)
			ext2fs_mark_block_bitmap2(new_map, c + j);
		if (d)
			ext2fs_mark_block_bitmap2(new_map, d);
	}

	cluster_ratio = EXT2FS_CLUSTER_RATIO(rfs->new_fs);

	/* Find changes in block allocations for bg metadata */
	for (b = EXT2FS_B2C(rfs->old_fs,
			    rfs->old_fs->super->s_first_data_block);
	     b < ext2fs_blocks_count(rfs->new_fs->super);
	     b += cluster_ratio) {
		old = ext2fs_test_block_bitmap2(old_map, b);
		new = ext2fs_test_block_bitmap2(new_map, b);

		if (old && !new) {
			/* mark old_map, unmark new_map */
			if (cluster_ratio == 1)
				ext2fs_unmark_block_bitmap2(
						rfs->new_fs->block_map, b);
		} else if (!old && new)
			; /* unmark old_map, mark new_map */
		else {
			ext2fs_unmark_block_bitmap2(old_map, b);
			ext2fs_unmark_block_bitmap2(new_map, b);
		}
	}

	/*
	 * new_map now shows blocks that have been newly allocated.
	 * old_map now shows blocks that have been newly freed.
	 */

	/*
	 * Move any conflicting bitmaps and inode tables.  Ensure that we
	 * don't try to free clusters associated with bitmaps or tables.
	 */
	for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
		b = ext2fs_block_bitmap_loc(rfs->new_fs, i);
		if (ext2fs_test_block_bitmap2(new_map, b))
			ext2fs_block_bitmap_loc_set(rfs->new_fs, i, 0);
		else if (ext2fs_test_block_bitmap2(old_map, b))
			ext2fs_unmark_block_bitmap2(old_map, b);

		b = ext2fs_inode_bitmap_loc(rfs->new_fs, i);
		if (ext2fs_test_block_bitmap2(new_map, b))
			ext2fs_inode_bitmap_loc_set(rfs->new_fs, i, 0);
		else if (ext2fs_test_block_bitmap2(old_map, b))
			ext2fs_unmark_block_bitmap2(old_map, b);

		c = ext2fs_inode_table_loc(rfs->new_fs, i);
		for (b = 0;
		     b < rfs->new_fs->inode_blocks_per_group;
		     b++) {
			if (ext2fs_test_block_bitmap2(new_map, b + c))
				ext2fs_inode_table_loc_set(rfs->new_fs, i, 0);
			else if (ext2fs_test_block_bitmap2(old_map, b + c))
				ext2fs_unmark_block_bitmap2(old_map, b + c);
		}
	}

	/* Free unused clusters */
	for (b = 0;
	     cluster_ratio > 1 && b < ext2fs_blocks_count(rfs->new_fs->super);
	     b += cluster_ratio)
		if (ext2fs_test_block_bitmap2(old_map, b))
			ext2fs_unmark_block_bitmap2(rfs->new_fs->block_map, b);
out:
	if (old_map)
		ext2fs_free_block_bitmap(old_map);
	if (new_map)
		ext2fs_free_block_bitmap(new_map);
	return retval;
}

/* Zero out the high bits of extent fields */
static errcode_t zero_high_bits_in_extents(ext2_filsys fs, ext2_ino_t ino,
				 struct ext2_inode *inode)
{
	ext2_extent_handle_t	handle;
	struct ext2fs_extent	extent;
	int			op = EXT2_EXTENT_ROOT;
	errcode_t		errcode;

	if (!(inode->i_flags & EXT4_EXTENTS_FL))
		return 0;

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

	while (1) {
		errcode = ext2fs_extent_get(handle, op, &extent);
		if (errcode)
			break;

		op = EXT2_EXTENT_NEXT_SIB;

		if (extent.e_pblk > (1ULL << 32)) {
			extent.e_pblk &= (1ULL << 32) - 1;
			errcode = ext2fs_extent_replace(handle, 0, &extent);
			if (errcode)
				break;
		}
	}

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

/* Zero out the high bits of inodes. */
static errcode_t zero_high_bits_in_inodes(ext2_resize_t rfs)
{
	ext2_filsys	fs = rfs->old_fs;
	int length = EXT2_INODE_SIZE(fs->super);
	struct ext2_inode *inode = NULL;
	ext2_inode_scan	scan = NULL;
	errcode_t	retval;
	ext2_ino_t	ino;

	if (!(rfs->flags & (RESIZE_DISABLE_64BIT | RESIZE_ENABLE_64BIT)))
		return 0;

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

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

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

		/*
		 * Here's how we deal with high block number fields:
		 *
		 *  - i_size_high has been been written out with i_size_lo
		 *    since the ext2 days, so no conversion is needed.
		 *
		 *  - i_blocks_hi is guarded by both the huge_file feature and
		 *    inode flags and has always been written out with
		 *    i_blocks_lo if the feature is set.  The field is only
		 *    ever read if both feature and inode flag are set, so
		 *    we don't need to zero it now.
		 *
		 *  - i_file_acl_high can be uninitialized, so zero it if
		 *    it isn't already.
		 */
		if (inode->osd2.linux2.l_i_file_acl_high) {
			inode->osd2.linux2.l_i_file_acl_high = 0;
			retval = ext2fs_write_inode_full(fs, ino, inode,
							 length);
			if (retval)
				goto out;
		}

		retval = zero_high_bits_in_extents(fs, ino, inode);
		if (retval)
			goto out;
	} while (ino);

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

/*
 * Clean up the bitmaps for uninitialized bitmaps
 */
static void fix_uninit_block_bitmaps(ext2_filsys fs)
{
	blk64_t		blk, lblk;
	dgrp_t		g;
	unsigned int	i;

	if (!ext2fs_has_group_desc_csum(fs))
		return;

	for (g=0; g < fs->group_desc_count; g++) {
		if (!(ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT)))
			continue;

		blk = ext2fs_group_first_block2(fs, g);
		lblk = ext2fs_group_last_block2(fs, g);
		ext2fs_unmark_block_bitmap_range2(fs->block_map, blk,
						  lblk - blk + 1);

		ext2fs_reserve_super_and_bgd(fs, g, fs->block_map);
		ext2fs_mark_block_bitmap2(fs->block_map,
					  ext2fs_block_bitmap_loc(fs, g));
		ext2fs_mark_block_bitmap2(fs->block_map,
					  ext2fs_inode_bitmap_loc(fs, g));
		for (i = 0, blk = ext2fs_inode_table_loc(fs, g);
		     i < fs->inode_blocks_per_group;
		     i++, blk++)
			ext2fs_mark_block_bitmap2(fs->block_map, blk);
	}
}

/* --------------------------------------------------------------------
 *
 * Resize processing, phase 1.
 *
 * In this phase we adjust the in-memory superblock information, and
 * initialize any new parts of the inode table.  The new parts of the
 * inode table are created in virgin disk space, so we can abort here
 * without any side effects.
 * --------------------------------------------------------------------
 */

/*
 * If the group descriptor's bitmap and inode table blocks are valid,
 * release them in the new filesystem data structure, and mark them as
 * reserved so the old inode table blocks don't get overwritten.
 */
static errcode_t free_gdp_blocks(ext2_filsys fs,
				 ext2fs_block_bitmap reserve_blocks,
				 ext2_filsys old_fs,
				 dgrp_t group)
{
	blk64_t		blk;
	unsigned int	j;
	dgrp_t		i;
	ext2fs_block_bitmap bg_map = NULL;
	errcode_t	retval = 0;
	dgrp_t		count = old_fs->group_desc_count - fs->group_desc_count;

	/* If bigalloc, don't free metadata living in the same cluster */
	if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
		retval = ext2fs_allocate_block_bitmap(fs, "bgdata", &bg_map);
		if (retval)
			goto out;

		retval = mark_table_blocks(fs, bg_map);
		if (retval)
			goto out;
	}

	for (i = group; i < group + count; i++) {
		blk = ext2fs_block_bitmap_loc(old_fs, i);
		if (blk &&
		    (blk < ext2fs_blocks_count(fs->super)) &&
		    !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) {
			ext2fs_block_alloc_stats2(fs, blk, -1);
			ext2fs_mark_block_bitmap2(reserve_blocks, blk);
		}

		blk = ext2fs_inode_bitmap_loc(old_fs, i);
		if (blk &&
		    (blk < ext2fs_blocks_count(fs->super)) &&
		    !(bg_map && ext2fs_test_block_bitmap2(bg_map, blk))) {
			ext2fs_block_alloc_stats2(fs, blk, -1);
			ext2fs_mark_block_bitmap2(reserve_blocks, blk);
		}

		blk = ext2fs_inode_table_loc(old_fs, i);
		for (j = 0;
		     j < fs->inode_blocks_per_group; j++, blk++) {
			if (blk >= ext2fs_blocks_count(fs->super) ||
			    (bg_map && ext2fs_test_block_bitmap2(bg_map, blk)))
				continue;
			ext2fs_block_alloc_stats2(fs, blk, -1);
			ext2fs_mark_block_bitmap2(reserve_blocks, blk);
		}
	}

out:
	if (bg_map)
		ext2fs_free_block_bitmap(bg_map);
	return retval;
}

/*
 * This routine is shared by the online and offline resize routines.
 * All of the information which is adjusted in memory is done here.
 */
errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
			 ext2fs_block_bitmap reserve_blocks, blk64_t new_size)
{
	errcode_t	retval;
	blk64_t		overhead = 0;
	blk64_t		rem;
	blk64_t		blk, group_block;
	blk64_t		real_end;
	blk64_t		old_numblocks, numblocks, adjblocks;
	unsigned long	i, j, old_desc_blocks;
	unsigned int	meta_bg, meta_bg_size;
	int		has_super, csum_flag, has_bg;
	unsigned long long new_inodes;	/* u64 to check for overflow */
	double		percent;

	ext2fs_blocks_count_set(fs->super, new_size);

retry:
	fs->group_desc_count = ext2fs_div64_ceil(ext2fs_blocks_count(fs->super) -
				       fs->super->s_first_data_block,
				       EXT2_BLOCKS_PER_GROUP(fs->super));
	if (fs->group_desc_count == 0)
		return EXT2_ET_TOOSMALL;
	fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
					  EXT2_DESC_PER_BLOCK(fs->super));

	/*
	 * Overhead is the number of bookkeeping blocks per group.  It
	 * includes the superblock backup, the group descriptor
	 * backups, the inode bitmap, the block bitmap, and the inode
	 * table.
	 */
	overhead = (int) (2 + fs->inode_blocks_per_group);

	has_bg = 0;
	if (ext2fs_has_feature_sparse_super2(fs->super)) {
		/*
		 * We have to do this manually since
		 * super->s_backup_bgs hasn't been set up yet.
		 */
		if (fs->group_desc_count == 2)
			has_bg = fs->super->s_backup_bgs[0] != 0;
		else
			has_bg = fs->super->s_backup_bgs[1] != 0;
	} else
		has_bg = ext2fs_bg_has_super(fs, fs->group_desc_count - 1);
	if (has_bg)
		overhead += 1 + fs->desc_blocks +
			fs->super->s_reserved_gdt_blocks;

	/*
	 * See if the last group is big enough to support the
	 * necessary data structures.  If not, we need to get rid of
	 * it.
	 */
	rem = (ext2fs_blocks_count(fs->super) - fs->super->s_first_data_block) %
		fs->super->s_blocks_per_group;
	if ((fs->group_desc_count == 1) && rem && (rem < overhead))
		return EXT2_ET_TOOSMALL;
	if ((fs->group_desc_count > 1) && rem && (rem < overhead+50)) {
		ext2fs_blocks_count_set(fs->super,
					ext2fs_blocks_count(fs->super) - rem);
		goto retry;
	}
	/*
	 * Adjust the number of inodes
	 */
	new_inodes =(unsigned long long) fs->super->s_inodes_per_group * fs->group_desc_count;
	if (new_inodes > ~0U) {
		fprintf(stderr, _("inodes (%llu) must be less than %u\n"),
				   new_inodes, ~0U);
		return EXT2_ET_TOO_MANY_INODES;
	}
	fs->super->s_inodes_count = fs->super->s_inodes_per_group *
		fs->group_desc_count;

	/*
	 * Adjust the number of free blocks
	 */
	blk = ext2fs_blocks_count(old_fs->super);
	if (blk > ext2fs_blocks_count(fs->super))
		ext2fs_free_blocks_count_set(fs->super, 
			ext2fs_free_blocks_count(fs->super) -
			(blk - ext2fs_blocks_count(fs->super)));
	else
		ext2fs_free_blocks_count_set(fs->super, 
			ext2fs_free_blocks_count(fs->super) +
			(ext2fs_blocks_count(fs->super) - blk));

	/*
	 * Adjust the number of reserved blocks
	 */
	percent = (ext2fs_r_blocks_count(old_fs->super) * 100.0) /
		ext2fs_blocks_count(old_fs->super);
	ext2fs_r_blocks_count_set(fs->super,
				  (percent * ext2fs_blocks_count(fs->super) /
				   100.0));

	/*
	 * Adjust the bitmaps for size
	 */
	retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count,
					    fs->super->s_inodes_count,
					    fs->inode_map);
	if (retval) goto errout;

	real_end = EXT2_GROUPS_TO_BLOCKS(fs->super, fs->group_desc_count) - 1 +
		fs->super->s_first_data_block;
	retval = ext2fs_resize_block_bitmap2(new_size - 1,
					     real_end, fs->block_map);
	if (retval) goto errout;

	/*
	 * If we are growing the file system, also grow the size of
	 * the reserve_blocks bitmap
	 */
	if (reserve_blocks && new_size > ext2fs_blocks_count(old_fs->super)) {
		retval = ext2fs_resize_block_bitmap2(new_size - 1,
						     real_end, reserve_blocks);
		if (retval) goto errout;
	}

	/*
	 * Reallocate the group descriptors as necessary.
	 */
	if (EXT2_DESC_SIZE(old_fs->super) == EXT2_DESC_SIZE(fs->super) &&
	    old_fs->desc_blocks != fs->desc_blocks) {
		retval = ext2fs_resize_mem(old_fs->desc_blocks *
					   fs->blocksize,
					   fs->desc_blocks * fs->blocksize,
					   &fs->group_desc);
		if (retval)
			goto errout;
		if (fs->desc_blocks > old_fs->desc_blocks)
			memset((char *) fs->group_desc +
			       (old_fs->desc_blocks * fs->blocksize), 0,
			       (fs->desc_blocks - old_fs->desc_blocks) *
			       fs->blocksize);
	}

	/*
	 * If the resize_inode feature is set, and we are changing the
	 * number of descriptor blocks, then adjust
	 * s_reserved_gdt_blocks if possible to avoid needing to move
	 * the inode table either now or in the future.
	 *
	 * Note: If we're converting to 64bit mode, we did this earlier.
	 */
	if (EXT2_DESC_SIZE(old_fs->super) == EXT2_DESC_SIZE(fs->super))
		adjust_reserved_gdt_blocks(old_fs, fs);

	if (ext2fs_has_feature_meta_bg(fs->super) &&
	    (fs->super->s_first_meta_bg > fs->desc_blocks)) {
		ext2fs_clear_feature_meta_bg(fs->super);
		fs->super->s_first_meta_bg = 0;
	}

	/*
	 * Update the location of the backup superblocks if the
	 * sparse_super2 feature is enabled.
	 */
	if (ext2fs_has_feature_sparse_super2(fs->super)) {
		dgrp_t last_bg = fs->group_desc_count - 1;
		dgrp_t old_last_bg = old_fs->group_desc_count - 1;

		if (last_bg > old_last_bg) {
			if (old_fs->group_desc_count == 1)
				fs->super->s_backup_bgs[0] = 1;
			if ((old_fs->group_desc_count < 3 &&
			     fs->group_desc_count > 2) ||
			    fs->super->s_backup_bgs[1])
				fs->super->s_backup_bgs[1] = last_bg;
		} else if (last_bg < old_last_bg) {
			if (fs->super->s_backup_bgs[0] > last_bg)
				fs->super->s_backup_bgs[0] = 0;
			if (fs->super->s_backup_bgs[1] > last_bg)
				fs->super->s_backup_bgs[1] = 0;
			if (last_bg > 1 &&
			    old_fs->super->s_backup_bgs[1] == old_last_bg)
				fs->super->s_backup_bgs[1] = last_bg;
		}
	}

	/*
	 * If we are shrinking the number of block groups, we're done
	 * and can exit now.
	 */
	if (old_fs->group_desc_count > fs->group_desc_count) {
		/*
		 * Check the block groups that we are chopping off
		 * and free any blocks associated with their metadata
		 */
		retval = free_gdp_blocks(fs, reserve_blocks, old_fs,
					 fs->group_desc_count);
		goto errout;
	}

	/*
	 * Fix the count of the last (old) block group
	 */
	old_numblocks = (ext2fs_blocks_count(old_fs->super) -
			 old_fs->super->s_first_data_block) %
				 old_fs->super->s_blocks_per_group;
	if (!old_numblocks)
		old_numblocks = old_fs->super->s_blocks_per_group;
	if (old_fs->group_desc_count == fs->group_desc_count) {
		numblocks = (ext2fs_blocks_count(fs->super) -
			     fs->super->s_first_data_block) %
			fs->super->s_blocks_per_group;
		if (!numblocks)
			numblocks = fs->super->s_blocks_per_group;
	} else
		numblocks = fs->super->s_blocks_per_group;
	i = old_fs->group_desc_count - 1;
	ext2fs_bg_free_blocks_count_set(fs, i, ext2fs_bg_free_blocks_count(fs, i) + (numblocks - old_numblocks));
	ext2fs_group_desc_csum_set(fs, i);

	/*
	 * If the number of block groups is staying the same, we're
	 * done and can exit now.  (If the number block groups is
	 * shrinking, we had exited earlier.)
	 */
	if (old_fs->group_desc_count >= fs->group_desc_count) {
		retval = 0;
		goto errout;
	}

	/*
	 * Initialize the new block group descriptors
	 */
	group_block = ext2fs_group_first_block2(fs,
						old_fs->group_desc_count);
	csum_flag = ext2fs_has_group_desc_csum(fs);
	if (getenv("RESIZE2FS_FORCE_LAZY_ITABLE_INIT") ||
	    (!getenv("RESIZE2FS_FORCE_ITABLE_INIT") &&
	     access("/sys/fs/ext4/features/lazy_itable_init", F_OK) == 0))
		lazy_itable_init = 1;
	if (ext2fs_has_feature_meta_bg(fs->super))
		old_desc_blocks = fs->super->s_first_meta_bg;
	else
		old_desc_blocks = fs->desc_blocks +
			fs->super->s_reserved_gdt_blocks;

	/*
	 * If we changed the number of block_group descriptor blocks,
	 * we need to make sure they are all marked as reserved in the
	 * filesystem's block allocation map.
	 */
	for (i = 0; i < old_fs->group_desc_count; i++)
		ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);

	for (i = old_fs->group_desc_count;
	     i < fs->group_desc_count; i++) {
		memset(ext2fs_group_desc(fs, fs->group_desc, i), 0,
		       sizeof(struct ext2_group_desc));
		adjblocks = 0;

		ext2fs_bg_flags_zap(fs, i);
		if (csum_flag) {
			ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);
			if (!lazy_itable_init)
				ext2fs_bg_flags_set(fs, i,
						    EXT2_BG_INODE_ZEROED);
			ext2fs_bg_itable_unused_set(fs, i,
					fs->super->s_inodes_per_group);
		}

		numblocks = ext2fs_group_blocks_count(fs, i);
		if ((i < fs->group_desc_count - 1) && csum_flag)
			ext2fs_bg_flags_set(fs, i, EXT2_BG_BLOCK_UNINIT);

		has_super = ext2fs_bg_has_super(fs, i);
		if (has_super) {
			ext2fs_block_alloc_stats2(fs, group_block, +1);
			adjblocks++;
		}
		meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
		meta_bg = i / meta_bg_size;
		if (!ext2fs_has_feature_meta_bg(fs->super) ||
		    (meta_bg < fs->super->s_first_meta_bg)) {
			if (has_super) {
				for (j=0; j < old_desc_blocks; j++)
					ext2fs_block_alloc_stats2(fs,
						 group_block + 1 + j, +1);
				adjblocks += old_desc_blocks;
			}
		} else {
			if (has_super)
				has_super = 1;
			if (((i % meta_bg_size) == 0) ||
			    ((i % meta_bg_size) == 1) ||
			    ((i % meta_bg_size) == (meta_bg_size-1)))
				ext2fs_block_alloc_stats2(fs,
						 group_block + has_super, +1);
		}

		adjblocks += 2 + fs->inode_blocks_per_group;

		numblocks -= adjblocks;
		ext2fs_free_blocks_count_set(fs->super,
			     ext2fs_free_blocks_count(fs->super) - adjblocks);
		fs->super->s_free_inodes_count +=
			fs->super->s_inodes_per_group;
		ext2fs_bg_free_blocks_count_set(fs, i, numblocks);
		ext2fs_bg_free_inodes_count_set(fs, i,
						fs->super->s_inodes_per_group);
		ext2fs_bg_used_dirs_count_set(fs, i, 0);
		ext2fs_group_desc_csum_set(fs, i);

		retval = ext2fs_allocate_group_table(fs, i, 0);
		if (retval) goto errout;

		group_block += fs->super->s_blocks_per_group;
	}
	retval = 0;

	/*
	 * Mark all of the metadata blocks as reserved so they won't
	 * get allocated by the call to ext2fs_allocate_group_table()
	 * in blocks_to_move(), where we allocate new blocks to
	 * replace those allocation bitmap and inode table blocks
	 * which have to get relocated to make space for an increased
	 * number of the block group descriptors.
	 */
	if (reserve_blocks)
		mark_table_blocks(fs, reserve_blocks);

errout:
	return (retval);
}

/*
 * This routine adjusts the superblock and other data structures, both
 * in disk as well as in memory...
 */
static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
{
	ext2_filsys	fs = rfs->new_fs;
	int		adj = 0;
	errcode_t	retval;
	blk64_t		group_block;
	unsigned long	i;
	unsigned long	max_group;

	ext2fs_mark_super_dirty(fs);
	ext2fs_mark_bb_dirty(fs);
	ext2fs_mark_ib_dirty(fs);

	retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"),
					      &rfs->reserve_blocks);
	if (retval)
		return retval;

	retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size);
	if (retval)
		goto errout;

	/*
	 * Check to make sure there are enough inodes
	 */
	if ((rfs->old_fs->super->s_inodes_count -
	     rfs->old_fs->super->s_free_inodes_count) >
	    rfs->new_fs->super->s_inodes_count) {
		retval = ENOSPC;
		goto errout;
	}

	/*
	 * If we are shrinking the number block groups, we're done and
	 * can exit now.
	 */
	if (rfs->old_fs->group_desc_count > fs->group_desc_count) {
		retval = 0;
		goto errout;
	}

	/*
	 * If the number of block groups is staying the same, we're
	 * done and can exit now.  (If the number block groups is
	 * shrinking, we had exited earlier.)
	 */
	if (rfs->old_fs->group_desc_count >= fs->group_desc_count) {
		retval = 0;
		goto errout;
	}

	/*
	 * If we are using uninit_bg (aka GDT_CSUM) and the kernel
	 * supports lazy inode initialization, we can skip
	 * initializing the inode table.
	 */
	if (lazy_itable_init && ext2fs_has_group_desc_csum(fs)) {
		retval = 0;
		goto errout;
	}

	/*
	 * Initialize the inode table
	 */
	retval = ext2fs_get_array(fs->blocksize, fs->inode_blocks_per_group,
				&rfs->itable_buf);
	if (retval)
		goto errout;

	memset(rfs->itable_buf, 0, fs->blocksize * fs->inode_blocks_per_group);
	group_block = ext2fs_group_first_block2(fs,
						rfs->old_fs->group_desc_count);
	adj = rfs->old_fs->group_desc_count;
	max_group = fs->group_desc_count - adj;
	if (rfs->progress) {
		retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS,
				       0, max_group);
		if (retval)
			goto errout;
	}
	for (i = rfs->old_fs->group_desc_count;
	     i < fs->group_desc_count; i++) {
		/*
		 * Write out the new inode table
		 */
		retval = ext2fs_zero_blocks2(fs, ext2fs_inode_table_loc(fs, i),
					     fs->inode_blocks_per_group, NULL,
					     NULL);
		if (retval)
			goto errout;

		io_channel_flush(fs->io);
		if (rfs->progress) {
			retval = rfs->progress(rfs, E2_RSZ_EXTEND_ITABLE_PASS,
					       i - adj + 1, max_group);
			if (retval)
				goto errout;
		}
		group_block += fs->super->s_blocks_per_group;
	}
	io_channel_flush(fs->io);
	retval = 0;

errout:
	return retval;
}

/* --------------------------------------------------------------------
 *
 * Resize processing, phase 2.
 *
 * In this phase we adjust determine which blocks need to be moved, in
 * blocks_to_move().  We then copy the blocks to their ultimate new
 * destinations using block_mover().  Since we are copying blocks to
 * their new locations, again during this pass we can abort without
 * any problems.
 * --------------------------------------------------------------------
 */

/*
 * This helper function creates a block bitmap with all of the
 * filesystem meta-data blocks.
 */
static errcode_t mark_table_blocks(ext2_filsys fs,
				   ext2fs_block_bitmap bmap)
{
	dgrp_t			i;
	blk64_t			blk;

	for (i = 0; i < fs->group_desc_count; i++) {
		ext2fs_reserve_super_and_bgd(fs, i, bmap);

		/*
		 * Mark the blocks used for the inode table
		 */
		blk = ext2fs_inode_table_loc(fs, i);
		if (blk)
			ext2fs_mark_block_bitmap_range2(bmap, blk,
						fs->inode_blocks_per_group);

		/*
		 * Mark block used for the block bitmap
		 */
		blk = ext2fs_block_bitmap_loc(fs, i);
		if (blk)
			ext2fs_mark_block_bitmap2(bmap, blk);

		/*
		 * Mark block used for the inode bitmap
		 */
		blk = ext2fs_inode_bitmap_loc(fs, i);
		if (blk)
			ext2fs_mark_block_bitmap2(bmap, blk);
	}
	return 0;
}

/*
 * This function checks to see if a particular block (either a
 * superblock or a block group descriptor) overlaps with an inode or
 * block bitmap block, or with the inode table.
 */
static void mark_fs_metablock(ext2_resize_t rfs,
			      ext2fs_block_bitmap meta_bmap,
			      int group, blk64_t blk)
{
	ext2_filsys fs = rfs->new_fs;

	ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
	ext2fs_block_alloc_stats2(fs, blk, +1);

	/*
	 * Check to see if we overlap with the inode or block bitmap,
	 * or the inode tables.  If not, and the block is in use, then
	 * mark it as a block to be moved.
	 */
	if (is_block_bm(fs, group, blk)) {
		ext2fs_block_bitmap_loc_set(fs, group, 0);
		rfs->needed_blocks++;
		return;
	}
	if (is_inode_bm(fs, group, blk)) {
		ext2fs_inode_bitmap_loc_set(fs, group, 0);
		rfs->needed_blocks++;
		return;
	}
	if (is_inode_tb(fs, group, blk)) {
		ext2fs_inode_table_loc_set(fs, group, 0);
		rfs->needed_blocks++;
		return;
	}
	if (ext2fs_has_feature_flex_bg(fs->super)) {
		dgrp_t i;

		for (i = 0; i < rfs->old_fs->group_desc_count; i++) {
			if (is_block_bm(fs, i, blk)) {
				ext2fs_block_bitmap_loc_set(fs, i, 0);
				rfs->needed_blocks++;
				return;
			}
			if (is_inode_bm(fs, i, blk)) {
				ext2fs_inode_bitmap_loc_set(fs, i, 0);
				rfs->needed_blocks++;
				return;
			}
			if (is_inode_tb(fs, i, blk)) {
				ext2fs_inode_table_loc_set(fs, i, 0);
				rfs->needed_blocks++;
				return;
			}
		}
	}

	if (ext2fs_has_group_desc_csum(fs) &&
	    (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))) {
		/*
		 * If the block bitmap is uninitialized, which means
		 * nothing other than standard metadata in use.
		 */
		return;
	} else if (ext2fs_test_block_bitmap2(rfs->old_fs->block_map, blk) &&
		   !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
		ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
		rfs->needed_blocks++;
	}
}


/*
 * This routine marks and unmarks reserved blocks in the new block
 * bitmap.  It also determines which blocks need to be moved and
 * places this information into the move_blocks bitmap.
 */
static errcode_t blocks_to_move(ext2_resize_t rfs)
{
	unsigned int	j;
	int		has_super;
	dgrp_t		i, max_groups, g;
	blk64_t		blk, group_blk;
	blk64_t		old_blocks, new_blocks, group_end, cluster_freed;
	blk64_t		new_size;
	unsigned int	meta_bg, meta_bg_size;
	errcode_t	retval;
	ext2_filsys 	fs, old_fs;
	ext2fs_block_bitmap	meta_bmap, new_meta_bmap = NULL;
	int		flex_bg;

	fs = rfs->new_fs;
	old_fs = rfs->old_fs;
	if (ext2fs_blocks_count(old_fs->super) > ext2fs_blocks_count(fs->super))
		fs = rfs->old_fs;

	retval = ext2fs_allocate_block_bitmap(fs, _("blocks to be moved"),
					      &rfs->move_blocks);
	if (retval)
		return retval;

	retval = ext2fs_allocate_block_bitmap(fs, _("meta-data blocks"),
					      &meta_bmap);
	if (retval)
		return retval;

	retval = mark_table_blocks(old_fs, meta_bmap);
	if (retval)
		return retval;

	fs = rfs->new_fs;

	/*
	 * If we're shrinking the filesystem, we need to move any
	 * group's metadata blocks (either allocation bitmaps or the
	 * inode table) which are beyond the end of the new
	 * filesystem.
	 */
	new_size = ext2fs_blocks_count(fs->super);
	if (new_size < ext2fs_blocks_count(old_fs->super)) {
		for (g = 0; g < fs->group_desc_count; g++) {
			int realloc = 0;
			/*
			 * ext2fs_allocate_group_table will re-allocate any
			 * metadata blocks whose location is set to zero.
			 */
			if (ext2fs_block_bitmap_loc(fs, g) >= new_size) {
				ext2fs_block_bitmap_loc_set(fs, g, 0);
				realloc = 1;
			}
			if (ext2fs_inode_bitmap_loc(fs, g) >= new_size) {
				ext2fs_inode_bitmap_loc_set(fs, g, 0);
				realloc = 1;
			}
			if ((ext2fs_inode_table_loc(fs, g) +
			     fs->inode_blocks_per_group) > new_size) {
				ext2fs_inode_table_loc_set(fs, g, 0);
				realloc = 1;
			}

			if (realloc) {
				retval = ext2fs_allocate_group_table(fs, g, 0);
				if (retval)
					return retval;
			}
		}
	}

	/*
	 * If we're shrinking the filesystem, we need to move all of
	 * the blocks that don't fit any more
	 */
	for (blk = ext2fs_blocks_count(fs->super);
	     blk < ext2fs_blocks_count(old_fs->super); blk++) {
		g = ext2fs_group_of_blk2(fs, blk);
		if (ext2fs_has_group_desc_csum(fs) &&
		    ext2fs_bg_flags_test(old_fs, g, EXT2_BG_BLOCK_UNINIT)) {
			/*
			 * The block bitmap is uninitialized, so skip
			 * to the next block group.
			 */
			blk = ext2fs_group_first_block2(fs, g+1) - 1;
			continue;
		}
		if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
		    !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
			ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
			rfs->needed_blocks++;
		}
		ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
	}

	if (ext2fs_has_feature_meta_bg(old_fs->super))
		old_blocks = old_fs->super->s_first_meta_bg;
	else
		old_blocks = old_fs->desc_blocks +
			old_fs->super->s_reserved_gdt_blocks;
	if (ext2fs_has_feature_meta_bg(fs->super))
		new_blocks = fs->super->s_first_meta_bg;
	else
		new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;

	retval = reserve_sparse_super2_last_group(rfs, meta_bmap);
	if (retval)
		goto errout;

	if (EXT2_DESC_SIZE(rfs->old_fs->super) ==
	    EXT2_DESC_SIZE(rfs->new_fs->super) &&
	    old_blocks == new_blocks) {
		retval = 0;
		goto errout;
	}

	max_groups = fs->group_desc_count;
	if (max_groups > old_fs->group_desc_count)
		max_groups = old_fs->group_desc_count;
	group_blk = old_fs->super->s_first_data_block;
	/*
	 * If we're reducing the number of descriptor blocks, this
	 * makes life easy.  :-)   We just have to mark some extra
	 * blocks as free.
	 */
	if (old_blocks > new_blocks) {
		if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
			retval = ext2fs_allocate_block_bitmap(fs,
							_("new meta blocks"),
							&new_meta_bmap);
			if (retval)
				goto errout;

			retval = mark_table_blocks(fs, new_meta_bmap);
			if (retval)
				goto errout;
		}

		for (i = 0; i < max_groups; i++) {
			if (!ext2fs_bg_has_super(old_fs, i)) {
				group_blk += fs->super->s_blocks_per_group;
				continue;
			}
			group_end = group_blk + 1 + old_blocks;
			for (blk = group_blk + 1 + new_blocks;
			     blk < group_end;) {
				if (new_meta_bmap == NULL ||
				    !ext2fs_test_block_bitmap2(new_meta_bmap,
							       blk)) {
					cluster_freed =
						EXT2FS_CLUSTER_RATIO(fs) -
						(blk &
						 EXT2FS_CLUSTER_MASK(fs));
					if (cluster_freed > group_end - blk)
						cluster_freed = group_end - blk;
					ext2fs_block_alloc_stats2(fs, blk, -1);
					blk += EXT2FS_CLUSTER_RATIO(fs);
					rfs->needed_blocks -= cluster_freed;
					continue;
				}
				rfs->needed_blocks--;
				blk++;
			}
			group_blk += fs->super->s_blocks_per_group;
		}
		retval = 0;
		goto errout;
	}
	/*
	 * If we're increasing the number of descriptor blocks, life
	 * gets interesting....
	 */
	meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super);
	flex_bg = ext2fs_has_feature_flex_bg(fs->super);
	/* first reserve all of the existing fs meta blocks */
	for (i = 0; i < max_groups; i++) {
		has_super = ext2fs_bg_has_super(fs, i);
		if (has_super)
			mark_fs_metablock(rfs, meta_bmap, i, group_blk);

		meta_bg = i / meta_bg_size;
		if (!ext2fs_has_feature_meta_bg(fs->super) ||
		    (meta_bg < fs->super->s_first_meta_bg)) {
			if (has_super) {
				for (blk = group_blk+1;
				     blk < group_blk + 1 + new_blocks; blk++)
					mark_fs_metablock(rfs, meta_bmap,
							  i, blk);
			}
		} else {
			if (has_super)
				has_super = 1;
			if (((i % meta_bg_size) == 0) ||
			    ((i % meta_bg_size) == 1) ||
			    ((i % meta_bg_size) == (meta_bg_size-1)))
				mark_fs_metablock(rfs, meta_bmap, i,
						  group_blk + has_super);
		}

		/*
		 * Reserve the existing meta blocks that we know
		 * aren't to be moved.
		 *
		 * For flex_bg file systems, in order to avoid
		 * overwriting fs metadata (especially inode table
		 * blocks) belonging to a different block group when
		 * we are relocating the inode tables, we need to
		 * reserve all existing fs metadata blocks.
		 */
		if (ext2fs_block_bitmap_loc(fs, i))
			ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
				 ext2fs_block_bitmap_loc(fs, i));
		else if (flex_bg && i < old_fs->group_desc_count)
			ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
				 ext2fs_block_bitmap_loc(old_fs, i));

		if (ext2fs_inode_bitmap_loc(fs, i))
			ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
				 ext2fs_inode_bitmap_loc(fs, i));
		else if (flex_bg && i < old_fs->group_desc_count)
			ext2fs_mark_block_bitmap2(rfs->reserve_blocks,
				 ext2fs_inode_bitmap_loc(old_fs, i));

		if (ext2fs_inode_table_loc(fs, i))
			ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks,
					ext2fs_inode_table_loc(fs, i),
					fs->inode_blocks_per_group);
		else if (flex_bg && i < old_fs->group_desc_count)
			ext2fs_mark_block_bitmap_range2(rfs->reserve_blocks,
					ext2fs_inode_table_loc(old_fs, i),
					old_fs->inode_blocks_per_group);

		group_blk += rfs->new_fs->super->s_blocks_per_group;
	}

	/* Allocate the missing data structures */
	for (i = 0; i < max_groups; i++) {
		if (ext2fs_inode_table_loc(fs, i) &&
		    ext2fs_inode_bitmap_loc(fs, i) &&
		    ext2fs_block_bitmap_loc(fs, i))
			continue;

		retval = ext2fs_allocate_group_table(fs, i,
						     rfs->reserve_blocks);
		if (retval)
			goto errout;

		/*
		 * For those structures that have changed, we need to
		 * do bookkeeping.
		 */
		if (ext2fs_block_bitmap_loc(old_fs, i) !=
		    (blk = ext2fs_block_bitmap_loc(fs, i))) {
			ext2fs_block_alloc_stats2(fs, blk, +1);
			if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
			    !ext2fs_test_block_bitmap2(meta_bmap, blk))
				ext2fs_mark_block_bitmap2(rfs->move_blocks,
							 blk);
		}
		if (ext2fs_inode_bitmap_loc(old_fs, i) !=
		    (blk = ext2fs_inode_bitmap_loc(fs, i))) {
			ext2fs_block_alloc_stats2(fs, blk, +1);
			if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
			    !ext2fs_test_block_bitmap2(meta_bmap, blk))
				ext2fs_mark_block_bitmap2(rfs->move_blocks,
							 blk);
		}

		/*
		 * The inode table, if we need to relocate it, is
		 * handled specially.  We have to reserve the blocks
		 * for both the old and the new inode table, since we
		 * can't have the inode table be destroyed during the
		 * block relocation phase.
		 */
		if (ext2fs_inode_table_loc(fs, i) == ext2fs_inode_table_loc(old_fs, i))
			continue;	/* inode table not moved */

		rfs->needed_blocks += fs->inode_blocks_per_group;

		/*
		 * Mark the new inode table as in use in the new block
		 * allocation bitmap, and move any blocks that might
		 * be necessary.
		 */
		for (blk = ext2fs_inode_table_loc(fs, i), j=0;
		     j < fs->inode_blocks_per_group ; j++, blk++) {
			ext2fs_block_alloc_stats2(fs, blk, +1);
			if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
			    !ext2fs_test_block_bitmap2(meta_bmap, blk))
				ext2fs_mark_block_bitmap2(rfs->move_blocks,
							 blk);
		}

		/*
		 * Make sure the old inode table is reserved in the
		 * block reservation bitmap.
		 */
		for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0;
		     j < fs->inode_blocks_per_group ; j++, blk++)
			ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
	}
	retval = 0;

errout:
	if (new_meta_bmap)
		ext2fs_free_block_bitmap(new_meta_bmap);
	if (meta_bmap)
		ext2fs_free_block_bitmap(meta_bmap);

	return retval;
}

/*
 * This helper function tries to allocate a new block.  We try to
 * avoid hitting the original group descriptor blocks at least at
 * first, since we want to make it possible to recover from a badly
 * aborted resize operation as much as possible.
 *
 * In the future, I may further modify this routine to balance out
 * where we get the new blocks across the various block groups.
 * Ideally we would allocate blocks that corresponded with the block
 * group of the containing inode, and keep contiguous blocks
 * together.  However, this very difficult to do efficiently, since we
 * don't have the necessary information up front.
 */

#define AVOID_OLD	1
#define DESPERATION	2

static void init_block_alloc(ext2_resize_t rfs)
{
	rfs->alloc_state = AVOID_OLD;
	rfs->new_blk = rfs->new_fs->super->s_first_data_block;
#if 0
	/* HACK for testing */
	if (ext2fs_blocks_count(rfs->new_fs->super) >
	    ext2fs_blocks_count(rfs->old_fs->super))
		rfs->new_blk = ext2fs_blocks_count(rfs->old_fs->super);
#endif
}

static blk64_t get_new_block(ext2_resize_t rfs)
{
	ext2_filsys	fs = rfs->new_fs;

	while (1) {
		if (rfs->new_blk >= ext2fs_blocks_count(fs->super)) {
			if (rfs->alloc_state == DESPERATION)
				return 0;

#ifdef RESIZE2FS_DEBUG
			if (rfs->flags & RESIZE_DEBUG_BMOVE)
				printf("Going into desperation mode "
				       "for block allocations\n");
#endif
			rfs->alloc_state = DESPERATION;
			rfs->new_blk = fs->super->s_first_data_block;
			continue;
		}
		if (ext2fs_test_block_bitmap2(fs->block_map, rfs->new_blk) ||
		    ext2fs_test_block_bitmap2(rfs->reserve_blocks,
					     rfs->new_blk) ||
		    ((rfs->alloc_state == AVOID_OLD) &&
		     (rfs->new_blk < ext2fs_blocks_count(rfs->old_fs->super)) &&
		     ext2fs_test_block_bitmap2(rfs->old_fs->block_map,
					      rfs->new_blk))) {
			rfs->new_blk++;
			continue;
		}
		return rfs->new_blk;
	}
}

static errcode_t resize2fs_get_alloc_block(ext2_filsys fs,
					   blk64_t goal EXT2FS_ATTR((unused)),
					   blk64_t *ret)
{
	ext2_resize_t rfs = (ext2_resize_t) fs->priv_data;
	blk64_t blk;
	int group;

	blk = get_new_block(rfs);
	if (!blk)
		return ENOSPC;

#ifdef RESIZE2FS_DEBUG
	if (rfs->flags & 0xF)
		printf("get_alloc_block allocating %llu\n", blk);
#endif

	ext2fs_mark_block_bitmap2(rfs->old_fs->block_map, blk);
	ext2fs_mark_block_bitmap2(rfs->new_fs->block_map, blk);

	group = ext2fs_group_of_blk2(rfs->old_fs, blk);
	ext2fs_clear_block_uninit(rfs->old_fs, group);
	group = ext2fs_group_of_blk2(rfs->new_fs, blk);
	ext2fs_clear_block_uninit(rfs->new_fs, group);

	*ret = (blk64_t) blk;
	return 0;
}

static errcode_t block_mover(ext2_resize_t rfs)
{
	blk64_t			blk, old_blk, new_blk;
	ext2_filsys		fs = rfs->new_fs;
	ext2_filsys		old_fs = rfs->old_fs;
	errcode_t		retval;
	__u64			c, size;
	int			to_move, moved;
	ext2_badblocks_list	badblock_list = 0;
	int			bb_modified = 0;

	fs->get_alloc_block = resize2fs_get_alloc_block;
	old_fs->get_alloc_block = resize2fs_get_alloc_block;

	retval = ext2fs_read_bb_inode(old_fs, &badblock_list);
	if (retval)
		return retval;

	new_blk = fs->super->s_first_data_block;
	if (!rfs->itable_buf) {
		retval = ext2fs_get_array(fs->blocksize,
					fs->inode_blocks_per_group,
					&rfs->itable_buf);
		if (retval)
			return retval;
	}
	retval = ext2fs_create_extent_table(&rfs->bmap, 0);
	if (retval)
		return retval;

	/*
	 * The first step is to figure out where all of the blocks
	 * will go.
	 */
	to_move = moved = 0;
	init_block_alloc(rfs);
	for (blk = B2C(old_fs->super->s_first_data_block);
	     blk < ext2fs_blocks_count(old_fs->super);
	     blk += EXT2FS_CLUSTER_RATIO(fs)) {
		if (!ext2fs_test_block_bitmap2(old_fs->block_map, blk))
			continue;
		if (!ext2fs_test_block_bitmap2(rfs->move_blocks, blk))
			continue;
		if (ext2fs_badblocks_list_test(badblock_list, blk)) {
			ext2fs_badblocks_list_del(badblock_list, blk);
			bb_modified++;
			continue;
		}

		new_blk = get_new_block(rfs);
		if (!new_blk) {
			retval = ENOSPC;
			goto errout;
		}
		ext2fs_block_alloc_stats2(fs, new_blk, +1);
		ext2fs_add_extent_entry(rfs->bmap, B2C(blk), B2C(new_blk));
		to_move++;
	}

	if (to_move == 0) {
		if (rfs->bmap) {
			ext2fs_free_extent_table(rfs->bmap);
			rfs->bmap = 0;
		}
		retval = 0;
		goto errout;
	}

	/*
	 * Step two is to actually move the blocks
	 */
	retval =  ext2fs_iterate_extent(rfs->bmap, 0, 0, 0);
	if (retval) goto errout;

	if (rfs->progress) {
		retval = (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS,
					 0, to_move);
		if (retval)
			goto errout;
	}
	while (1) {
		retval = ext2fs_iterate_extent(rfs->bmap, &old_blk, &new_blk, &size);
		if (retval) goto errout;
		if (!size)
			break;
		old_blk = C2B(old_blk);
		new_blk = C2B(new_blk);
		size = C2B(size);
#ifdef RESIZE2FS_DEBUG
		if (rfs->flags & RESIZE_DEBUG_BMOVE)
			printf("Moving %llu blocks %llu->%llu\n",
			       size, old_blk, new_blk);
#endif
		do {
			c = size;
			if (c > fs->inode_blocks_per_group)
				c = fs->inode_blocks_per_group;
			retval = io_channel_read_blk64(fs->io, old_blk, c,
						       rfs->itable_buf);
			if (retval) goto errout;
			retval = io_channel_write_blk64(fs->io, new_blk, c,
							rfs->itable_buf);
			if (retval) goto errout;
			size -= c;
			new_blk += c;
			old_blk += c;
			moved += c;
			if (rfs->progress) {
				io_channel_flush(fs->io);
				retval = (rfs->progress)(rfs,
						E2_RSZ_BLOCK_RELOC_PASS,
						moved, to_move);
				if (retval)
					goto errout;
			}
		} while (size > 0);
		io_channel_flush(fs->io);
	}

errout:
	if (badblock_list) {
		if (!retval && bb_modified)
			retval = ext2fs_update_bb_inode(old_fs,
							badblock_list);
		ext2fs_badblocks_list_free(badblock_list);
	}
	return retval;
}


/* --------------------------------------------------------------------
 *
 * Resize processing, phase 3
 *
 * --------------------------------------------------------------------
 */


/*
 * The extent translation table is stored in clusters so we need to
 * take special care when mapping a source block number to its
 * destination block number.
 */
static __u64 extent_translate(ext2_filsys fs, ext2_extent extent, __u64 old_loc)
{
	__u64 new_block = C2B(ext2fs_extent_translate(extent, B2C(old_loc)));

	if (new_block != 0)
		new_block += old_loc & (EXT2FS_CLUSTER_RATIO(fs) - 1);
	return new_block;
}

struct process_block_struct {
	ext2_resize_t 		rfs;
	ext2_ino_t		ino;
	ext2_ino_t		old_ino;
	struct ext2_inode *	inode;
	errcode_t		error;
	int			is_dir;
	int			changed;
	int			has_extents;
};

static int process_block(ext2_filsys fs, blk64_t	*block_nr,
			 e2_blkcnt_t blockcnt,
			 blk64_t ref_block EXT2FS_ATTR((unused)),
			 int ref_offset EXT2FS_ATTR((unused)), void *priv_data)
{
	struct process_block_struct *pb;
	errcode_t	retval;
	blk64_t		block, new_block;
	int		ret = 0;

	pb = (struct process_block_struct *) priv_data;
	block = *block_nr;
	if (pb->rfs->bmap) {
		new_block = extent_translate(fs, pb->rfs->bmap, block);
		if (new_block) {
			*block_nr = new_block;
			ret |= BLOCK_CHANGED;
			pb->changed = 1;
#ifdef RESIZE2FS_DEBUG
			if (pb->rfs->flags & RESIZE_DEBUG_BMOVE)
				printf("ino=%u, blockcnt=%lld, %llu->%llu\n",
				       pb->old_ino, blockcnt, block,
				       new_block);
#endif
			block = new_block;
		}
	}

	if (pb->is_dir) {
		retval = ext2fs_add_dir_block2(fs->dblist, pb->ino,
					       block, (int) blockcnt);
		if (retval) {
			pb->error = retval;
			ret |= BLOCK_ABORT;
		}
	}
	return ret;
}

/*
 * Progress callback
 */
static errcode_t progress_callback(ext2_filsys fs,
				   ext2_inode_scan scan EXT2FS_ATTR((unused)),
				   dgrp_t group, void * priv_data)
{
	ext2_resize_t rfs = (ext2_resize_t) priv_data;
	errcode_t		retval;

	/*
	 * This check is to protect against old ext2 libraries.  It
	 * shouldn't be needed against new libraries.
	 */
	if ((group+1) == 0)
		return 0;

	if (rfs->progress) {
		io_channel_flush(fs->io);
		retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
					 group+1, fs->group_desc_count);
		if (retval)
			return retval;
	}

	return 0;
}

static errcode_t migrate_ea_block(ext2_resize_t rfs, ext2_ino_t ino,
				  struct ext2_inode *inode, int *changed)
{
	char *buf = NULL;
	blk64_t new_block;
	errcode_t err = 0;

	/* No EA block or no remapping?  Quit early. */
	if (ext2fs_file_acl_block(rfs->old_fs, inode) == 0 || !rfs->bmap)
		return 0;
	new_block = extent_translate(rfs->old_fs, rfs->bmap,
		ext2fs_file_acl_block(rfs->old_fs, inode));
	if (new_block == 0)
		return 0;

	/* Set the new ACL block */
	ext2fs_file_acl_block_set(rfs->old_fs, inode, new_block);

	/* Update checksum */
	if (ext2fs_has_feature_metadata_csum(rfs->new_fs->super)) {
		err = ext2fs_get_mem(rfs->old_fs->blocksize, &buf);
		if (err)
			return err;
		rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
		err = ext2fs_read_ext_attr3(rfs->old_fs, new_block, buf, ino);
		rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
		if (err)
			goto out;
		err = ext2fs_write_ext_attr3(rfs->old_fs, new_block, buf, ino);
		if (err)
			goto out;
	}
	*changed = 1;

out:
	ext2fs_free_mem(&buf);
	return err;
}

static void quiet_com_err_proc(const char *whoami EXT2FS_ATTR((unused)),
			       errcode_t code EXT2FS_ATTR((unused)),
			       const char *fmt EXT2FS_ATTR((unused)),
			       va_list args EXT2FS_ATTR((unused)))
{
}

static int fix_ea_entries(ext2_extent imap, struct ext2_ext_attr_entry *entry,
			  struct ext2_ext_attr_entry *end, ext2_ino_t last_ino)
{
	int modified = 0;
	ext2_ino_t new_ino;

	while (entry < end && !EXT2_EXT_IS_LAST_ENTRY(entry)) {
		if (entry->e_value_inum > last_ino) {
			new_ino = ext2fs_extent_translate(imap,
							  entry->e_value_inum);
			entry->e_value_inum = new_ino;
			modified = 1;
		}
		entry = EXT2_EXT_ATTR_NEXT(entry);
	}
	return modified;
}

static int fix_ea_ibody_entries(ext2_extent imap,
				struct ext2_inode_large *inode, int inode_size,
				ext2_ino_t last_ino)
{
	struct ext2_ext_attr_entry *start, *end;
	__u32 *ea_magic;

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

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

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

	return fix_ea_entries(imap, start, end, last_ino);
}

static int fix_ea_block_entries(ext2_extent imap, char *block_buf,
				unsigned int blocksize, ext2_ino_t last_ino)
{
	struct ext2_ext_attr_header *header;
	struct ext2_ext_attr_entry *start, *end;

	header = (struct ext2_ext_attr_header *)block_buf;
	start = (struct ext2_ext_attr_entry *)(header+1);
	end = (struct ext2_ext_attr_entry *)(block_buf + blocksize);

	return fix_ea_entries(imap, start, end, last_ino);
}

/* A simple LRU cache to check recently processed blocks. */
struct blk_cache {
	int cursor;
	blk64_t blks[4];
};

#define BLK_IN_CACHE(b,c) ((b) == (c).blks[0] || (b) == (c).blks[1] || \
			   (b) == (c).blks[2] || (b) == (c).blks[3])
#define BLK_ADD_CACHE(b,c) { 			\
	(c).blks[(c).cursor] = (b);		\
	(c).cursor = ((c).cursor + 1) % 4;	\
}

static errcode_t fix_ea_inode_refs(ext2_resize_t rfs, struct ext2_inode *inode,
				   char *block_buf, ext2_ino_t last_ino)
{
	ext2_filsys	fs = rfs->new_fs;
	ext2_inode_scan	scan = NULL;
	ext2_ino_t	ino;
	int		inode_size = EXT2_INODE_SIZE(fs->super);
	blk64_t		blk;
	int		modified;
	struct blk_cache blk_cache;
	struct ext2_ext_attr_header *header;
	errcode_t		retval;

	memset(&blk_cache, 0, sizeof(blk_cache));

	header = (struct ext2_ext_attr_header *)block_buf;

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

	while (1) {
		retval = ext2fs_get_next_inode_full(scan, &ino, inode,
						    inode_size);
		if (retval)
			goto out;
		if (!ino)
			break;

		if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
			continue; /* inode not in use */

		if (inode_size != EXT2_GOOD_OLD_INODE_SIZE) {
			modified = fix_ea_ibody_entries(rfs->imap,
					(struct ext2_inode_large *)inode,
					inode_size, last_ino);
			if (modified) {
				retval = ext2fs_write_inode_full(fs, ino, inode,
								 inode_size);
				if (retval)
					goto out;
			}
		}

		blk = ext2fs_file_acl_block(fs, inode);
		if (blk && !BLK_IN_CACHE(blk, blk_cache)) {
			retval = ext2fs_read_ext_attr3(fs, blk, block_buf, ino);
			if (retval)
				goto out;

			modified = fix_ea_block_entries(rfs->imap, block_buf,
							fs->blocksize,
							last_ino);
			if (modified) {
				retval = ext2fs_write_ext_attr3(fs, blk,
								block_buf, ino);
				if (retval)
					goto out;
				/*
				 * If refcount is greater than 1, we might see
				 * the same block referenced by other inodes
				 * later.
				 */
				if (header->h_refcount > 1)
					BLK_ADD_CACHE(blk, blk_cache);
			}
		}
	}
	retval = 0;
out:
	if (scan)
		ext2fs_close_inode_scan(scan);
	return retval;

}
static errcode_t inode_scan_and_fix(ext2_resize_t rfs)
{
	struct process_block_struct	pb;
	ext2_ino_t		ino, new_inode;
	struct ext2_inode 	*inode = NULL;
	ext2_inode_scan 	scan = NULL;
	errcode_t		retval;
	char			*block_buf = 0;
	ext2_ino_t		start_to_move;
	int			inode_size;
	int			update_ea_inode_refs = 0;

	if ((rfs->old_fs->group_desc_count <=
	     rfs->new_fs->group_desc_count) &&
	    !rfs->bmap)
		return 0;

	set_com_err_hook(quiet_com_err_proc);

	retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan);
	if (retval) goto errout;

	retval = ext2fs_init_dblist(rfs->old_fs, 0);
	if (retval) goto errout;
	retval = ext2fs_get_array(rfs->old_fs->blocksize, 3, &block_buf);
	if (retval) goto errout;

	start_to_move = (rfs->new_fs->group_desc_count *
			 rfs->new_fs->super->s_inodes_per_group);

	if (rfs->progress) {
		retval = (rfs->progress)(rfs, E2_RSZ_INODE_SCAN_PASS,
					 0, rfs->old_fs->group_desc_count);
		if (retval)
			goto errout;
	}
	ext2fs_set_inode_callback(scan, progress_callback, (void *) rfs);
	pb.rfs = rfs;
	pb.inode = inode;
	pb.error = 0;
	new_inode = EXT2_FIRST_INODE(rfs->new_fs->super);
	inode_size = EXT2_INODE_SIZE(rfs->new_fs->super);
	inode = malloc(inode_size);
	if (!inode) {
		retval = ENOMEM;
		goto errout;
	}
	/*
	 * First, copy all of the inodes that need to be moved
	 * elsewhere in the inode table
	 */
	while (1) {
		retval = ext2fs_get_next_inode_full(scan, &ino, inode, inode_size);
		if (retval) goto errout;
		if (!ino)
			break;

		if (inode->i_links_count == 0 && ino != EXT2_RESIZE_INO)
			continue; /* inode not in use */

		pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
		pb.changed = 0;

		/* Remap EA block */
		retval = migrate_ea_block(rfs, ino, inode, &pb.changed);
		if (retval)
			goto errout;

		new_inode = ino;
		if (ino <= start_to_move)
			goto remap_blocks; /* Don't need to move inode. */

		/*
		 * Find a new inode.  Now that extents and directory blocks
		 * are tied to the inode number through the checksum, we must
		 * set up the new inode before we start rewriting blocks.
		 */
		retval = ext2fs_new_inode(rfs->new_fs, 0, 0, 0, &new_inode);
		if (retval)
			goto errout;

		ext2fs_inode_alloc_stats2(rfs->new_fs, new_inode, +1,
					  pb.is_dir);
		/*
		 * i_ctime field in xattr inodes contain a portion of the ref
		 * count, do not overwrite.
		 */
		if (inode->i_flags & EXT4_EA_INODE_FL)
			update_ea_inode_refs = 1;
		else
			inode->i_ctime = time(0);

		retval = ext2fs_write_inode_full(rfs->old_fs, new_inode,
						inode, inode_size);
		if (retval)
			goto errout;
		pb.changed = 0;

#ifdef RESIZE2FS_DEBUG
		if (rfs->flags & RESIZE_DEBUG_INODEMAP)
			printf("Inode moved %u->%u\n", ino, new_inode);
#endif
		if (!rfs->imap) {
			retval = ext2fs_create_extent_table(&rfs->imap, 0);
			if (retval)
				goto errout;
		}
		ext2fs_add_extent_entry(rfs->imap, ino, new_inode);

remap_blocks:
		if (pb.changed)
			retval = ext2fs_write_inode_full(rfs->old_fs,
							 new_inode,
							 inode, inode_size);
		if (retval)
			goto errout;

		/*
		 * Update inodes to point to new blocks; schedule directory
		 * blocks for inode remapping.  Need to write out dir blocks
		 * with new inode numbers if we have metadata_csum enabled.
		 */
		rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
		if (ext2fs_inode_has_valid_blocks2(rfs->old_fs, inode) &&
		    (rfs->bmap || pb.is_dir)) {
			pb.ino = new_inode;
			pb.old_ino = ino;
			pb.has_extents = inode->i_flags & EXT4_EXTENTS_FL;
			retval = ext2fs_block_iterate3(rfs->old_fs,
						       new_inode, 0, block_buf,
						       process_block, &pb);
			if (retval)
				goto errout;
			if (pb.error) {
				retval = pb.error;
				goto errout;
			}
		} else if ((inode->i_flags & EXT4_INLINE_DATA_FL) &&
			   (rfs->bmap || pb.is_dir)) {
			/* inline data dir; update it too */
			retval = ext2fs_add_dir_block2(rfs->old_fs->dblist,
						       new_inode, 0, 0);
			if (retval)
				goto errout;
		}

		/* Fix up extent block checksums with the new inode number */
		if (ext2fs_has_feature_metadata_csum(rfs->old_fs->super) &&
		    (inode->i_flags & EXT4_EXTENTS_FL)) {
			retval = ext2fs_fix_extents_checksums(rfs->old_fs,
							      new_inode, NULL);
			if (retval)
				goto errout;
		}
	}

	if (update_ea_inode_refs &&
	    ext2fs_has_feature_ea_inode(rfs->new_fs->super)) {
		retval = fix_ea_inode_refs(rfs, inode, block_buf,
					   start_to_move);
		if (retval)
			goto errout;
	}
	io_channel_flush(rfs->old_fs->io);

errout:
	reset_com_err_hook();
	rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
	if (rfs->bmap) {
		ext2fs_free_extent_table(rfs->bmap);
		rfs->bmap = 0;
	}
	if (scan)
		ext2fs_close_inode_scan(scan);
	if (block_buf)
		ext2fs_free_mem(&block_buf);
	free(inode);
	return retval;
}

/* --------------------------------------------------------------------
 *
 * Resize processing, phase 4.
 *
 * --------------------------------------------------------------------
 */

struct istruct {
	ext2_resize_t rfs;
	errcode_t	err;
	unsigned int	max_dirs;
	unsigned int	num;
};

static int check_and_change_inodes(ext2_ino_t dir,
				   int entry EXT2FS_ATTR((unused)),
				   struct ext2_dir_entry *dirent, int offset,
				   int	blocksize EXT2FS_ATTR((unused)),
				   char *buf EXT2FS_ATTR((unused)),
				   void *priv_data)
{
	struct istruct *is = (struct istruct *) priv_data;
	struct ext2_inode 	inode;
	ext2_ino_t		new_inode;
	errcode_t		retval;
	int			ret = 0;

	if (is->rfs->progress && offset == 0) {
		io_channel_flush(is->rfs->old_fs->io);
		is->err = (is->rfs->progress)(is->rfs,
					      E2_RSZ_INODE_REF_UPD_PASS,
					      ++is->num, is->max_dirs);
		if (is->err)
			return DIRENT_ABORT;
	}

	/*
	 * If we have checksums enabled and the inode wasn't present in the
	 * old fs, then we must rewrite all dir blocks with new checksums.
	 */
	if (ext2fs_has_feature_metadata_csum(is->rfs->old_fs->super) &&
	    !ext2fs_test_inode_bitmap2(is->rfs->old_fs->inode_map, dir))
		ret |= DIRENT_CHANGED;

	if (!dirent->inode)
		return ret;

	new_inode = ext2fs_extent_translate(is->rfs->imap, dirent->inode);

	if (!new_inode)
		return ret;
#ifdef RESIZE2FS_DEBUG
	if (is->rfs->flags & RESIZE_DEBUG_INODEMAP)
		printf("Inode translate (dir=%u, name=%.*s, %u->%u)\n",
		       dir, ext2fs_dirent_name_len(dirent), dirent->name,
		       dirent->inode, new_inode);
#endif

	dirent->inode = new_inode;

	/* Update the directory mtime and ctime */
	retval = ext2fs_read_inode(is->rfs->old_fs, dir, &inode);
	if (retval == 0) {
		inode.i_mtime = inode.i_ctime = time(0);
		is->err = ext2fs_write_inode(is->rfs->old_fs, dir, &inode);
		if (is->err)
			return ret | DIRENT_ABORT;
	}

	return ret | DIRENT_CHANGED;
}

static errcode_t inode_ref_fix(ext2_resize_t rfs)
{
	errcode_t		retval;
	struct istruct 		is;

	if (!rfs->imap)
		return 0;

	/*
	 * Now, we iterate over all of the directories to update the
	 * inode references
	 */
	is.num = 0;
	is.max_dirs = ext2fs_dblist_count2(rfs->old_fs->dblist);
	is.rfs = rfs;
	is.err = 0;

	if (rfs->progress) {
		retval = (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
					 0, is.max_dirs);
		if (retval)
			goto errout;
	}

	rfs->old_fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
	retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist,
					   DIRENT_FLAG_INCLUDE_EMPTY, 0,
					   check_and_change_inodes, &is);
	rfs->old_fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
	if (retval)
		goto errout;
	if (is.err) {
		retval = is.err;
		goto errout;
	}

	if (rfs->progress && (is.num < is.max_dirs))
		(rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
				is.max_dirs, is.max_dirs);

errout:
	ext2fs_free_extent_table(rfs->imap);
	rfs->imap = 0;
	return retval;
}


/* --------------------------------------------------------------------
 *
 * Resize processing, phase 5.
 *
 * In this phase we actually move the inode table around, and then
 * update the summary statistics.  This is scary, since aborting here
 * will potentially scramble the filesystem.  (We are moving the
 * inode tables around in place, and so the potential for lost data,
 * or at the very least scrambling the mapping between filenames and
 * inode numbers is very high in case of a power failure here.)
 * --------------------------------------------------------------------
 */


/*
 * A very scary routine --- this one moves the inode table around!!!
 *
 * After this you have to use the rfs->new_fs file handle to read and
 * write inodes.
 */
static errcode_t move_itables(ext2_resize_t rfs)
{
	int		n, num, size;
	long long	diff;
	dgrp_t		i, max_groups;
	ext2_filsys	fs = rfs->new_fs;
	char		*cp;
	blk64_t		old_blk, new_blk, blk, cluster_freed;
	errcode_t	retval;
	int		to_move, moved;
	unsigned int	j;
	ext2fs_block_bitmap	new_bmap = NULL;

	max_groups = fs->group_desc_count;
	if (max_groups > rfs->old_fs->group_desc_count)
		max_groups = rfs->old_fs->group_desc_count;

	size = fs->blocksize * fs->inode_blocks_per_group;
	if (!rfs->itable_buf) {
		retval = ext2fs_get_mem(size, &rfs->itable_buf);
		if (retval)
			return retval;
	}

	if (EXT2FS_CLUSTER_RATIO(fs) > 1) {
		retval = ext2fs_allocate_block_bitmap(fs, _("new meta blocks"),
						      &new_bmap);
		if (retval)
			return retval;

		retval = mark_table_blocks(fs, new_bmap);
		if (retval)
			goto errout;
	}

	/*
	 * Figure out how many inode tables we need to move
	 */
	to_move = moved = 0;
	for (i=0; i < max_groups; i++)
		if (ext2fs_inode_table_loc(rfs->old_fs, i) !=
		    ext2fs_inode_table_loc(fs, i))
			to_move++;

	if (to_move == 0) {
		retval = 0;
		goto errout;
	}

	if (rfs->progress) {
		retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
				       0, to_move);
		if (retval)
			goto errout;
	}

	rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;

	for (i=0; i < max_groups; i++) {
		old_blk = ext2fs_inode_table_loc(rfs->old_fs, i);
		new_blk = ext2fs_inode_table_loc(fs, i);
		diff = new_blk - old_blk;

#ifdef RESIZE2FS_DEBUG
		if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
			printf("Itable move group %d block %llu->%llu (diff %lld)\n",
			       i, old_blk, new_blk, diff);
#endif

		if (!diff)
			continue;
		if (diff < 0)
			diff = 0;

		retval = io_channel_read_blk64(fs->io, old_blk,
					       fs->inode_blocks_per_group,
					       rfs->itable_buf);
		if (retval)
			goto errout;
		/*
		 * The end of the inode table segment often contains
		 * all zeros, and we're often only moving the inode
		 * table down a block or two.  If so, we can optimize
		 * things by not rewriting blocks that we know to be zero
		 * already.
		 */
		for (cp = rfs->itable_buf+size-1, n=0; n < size; n++, cp--)
			if (*cp)
				break;
		n = n >> EXT2_BLOCK_SIZE_BITS(fs->super);
#ifdef RESIZE2FS_DEBUG
		if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
			printf("%d blocks of zeros...\n", n);
#endif
		num = fs->inode_blocks_per_group;
		if (n > diff)
			num -= n;

		retval = io_channel_write_blk64(fs->io, new_blk,
						num, rfs->itable_buf);
		if (retval) {
			io_channel_write_blk64(fs->io, old_blk,
					       num, rfs->itable_buf);
			goto errout;
		}
		if (n > diff) {
			retval = io_channel_write_blk64(fs->io,
			      old_blk + fs->inode_blocks_per_group,
			      diff, (rfs->itable_buf +
				     (fs->inode_blocks_per_group - diff) *
				     fs->blocksize));
			if (retval)
				goto errout;
		}

		for (blk = ext2fs_inode_table_loc(rfs->old_fs, i), j=0;
		     j < fs->inode_blocks_per_group;) {
			if (new_bmap == NULL ||
			    !ext2fs_test_block_bitmap2(new_bmap, blk)) {
				ext2fs_block_alloc_stats2(fs, blk, -1);
				cluster_freed = EXT2FS_CLUSTER_RATIO(fs) -
						(blk & EXT2FS_CLUSTER_MASK(fs));
				blk += cluster_freed;
				j += cluster_freed;
				continue;
			}
			blk++;
			j++;
		}

		ext2fs_inode_table_loc_set(rfs->old_fs, i, new_blk);
		ext2fs_group_desc_csum_set(rfs->old_fs, i);
		ext2fs_mark_super_dirty(rfs->old_fs);
		ext2fs_flush(rfs->old_fs);

		if (rfs->progress) {
			retval = rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
					       ++moved, to_move);
			if (retval)
				goto errout;
		}
	}
	mark_table_blocks(fs, fs->block_map);
	ext2fs_flush(fs);
#ifdef RESIZE2FS_DEBUG
	if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
		printf("Inode table move finished.\n");
#endif
	retval = 0;

errout:
	if (new_bmap)
		ext2fs_free_block_bitmap(new_bmap);
	return retval;
}

/*
 * This function is used when expanding a file system.  It frees the
 * superblock and block group descriptor blocks from the block group
 * which is no longer the last block group.
 */
static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs)
{
	ext2_filsys	fs = rfs->new_fs;
	ext2_filsys	old_fs = rfs->old_fs;
	errcode_t	retval;
	dgrp_t		old_last_bg = rfs->old_fs->group_desc_count - 1;
	dgrp_t		last_bg = fs->group_desc_count - 1;
	blk64_t		sb, old_desc;
	blk_t		num;

	if (!ext2fs_has_feature_sparse_super2(fs->super))
		return 0;

	if (last_bg <= old_last_bg)
		return 0;

	if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] &&
	    fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1])
		return 0;

	if (old_fs->super->s_backup_bgs[0] != old_last_bg &&
	    old_fs->super->s_backup_bgs[1] != old_last_bg)
		return 0;

	if (fs->super->s_backup_bgs[0] == old_last_bg ||
	    fs->super->s_backup_bgs[1] == old_last_bg)
		return 0;

	if (old_last_bg == 0)
		return 0;

	retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, old_last_bg,
					   &sb, &old_desc, NULL, &num);
	if (retval)
		return retval;

	if (sb)
		ext2fs_unmark_block_bitmap2(fs->block_map, sb);
	if (old_desc)
		ext2fs_unmark_block_bitmap_range2(fs->block_map, old_desc, num);
	return 0;
}

/*
 * This function is used when shrinking a file system.  We need to
 * utilize blocks from what will be the new last block group for the
 * backup superblock and block group descriptor blocks.
 * Unfortunately, those blocks may be used by other files or fs
 * metadata blocks.  We need to mark them as being in use.
 */
static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
						 ext2fs_block_bitmap meta_bmap)
{
	ext2_filsys	fs = rfs->new_fs;
	ext2_filsys	old_fs = rfs->old_fs;
	errcode_t	retval;
	dgrp_t		old_last_bg = rfs->old_fs->group_desc_count - 1;
	dgrp_t		last_bg = fs->group_desc_count - 1;
	dgrp_t		g;
	blk64_t		blk, sb, old_desc;
	blk_t		i, num;
	int		realloc = 0;

	if (!ext2fs_has_feature_sparse_super2(fs->super))
		return 0;

	if (last_bg >= old_last_bg)
		return 0;

	if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] &&
	    fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1])
		return 0;

	if (fs->super->s_backup_bgs[0] != last_bg &&
	    fs->super->s_backup_bgs[1] != last_bg)
		return 0;

	if (old_fs->super->s_backup_bgs[0] == last_bg ||
	    old_fs->super->s_backup_bgs[1] == last_bg)
		return 0;

	retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, last_bg,
					   &sb, &old_desc, NULL, &num);
	if (retval)
		return retval;

	if (last_bg && !sb) {
		fputs(_("Should never happen!  No sb in last super_sparse bg?\n"),
		      stderr);
		exit(1);
	}
	if (old_desc && old_desc != sb+1) {
		fputs(_("Should never happen!  Unexpected old_desc in "
			"super_sparse bg?\n"),
		      stderr);
		exit(1);
	}
	num = (old_desc) ? num : 1;

	/* Reserve the backup blocks */
	ext2fs_mark_block_bitmap_range2(fs->block_map, sb, num);

	for (g = 0; g < fs->group_desc_count; g++) {
		blk64_t mb;

		mb = ext2fs_block_bitmap_loc(fs, g);
		if ((mb >= sb) && (mb < sb + num)) {
			ext2fs_block_bitmap_loc_set(fs, g, 0);
			realloc = 1;
		}
		mb = ext2fs_inode_bitmap_loc(fs, g);
		if ((mb >= sb) && (mb < sb + num)) {
			ext2fs_inode_bitmap_loc_set(fs, g, 0);
			realloc = 1;
		}
		mb = ext2fs_inode_table_loc(fs, g);
		if ((mb < sb + num) &&
		    (sb < mb + fs->inode_blocks_per_group)) {
			ext2fs_inode_table_loc_set(fs, g, 0);
			realloc = 1;
		}
		if (realloc) {
			retval = ext2fs_allocate_group_table(fs, g, 0);
			if (retval)
				return retval;
		}
	}

	for (blk = sb, i = 0; i < num; blk++, i++) {
		if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
		    !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
			ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
			rfs->needed_blocks++;
		}
		ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
	}
	return 0;
}

/*
 * Fix the resize inode
 */
static errcode_t fix_resize_inode(ext2_filsys fs)
{
	struct ext2_inode	inode;
	errcode_t		retval;

	if (!ext2fs_has_feature_resize_inode(fs->super))
		return 0;

	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
	if (retval) goto errout;

	ext2fs_iblk_set(fs, &inode, 1);

	retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
	if (retval) goto errout;

	if (!inode.i_block[EXT2_DIND_BLOCK]) {
		/*
		 * Avoid zeroing out block #0; that's rude.  This
		 * should never happen anyway since the filesystem
		 * should be fsck'ed and we assume it is consistent.
		 */
		fprintf(stderr, "%s",
			_("Should never happen: resize inode corrupt!\n"));
		exit(1);
	}

	retval = ext2fs_zero_blocks2(fs, inode.i_block[EXT2_DIND_BLOCK], 1,
				     NULL, NULL);
	if (retval)
		goto errout;

	retval = ext2fs_create_resize_inode(fs);
	if (retval)
		goto errout;

errout:
	return retval;
}

/*
 * Finally, recalculate the summary information
 */
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;
	blk64_t		total_blocks_free = 0;
	int		total_inodes_free = 0;
	int		group_free = 0;
	int		uninit = 0;
	blk64_t		super_blk, old_desc_blk, new_desc_blk;
	int		old_desc_blocks;

	/*
	 * First calculate the block statistics
	 */
	uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT);
	ext2fs_super_and_bgd_loc2(fs, group, &super_blk, &old_desc_blk,
				  &new_desc_blk, 0);
	if (ext2fs_has_feature_meta_bg(fs->super))
		old_desc_blocks = fs->super->s_first_meta_bg;
	else
		old_desc_blocks = fs->desc_blocks +
			fs->super->s_reserved_gdt_blocks;
	for (blk = B2C(fs->super->s_first_data_block);
	     blk < ext2fs_blocks_count(fs->super);
	     blk += EXT2FS_CLUSTER_RATIO(fs)) {
		if ((uninit &&
		     !(EQ_CLSTR(blk, super_blk) ||
		       ((old_desc_blk && old_desc_blocks &&
			 GE_CLSTR(blk, old_desc_blk) &&
			 LT_CLSTR(blk, old_desc_blk + old_desc_blocks))) ||
		       ((new_desc_blk && EQ_CLSTR(blk, new_desc_blk))) ||
		       EQ_CLSTR(blk, ext2fs_block_bitmap_loc(fs, group)) ||
		       EQ_CLSTR(blk, ext2fs_inode_bitmap_loc(fs, group)) ||
		       ((GE_CLSTR(blk, ext2fs_inode_table_loc(fs, group)) &&
			 LT_CLSTR(blk, ext2fs_inode_table_loc(fs, group)
				  + fs->inode_blocks_per_group))))) ||
		    (!ext2fs_fast_test_block_bitmap2(fs->block_map, blk))) {
			group_free++;
			total_blocks_free++;
		}
		count++;
		if ((count == fs->super->s_clusters_per_group) ||
		    EQ_CLSTR(blk, ext2fs_blocks_count(fs->super)-1)) {
			ext2fs_bg_free_blocks_count_set(fs, group, group_free);
			ext2fs_group_desc_csum_set(fs, group);
			group++;
			if (group >= fs->group_desc_count)
				break;
			count = 0;
			group_free = 0;
			uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT);
			ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
						  &old_desc_blk,
						  &new_desc_blk, 0);
			if (ext2fs_has_feature_meta_bg(fs->super))
				old_desc_blocks = fs->super->s_first_meta_bg;
			else
				old_desc_blocks = fs->desc_blocks +
					fs->super->s_reserved_gdt_blocks;
		}
	}
	total_blocks_free = C2B(total_blocks_free);
	ext2fs_free_blocks_count_set(fs->super, total_blocks_free);

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

	/* Protect loop from wrap-around if s_inodes_count maxed */
	uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT);
	for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) {
		if (uninit ||
		    !ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) {
			group_free++;
			total_inodes_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);
			ext2fs_group_desc_csum_set(fs, group);
			group++;
			if (group >= fs->group_desc_count)
				break;
			count = 0;
			group_free = 0;
			uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT);
		}
	}
	fs->super->s_free_inodes_count = total_inodes_free;
	ext2fs_mark_super_dirty(fs);
	return 0;
}

/*
 *  Journal may have been relocated; update the backup journal blocks
 *  in the superblock.
 */
static errcode_t fix_sb_journal_backup(ext2_filsys fs)
{
	errcode_t	  retval;
	struct ext2_inode inode;

	if (!ext2fs_has_feature_journal(fs->super))
		return 0;

	/* External journal? Nothing to do. */
	if (fs->super->s_journal_dev && !fs->super->s_journal_inum)
		return 0;

	retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode);
	if (retval)
		return retval;
	memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
	fs->super->s_jnl_blocks[15] = inode.i_size_high;
	fs->super->s_jnl_blocks[16] = inode.i_size;
	fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
	ext2fs_mark_super_dirty(fs);
	return 0;
}

static int calc_group_overhead(ext2_filsys fs, blk64_t grp,
			       int old_desc_blocks)
{
	blk64_t	super_blk, old_desc_blk, new_desc_blk;
	int overhead;

	/* inode table blocks plus allocation bitmaps */
	overhead = fs->inode_blocks_per_group + 2;

	ext2fs_super_and_bgd_loc2(fs, grp, &super_blk,
				  &old_desc_blk, &new_desc_blk, 0);
	if ((grp == 0) || super_blk)
		overhead++;
	if (old_desc_blk)
		overhead += old_desc_blocks;
	else if (new_desc_blk)
		overhead++;
	return overhead;
}


/*
 * calculate the minimum number of blocks the given fs can be resized to
 */
blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags)
{
	ext2_ino_t inode_count;
	dgrp_t groups, flex_groups;
	blk64_t blks_needed, data_blocks;
	blk64_t grp, data_needed, last_start;
	blk64_t overhead = 0;
	int old_desc_blocks;
	int flexbg_size = 1 << fs->super->s_log_groups_per_flex;

	/*
	 * first figure out how many group descriptors we need to
	 * handle the number of inodes we have
	 */
	inode_count = fs->super->s_inodes_count -
		fs->super->s_free_inodes_count;
	blks_needed = ext2fs_div_ceil(inode_count,
				      fs->super->s_inodes_per_group) *
		(blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super);
	groups = ext2fs_div64_ceil(blks_needed,
				   EXT2_BLOCKS_PER_GROUP(fs->super));
#ifdef RESIZE2FS_DEBUG
	if (flags & RESIZE_DEBUG_MIN_CALC)
		printf("fs has %d inodes, %d groups required.\n",
		       inode_count, groups);
#endif

	/*
	 * number of old-style block group descriptor blocks
	 */
	if (ext2fs_has_feature_meta_bg(fs->super))
		old_desc_blocks = fs->super->s_first_meta_bg;
	else
		old_desc_blocks = fs->desc_blocks +
			fs->super->s_reserved_gdt_blocks;

	/* calculate how many blocks are needed for data */
	data_needed = ext2fs_blocks_count(fs->super) -
		ext2fs_free_blocks_count(fs->super);

	for (grp = 0; grp < fs->group_desc_count; grp++)
		data_needed -= calc_group_overhead(fs, grp, old_desc_blocks);
#ifdef RESIZE2FS_DEBUG
	if (flags & RESIZE_DEBUG_MIN_CALC)
		printf("fs requires %llu data blocks.\n", data_needed);
#endif

	/*
	 * For ext4 we need to allow for up to a flex_bg worth of
	 * inode tables of slack space so the resize operation can be
	 * guaranteed to finish.
	 */
	flex_groups = groups;
	if (ext2fs_has_feature_flex_bg(fs->super)) {
		dgrp_t remainder = groups & (flexbg_size - 1);

		flex_groups += flexbg_size - remainder;
		if (flex_groups > fs->group_desc_count)
			flex_groups = fs->group_desc_count;
	}

	/*
	 * figure out how many data blocks we have given the number of groups
	 * we need for our inodes
	 */
	data_blocks = EXT2_GROUPS_TO_BLOCKS(fs->super, groups);
	last_start = 0;
	for (grp = 0; grp < flex_groups; grp++) {
		overhead = calc_group_overhead(fs, grp, old_desc_blocks);

		/*
		 * we want to keep track of how much data we can store in
		 * the groups leading up to the last group so we can determine
		 * how big the last group needs to be
		 */
		if (grp < (groups - 1))
			last_start += EXT2_BLOCKS_PER_GROUP(fs->super) -
				overhead;

		if (data_blocks > overhead)
			data_blocks -= overhead;
		else
			data_blocks = 0;
	}
#ifdef RESIZE2FS_DEBUG
	if (flags & RESIZE_DEBUG_MIN_CALC)
		printf("With %d group(s), we have %llu blocks available.\n",
		       groups, data_blocks);
#endif

	/*
	 * if we need more group descriptors in order to accommodate our data
	 * then we need to add them here
	 */
	blks_needed = data_needed;
	while (blks_needed > data_blocks) {
		blk64_t remainder = blks_needed - data_blocks;
		dgrp_t extra_grps;

		/* figure out how many more groups we need for the data */
		extra_grps = ext2fs_div64_ceil(remainder,
					       EXT2_BLOCKS_PER_GROUP(fs->super));

		data_blocks += EXT2_GROUPS_TO_BLOCKS(fs->super, extra_grps);

		/* ok we have to account for the last group */
		overhead = calc_group_overhead(fs, groups-1, old_desc_blocks);
		last_start += EXT2_BLOCKS_PER_GROUP(fs->super) - overhead;

		grp = flex_groups;
		groups += extra_grps;
		if (!ext2fs_has_feature_flex_bg(fs->super))
			flex_groups = groups;
		else if (groups > flex_groups) {
			dgrp_t r = groups & (flexbg_size - 1);

			flex_groups = groups + flexbg_size - r;
			if (flex_groups > fs->group_desc_count)
				flex_groups = fs->group_desc_count;
		}

		for (; grp < flex_groups; grp++) {
			overhead = calc_group_overhead(fs, grp,
						       old_desc_blocks);

			/*
			 * again, we need to see how much data we cram into
			 * all of the groups leading up to the last group
			 */
			if (grp < groups - 1)
				last_start += EXT2_BLOCKS_PER_GROUP(fs->super)
					- overhead;

			data_blocks -= overhead;
		}

#ifdef RESIZE2FS_DEBUG
		if (flags & RESIZE_DEBUG_MIN_CALC)
			printf("Added %d extra group(s), "
			       "blks_needed %llu, data_blocks %llu, "
			       "last_start %llu\n", extra_grps, blks_needed,
			       data_blocks, last_start);
#endif
	}

	/* now for the fun voodoo */
	grp = groups - 1;
	if (ext2fs_has_feature_flex_bg(fs->super) &&
	    (grp & ~(flexbg_size - 1)) == 0)
		grp = grp & ~(flexbg_size - 1);
	overhead = 0;
	for (; grp < flex_groups; grp++)
		overhead += calc_group_overhead(fs, grp, old_desc_blocks);

#ifdef RESIZE2FS_DEBUG
	if (flags & RESIZE_DEBUG_MIN_CALC)
		printf("Last group's overhead is %llu\n", overhead);
#endif

	/*
	 * if this is the case then the last group is going to have data in it
	 * so we need to adjust the size of the last group accordingly
	 */
	if (last_start < blks_needed) {
		blk64_t remainder = blks_needed - last_start;

#ifdef RESIZE2FS_DEBUG
		if (flags & RESIZE_DEBUG_MIN_CALC)
			printf("Need %llu data blocks in last group\n",
			       remainder);
#endif
		/*
		 * 50 is a magic number that mkfs/resize uses to see if its
		 * even worth making/resizing the fs.  basically you need to
		 * have at least 50 blocks in addition to the blocks needed
		 * for the metadata in the last group
		 */
		if (remainder > 50)
			overhead += remainder;
		else
			overhead += 50;
	} else
		overhead += 50;

	overhead += fs->super->s_first_data_block;
#ifdef RESIZE2FS_DEBUG
	if (flags & RESIZE_DEBUG_MIN_CALC)
		printf("Final size of last group is %lld\n", overhead);
#endif

	/* Add extra slack for bigalloc file systems */
	if (EXT2FS_CLUSTER_RATIO(fs) > 1)
		overhead += EXT2FS_CLUSTER_RATIO(fs) * 2;

	/*
	 * since our last group doesn't have to be BLOCKS_PER_GROUP
	 * large, we only do groups-1, and then add the number of
	 * blocks needed to handle the group descriptor metadata+data
	 * that we need
	 */
	blks_needed = EXT2_GROUPS_TO_BLOCKS(fs->super, groups - 1);
	blks_needed += overhead;

	/*
	 * Make sure blks_needed covers the end of the inode table in
	 * the last block group.
	 */
	overhead = ext2fs_inode_table_loc(fs, groups-1) +
		fs->inode_blocks_per_group;
	if (blks_needed < overhead)
		blks_needed = overhead;

#ifdef RESIZE2FS_DEBUG
	if (flags & RESIZE_DEBUG_MIN_CALC)
		printf("Estimated blocks needed: %llu\n", blks_needed);
#endif

	/*
	 * If at this point we've already added up more "needed" than
	 * the current size, just return current size as minimum.
	 */
	if (blks_needed >= ext2fs_blocks_count(fs->super))
		return ext2fs_blocks_count(fs->super);
	/*
	 * We need to reserve a few extra blocks if extents are
	 * enabled, in case we need to grow the extent tree.  The more
	 * we shrink the file system, the more space we need.
	 *
	 * The absolute worst case is every single data block is in
	 * the part of the file system that needs to be evacuated,
	 * with each data block needs to be in its own extent, and
	 * with each inode needing at least one extent block.
	 */
	if (ext2fs_has_feature_extents(fs->super)) {
		blk64_t safe_margin = (ext2fs_blocks_count(fs->super) -
				       blks_needed)/500;
		unsigned int exts_per_blk = (fs->blocksize /
					     sizeof(struct ext3_extent)) - 1;
		blk64_t worst_case = ((data_needed + exts_per_blk - 1) /
				      exts_per_blk);

		if (worst_case < inode_count)
			worst_case = inode_count;

		if (safe_margin > worst_case)
			safe_margin = worst_case;

#ifdef RESIZE2FS_DEBUG
		if (flags & RESIZE_DEBUG_MIN_CALC)
			printf("Extents safety margin: %llu\n", safe_margin);
#endif
		blks_needed += safe_margin;
	}

	return blks_needed;
}
