/*
 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
 *
 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 *
 */

#include "config.h"
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>

#include "e2fsck.h"
#include "problem.h"

static void check_block_bitmaps(e2fsck_t ctx);
static void check_inode_bitmaps(e2fsck_t ctx);
static void check_inode_end(e2fsck_t ctx);
static void check_block_end(e2fsck_t ctx);
static void check_inode_bitmap_checksum(e2fsck_t ctx);
static void check_block_bitmap_checksum(e2fsck_t ctx);

void e2fsck_pass5(e2fsck_t ctx)
{
#ifdef RESOURCE_TRACK
	struct resource_track	rtrack;
#endif
	struct problem_context	pctx;

#ifdef MTRACE
	mtrace_print("Pass 5");
#endif

	init_resource_track(&rtrack, ctx->fs->io);
	clear_problem_context(&pctx);

	if (!(ctx->options & E2F_OPT_PREEN))
		fix_problem(ctx, PR_5_PASS_HEADER, &pctx);

	if (ctx->progress)
		if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
			return;

	e2fsck_read_bitmaps(ctx);

	check_block_bitmaps(ctx);
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		return;
	check_inode_bitmaps(ctx);
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		return;
	check_inode_end(ctx);
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		return;
	check_block_end(ctx);
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		return;

	check_inode_bitmap_checksum(ctx);
	check_block_bitmap_checksum(ctx);

	ext2fs_free_inode_bitmap(ctx->inode_used_map);
	ctx->inode_used_map = 0;
	ext2fs_free_inode_bitmap(ctx->inode_dir_map);
	ctx->inode_dir_map = 0;
	ext2fs_free_block_bitmap(ctx->block_found_map);
	ctx->block_found_map = 0;
	ext2fs_free_block_bitmap(ctx->block_metadata_map);
	ctx->block_metadata_map = 0;

	print_resource_track(ctx, _("Pass 5"), &rtrack, ctx->fs->io);
}

static void check_inode_bitmap_checksum(e2fsck_t ctx)
{
	struct problem_context	pctx;
	char		*buf = NULL;
	dgrp_t		i;
	int		nbytes;
	ext2_ino_t	ino_itr;
	errcode_t	retval;

	if (!ext2fs_has_feature_metadata_csum(ctx->fs->super))
		return;

	/* If bitmap is dirty from being fixed, checksum will be corrected */
	if (ext2fs_test_ib_dirty(ctx->fs))
		return;

	nbytes = (size_t)(EXT2_INODES_PER_GROUP(ctx->fs->super) / 8);
	retval = ext2fs_get_mem(ctx->fs->blocksize, &buf);
	if (retval) {
		com_err(ctx->program_name, 0, "%s",
		    _("check_inode_bitmap_checksum: Memory allocation error"));
		fatal_error(ctx, 0);
	}

	clear_problem_context(&pctx);
	for (i = 0; i < ctx->fs->group_desc_count; i++) {
		if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_INODE_UNINIT))
			continue;

		ino_itr = 1 + (i * (nbytes << 3));
		retval = ext2fs_get_inode_bitmap_range2(ctx->fs->inode_map,
							ino_itr, nbytes << 3,
							buf);
		if (retval)
			break;

		if (ext2fs_inode_bitmap_csum_verify(ctx->fs, i, buf, nbytes))
			continue;
		pctx.group = i;
		if (!fix_problem(ctx, PR_5_INODE_BITMAP_CSUM_INVALID, &pctx))
			continue;

		/*
		 * Fixing one checksum will rewrite all of them.  The bitmap
		 * will be checked against the one we made during pass1 for
		 * discrepancies, and fixed if need be.
		 */
		ext2fs_mark_ib_dirty(ctx->fs);
		break;
	}

	ext2fs_free_mem(&buf);
}

static void check_block_bitmap_checksum(e2fsck_t ctx)
{
	struct problem_context	pctx;
	char		*buf = NULL;
	dgrp_t		i;
	int		nbytes;
	blk64_t		blk_itr;
	errcode_t	retval;

	if (!ext2fs_has_feature_metadata_csum(ctx->fs->super))
		return;

	/* If bitmap is dirty from being fixed, checksum will be corrected */
	if (ext2fs_test_bb_dirty(ctx->fs))
		return;

	nbytes = (size_t)(EXT2_CLUSTERS_PER_GROUP(ctx->fs->super) / 8);
	retval = ext2fs_get_mem(ctx->fs->blocksize, &buf);
	if (retval) {
		com_err(ctx->program_name, 0, "%s",
		    _("check_block_bitmap_checksum: Memory allocation error"));
		fatal_error(ctx, 0);
	}

	clear_problem_context(&pctx);
	for (i = 0; i < ctx->fs->group_desc_count; i++) {
		if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_BLOCK_UNINIT))
			continue;

		blk_itr = EXT2FS_B2C(ctx->fs,
				     ctx->fs->super->s_first_data_block) +
			  ((blk64_t) i * (nbytes << 3));
		retval = ext2fs_get_block_bitmap_range2(ctx->fs->block_map,
							blk_itr, nbytes << 3,
							buf);
		if (retval)
			break;

		if (ext2fs_block_bitmap_csum_verify(ctx->fs, i, buf, nbytes))
			continue;
		pctx.group = i;
		if (!fix_problem(ctx, PR_5_BLOCK_BITMAP_CSUM_INVALID, &pctx))
			continue;

		/*
		 * Fixing one checksum will rewrite all of them.  The bitmap
		 * will be checked against the one we made during pass1 for
		 * discrepancies, and fixed if need be.
		 */
		ext2fs_mark_bb_dirty(ctx->fs);
		break;
	}

	ext2fs_free_mem(&buf);
}

static void e2fsck_discard_blocks(e2fsck_t ctx, blk64_t start,
				  blk64_t count)
{
	ext2_filsys fs = ctx->fs;

	/*
	 * If the filesystem has changed it means that there was an corruption
	 * which should be repaired, but in some cases just one e2fsck run is
	 * not enough to fix the problem, hence it is not safe to run discard
	 * in this case.
	 */
	if (ext2fs_test_changed(fs))
		ctx->options &= ~E2F_OPT_DISCARD;

	if ((ctx->options & E2F_OPT_DISCARD) &&
	    (io_channel_discard(fs->io, start, count)))
		ctx->options &= ~E2F_OPT_DISCARD;
}

/*
 * This will try to discard number 'count' inodes starting at
 * inode number 'start' within the 'group'. Note that 'start'
 * is 1-based, it means that we need to adjust it by -1 in this
 * function to compute right offset in the particular inode table.
 */
static void e2fsck_discard_inodes(e2fsck_t ctx, dgrp_t group,
				  ext2_ino_t start, int count)
{
	ext2_filsys fs = ctx->fs;
	blk64_t blk, num;

	/*
	 * Sanity check for 'start'
	 */
	if ((start < 1) || (start > EXT2_INODES_PER_GROUP(fs->super))) {
		printf("PROGRAMMING ERROR: Got start %d outside of group %d!"
		       " Disabling discard\n",
			start, group);
		ctx->options &= ~E2F_OPT_DISCARD;
	}

	/*
	 * Do not attempt to discard if E2F_OPT_DISCARD is not set. And also
	 * skip the discard on this group if discard does not zero data.
	 * The reason is that if the inode table is not zeroed discard would
	 * no help us since we need to zero it anyway, or if the inode table
	 * is zeroed then the read after discard would not be deterministic
	 * anyway and we would not be able to assume that this inode table
	 * was zeroed anymore so we would have to zero it again, which does
	 * not really make sense.
	 */
	if (!(ctx->options & E2F_OPT_DISCARD) ||
	    !io_channel_discard_zeroes_data(fs->io))
		return;

	/*
	 * Start is inode number within the group which starts
	 * counting from 1, so we need to adjust it.
	 */
	start -= 1;

	/*
	 * We can discard only blocks containing only unused
	 * inodes in the table.
	 */
	blk = DIV_ROUND_UP(start,
		EXT2_INODES_PER_BLOCK(fs->super));
	count -= (blk * EXT2_INODES_PER_BLOCK(fs->super) - start);
	blk += ext2fs_inode_table_loc(fs, group);
	num = count / EXT2_INODES_PER_BLOCK(fs->super);

	if (num > 0)
		e2fsck_discard_blocks(ctx, blk, num);
}

#define NO_BLK ((blk64_t) -1)

static void print_bitmap_problem(e2fsck_t ctx, problem_t problem,
			    struct problem_context *pctx)
{
	switch (problem) {
	case PR_5_BLOCK_UNUSED:
		if (pctx->blk == pctx->blk2)
			pctx->blk2 = 0;
		else
			problem = PR_5_BLOCK_RANGE_UNUSED;
		break;
	case PR_5_BLOCK_USED:
		if (pctx->blk == pctx->blk2)
			pctx->blk2 = 0;
		else
			problem = PR_5_BLOCK_RANGE_USED;
		break;
	case PR_5_INODE_UNUSED:
		if (pctx->ino == pctx->ino2)
			pctx->ino2 = 0;
		else
			problem = PR_5_INODE_RANGE_UNUSED;
		break;
	case PR_5_INODE_USED:
		if (pctx->ino == pctx->ino2)
			pctx->ino2 = 0;
		else
			problem = PR_5_INODE_RANGE_USED;
		break;
	}
	fix_problem(ctx, problem, pctx);
	pctx->blk = pctx->blk2 = NO_BLK;
	pctx->ino = pctx->ino2 = 0;
}

/* Just to be more succinct */
#define B2C(x)	EXT2FS_B2C(fs, (x))
#define EQ_CLSTR(x, y) (B2C(x) == B2C(y))
#define LE_CLSTR(x, y) (B2C(x) <= B2C(y))
#define GE_CLSTR(x, y) (B2C(x) >= B2C(y))

static void check_block_bitmaps(e2fsck_t ctx)
{
	ext2_filsys fs = ctx->fs;
	blk64_t	i;
	unsigned int	*free_array;
	dgrp_t		g, group = 0;
	unsigned int	blocks = 0;
	blk64_t	free_blocks = 0;
	blk64_t first_free = ext2fs_blocks_count(fs->super);
	unsigned int	group_free = 0;
	int	actual, bitmap;
	struct problem_context	pctx;
	problem_t	problem, save_problem;
	int		fixit, had_problem;
	errcode_t	retval;
	int	redo_flag = 0;
	char *actual_buf, *bitmap_buf;

	actual_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
						     "actual bitmap buffer");
	bitmap_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize,
						     "bitmap block buffer");

	clear_problem_context(&pctx);
	free_array = (unsigned int *) e2fsck_allocate_memory(ctx,
	    fs->group_desc_count * sizeof(unsigned int), "free block count array");

	if ((B2C(fs->super->s_first_data_block) <
	     ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
	    (B2C(ext2fs_blocks_count(fs->super)-1) >
	     ext2fs_get_block_bitmap_end2(ctx->block_found_map))) {
		pctx.num = 1;
		pctx.blk = B2C(fs->super->s_first_data_block);
		pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
		pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map);
		pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map);
		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);

		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		goto errout;
	}

	if ((B2C(fs->super->s_first_data_block) <
	     ext2fs_get_block_bitmap_start2(fs->block_map)) ||
	    (B2C(ext2fs_blocks_count(fs->super)-1) >
	     ext2fs_get_block_bitmap_end2(fs->block_map))) {
		pctx.num = 2;
		pctx.blk = B2C(fs->super->s_first_data_block);
		pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
		pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map);
		pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map);
		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);

		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		goto errout;
	}

redo_counts:
	had_problem = 0;
	save_problem = 0;
	pctx.blk = pctx.blk2 = NO_BLK;
	for (i = B2C(fs->super->s_first_data_block);
	     i < ext2fs_blocks_count(fs->super);
	     i += EXT2FS_CLUSTER_RATIO(fs)) {
		int first_block_in_bg = (B2C(i) -
					 B2C(fs->super->s_first_data_block)) %
			fs->super->s_clusters_per_group == 0;
		int n, nbytes = fs->super->s_clusters_per_group / 8;

		actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);

		/*
		 * Try to optimize pass5 by extracting a bitmap block
		 * as expected from what we have on disk, and then
		 * comparing the two.  If they are identical, then
		 * update the free block counts and go on to the next
		 * block group.  This is much faster than doing the
		 * individual bit-by-bit comparison.  The one downside
		 * is that this doesn't work if we are asking e2fsck
		 * to do a discard operation.
		 */
		if (!first_block_in_bg ||
		    (group == fs->group_desc_count - 1) ||
		    (ctx->options & E2F_OPT_DISCARD))
			goto no_optimize;

		retval = ext2fs_get_block_bitmap_range2(ctx->block_found_map,
				B2C(i), fs->super->s_clusters_per_group,
				actual_buf);
		if (retval)
			goto no_optimize;
		retval = ext2fs_get_block_bitmap_range2(fs->block_map,
				B2C(i), fs->super->s_clusters_per_group,
				bitmap_buf);
		if (retval)
			goto no_optimize;
		if (memcmp(actual_buf, bitmap_buf, nbytes) != 0)
			goto no_optimize;
		n = ext2fs_bitcount(actual_buf, nbytes);
		group_free = fs->super->s_clusters_per_group - n;
		free_blocks += group_free;
		i += EXT2FS_C2B(fs, fs->super->s_clusters_per_group - 1);
		goto next_group;
	no_optimize:

		if (redo_flag)
			bitmap = actual;
		else
			bitmap = ext2fs_fast_test_block_bitmap2(fs->block_map, i);

		if (!actual == !bitmap)
			goto do_counts;

		if (!actual && bitmap) {
			/*
			 * Block not used, but marked in use in the bitmap.
			 */
			problem = PR_5_BLOCK_UNUSED;
		} else {
			/*
			 * Block used, but not marked in use in the bitmap.
			 */
			problem = PR_5_BLOCK_USED;

			if (ext2fs_bg_flags_test(fs, group,
						 EXT2_BG_BLOCK_UNINIT)) {
				struct problem_context pctx2;
				pctx2.blk = i;
				pctx2.group = group;
				if (fix_problem(ctx, PR_5_BLOCK_UNINIT,
						&pctx2))
					ext2fs_bg_flags_clear(fs, group,
							EXT2_BG_BLOCK_UNINIT);
			}
		}
		if (pctx.blk == NO_BLK) {
			pctx.blk = pctx.blk2 = i;
			save_problem = problem;
		} else {
			if ((problem == save_problem) &&
			    (pctx.blk2 == i - EXT2FS_CLUSTER_RATIO(fs)))
				pctx.blk2 += EXT2FS_CLUSTER_RATIO(fs);
			else {
				print_bitmap_problem(ctx, save_problem, &pctx);
				pctx.blk = pctx.blk2 = i;
				save_problem = problem;
			}
		}
		ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
		had_problem++;

		/*
		 * If there a problem we should turn off the discard so we
		 * do not compromise the filesystem.
		 */
		ctx->options &= ~E2F_OPT_DISCARD;

	do_counts:
		if (!bitmap) {
			group_free++;
			free_blocks++;
			if (first_free > i)
				first_free = i;
		} else if (i > first_free) {
			e2fsck_discard_blocks(ctx, first_free,
					      (i - first_free));
			first_free = ext2fs_blocks_count(fs->super);
		}
		blocks ++;
		if ((blocks == fs->super->s_clusters_per_group) ||
		    (EXT2FS_B2C(fs, i) ==
		     EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super)-1))) {
			/*
			 * If the last block of this group is free, then we can
			 * discard it as well.
			 */
			if (!bitmap && i >= first_free)
				e2fsck_discard_blocks(ctx, first_free,
						      (i - first_free) + 1);
		next_group:
			first_free = ext2fs_blocks_count(fs->super);

			free_array[group] = group_free;
			group ++;
			blocks = 0;
			group_free = 0;
			if (ctx->progress)
				if ((ctx->progress)(ctx, 5, group,
						    fs->group_desc_count*2))
					goto errout;
		}
	}
	if (pctx.blk != NO_BLK)
		print_bitmap_problem(ctx, save_problem, &pctx);
	if (had_problem)
		fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
	else
		fixit = -1;
	ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;

	if (fixit == 1) {
		ext2fs_free_block_bitmap(fs->block_map);
		retval = ext2fs_copy_bitmap(ctx->block_found_map,
						  &fs->block_map);
		if (retval) {
			clear_problem_context(&pctx);
			fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
			ctx->flags |= E2F_FLAG_ABORT;
			goto errout;
		}
		ext2fs_set_bitmap_padding(fs->block_map);
		ext2fs_mark_bb_dirty(fs);

		/* Redo the counts */
		blocks = 0; free_blocks = 0; group_free = 0; group = 0;
		memset(free_array, 0, fs->group_desc_count * sizeof(int));
		redo_flag++;
		goto redo_counts;
	} else if (fixit == 0)
		ext2fs_unmark_valid(fs);

	for (g = 0; g < fs->group_desc_count; g++) {
		if (free_array[g] != ext2fs_bg_free_blocks_count(fs, g)) {
			pctx.group = g;
			pctx.blk = ext2fs_bg_free_blocks_count(fs, g);
			pctx.blk2 = free_array[g];

			if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
					&pctx)) {
				ext2fs_bg_free_blocks_count_set(fs, g, free_array[g]);
				ext2fs_mark_super_dirty(fs);
			} else
				ext2fs_unmark_valid(fs);
		}
	}
	free_blocks = EXT2FS_C2B(fs, free_blocks);
	if (free_blocks != ext2fs_free_blocks_count(fs->super)) {
		pctx.group = 0;
		pctx.blk = ext2fs_free_blocks_count(fs->super);
		pctx.blk2 = free_blocks;

		if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
			ext2fs_free_blocks_count_set(fs->super, free_blocks);
			ext2fs_mark_super_dirty(fs);
		}
	}
errout:
	ext2fs_free_mem(&free_array);
	ext2fs_free_mem(&actual_buf);
	ext2fs_free_mem(&bitmap_buf);
}

static void check_inode_bitmaps(e2fsck_t ctx)
{
	ext2_filsys fs = ctx->fs;
	ext2_ino_t	i;
	unsigned int	free_inodes = 0;
	int		group_free = 0;
	int		dirs_count = 0;
	dgrp_t		group = 0;
	unsigned int	inodes = 0;
	ext2_ino_t	*free_array;
	ext2_ino_t	*dir_array;
	int		actual, bitmap;
	errcode_t	retval;
	struct problem_context	pctx;
	problem_t	problem, save_problem;
	int		fixit, had_problem;
	int		csum_flag;
	int		skip_group = 0;
	int		redo_flag = 0;
	ext2_ino_t		first_free = fs->super->s_inodes_per_group + 1;

	clear_problem_context(&pctx);
	free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
	    fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array");

	dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
	   fs->group_desc_count * sizeof(ext2_ino_t), "directory count array");

	if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) ||
	    (fs->super->s_inodes_count >
	     ext2fs_get_inode_bitmap_end2(ctx->inode_used_map))) {
		pctx.num = 3;
		pctx.blk = 1;
		pctx.blk2 = fs->super->s_inodes_count;
		pctx.ino = ext2fs_get_inode_bitmap_start2(ctx->inode_used_map);
		pctx.ino2 = ext2fs_get_inode_bitmap_end2(ctx->inode_used_map);
		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);

		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		goto errout;
	}
	if ((1 < ext2fs_get_inode_bitmap_start2(fs->inode_map)) ||
	    (fs->super->s_inodes_count >
	     ext2fs_get_inode_bitmap_end2(fs->inode_map))) {
		pctx.num = 4;
		pctx.blk = 1;
		pctx.blk2 = fs->super->s_inodes_count;
		pctx.ino = ext2fs_get_inode_bitmap_start2(fs->inode_map);
		pctx.ino2 = ext2fs_get_inode_bitmap_end2(fs->inode_map);
		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);

		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		goto errout;
	}

	csum_flag = ext2fs_has_group_desc_csum(fs);
redo_counts:
	had_problem = 0;
	save_problem = 0;
	pctx.ino = pctx.ino2 = 0;
	if (csum_flag &&
	    (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)))
		skip_group++;

	/* Protect loop from wrap-around if inodes_count is maxed */
	for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
		bitmap = 0;
		if (skip_group &&
		    i % fs->super->s_inodes_per_group == 1) {
			/*
			 * Current inode is the first inode
			 * in the current block group.
			 */
			if (ext2fs_test_inode_bitmap_range(
				    ctx->inode_used_map, i,
				    fs->super->s_inodes_per_group)) {
				/*
				 * When the compared inodes in inodes bitmap
				 * are 0, count the free inode,
				 * skip the current block group.
				 */
				first_free = 1;
				inodes = fs->super->s_inodes_per_group - 1;
				group_free = inodes;
				free_inodes += inodes;
				i += inodes;
				skip_group = 0;
				goto do_counts;
			}
		}

		actual = ext2fs_fast_test_inode_bitmap2(ctx->inode_used_map, i);
		if (redo_flag)
			bitmap = actual;
		else if (!skip_group)
			bitmap = ext2fs_fast_test_inode_bitmap2(fs->inode_map, i);
		if (!actual == !bitmap)
			goto do_counts;

		if (!actual && bitmap) {
			/*
			 * Inode wasn't used, but marked in bitmap
			 */
			problem = PR_5_INODE_UNUSED;
		} else /* if (actual && !bitmap) */ {
			/*
			 * Inode used, but not in bitmap
			 */
			problem = PR_5_INODE_USED;

			/* We should never hit this, because it means that
			 * inodes were marked in use that weren't noticed
			 * in pass1 or pass 2. It is easier to fix the problem
			 * than to kill e2fsck and leave the user stuck. */
			if (skip_group) {
				struct problem_context pctx2;
				pctx2.blk = i;
				pctx2.group = group;
				if (fix_problem(ctx, PR_5_INODE_UNINIT,&pctx2)){
					ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
					skip_group = 0;
				}
			}
		}
		if (pctx.ino == 0) {
			pctx.ino = pctx.ino2 = i;
			save_problem = problem;
		} else {
			if ((problem == save_problem) &&
			    (pctx.ino2 == i-1))
				pctx.ino2++;
			else {
				print_bitmap_problem(ctx, save_problem, &pctx);
				pctx.ino = pctx.ino2 = i;
				save_problem = problem;
			}
		}
		ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
		had_problem++;
		/*
		 * If there a problem we should turn off the discard so we
		 * do not compromise the filesystem.
		 */
		ctx->options &= ~E2F_OPT_DISCARD;

do_counts:
		inodes++;
		if (bitmap) {
			if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i))
				dirs_count++;
			if (inodes > first_free) {
				e2fsck_discard_inodes(ctx, group, first_free,
						      inodes - first_free);
				first_free = fs->super->s_inodes_per_group + 1;
			}
		} else {
			group_free++;
			free_inodes++;
			if (first_free > inodes)
				first_free = inodes;
		}

		if ((inodes == fs->super->s_inodes_per_group) ||
		    (i == fs->super->s_inodes_count)) {
			/*
			 * If the last inode is free, we can discard it as well.
			 */
			if (!bitmap && inodes >= first_free)
				e2fsck_discard_inodes(ctx, group, first_free,
						      inodes - first_free + 1);
			/*
			 * If discard zeroes data and the group inode table
			 * was not zeroed yet, set itable as zeroed
			 */
			if ((ctx->options & E2F_OPT_DISCARD) &&
			    io_channel_discard_zeroes_data(fs->io) &&
			    !(ext2fs_bg_flags_test(fs, group,
						   EXT2_BG_INODE_ZEROED))) {
				ext2fs_bg_flags_set(fs, group,
						    EXT2_BG_INODE_ZEROED);
				ext2fs_group_desc_csum_set(fs, group);
			}

			first_free = fs->super->s_inodes_per_group + 1;
			free_array[group] = group_free;
			dir_array[group] = dirs_count;
			group ++;
			inodes = 0;
			skip_group = 0;
			group_free = 0;
			dirs_count = 0;
			if (ctx->progress)
				if ((ctx->progress)(ctx, 5,
					    group + fs->group_desc_count,
					    fs->group_desc_count*2))
					goto errout;
			if (csum_flag &&
			    (i != fs->super->s_inodes_count) &&
			    (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)
			     ))
				skip_group++;
		}
	}
	if (pctx.ino)
		print_bitmap_problem(ctx, save_problem, &pctx);

	if (had_problem)
		fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
	else
		fixit = -1;
	ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;

	if (fixit == 1) {
		ext2fs_free_inode_bitmap(fs->inode_map);
		retval = ext2fs_copy_bitmap(ctx->inode_used_map,
						  &fs->inode_map);
		if (retval) {
			clear_problem_context(&pctx);
			fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
			ctx->flags |= E2F_FLAG_ABORT;
			goto errout;
		}
		ext2fs_set_bitmap_padding(fs->inode_map);
		ext2fs_mark_ib_dirty(fs);

		/* redo counts */
		inodes = 0; free_inodes = 0; group_free = 0;
		dirs_count = 0; group = 0;
		memset(free_array, 0, fs->group_desc_count * sizeof(int));
		memset(dir_array, 0, fs->group_desc_count * sizeof(int));
		redo_flag++;
		goto redo_counts;
	} else if (fixit == 0)
		ext2fs_unmark_valid(fs);

	for (i = 0; i < fs->group_desc_count; i++) {
		if (free_array[i] != ext2fs_bg_free_inodes_count(fs, i)) {
			pctx.group = i;
			pctx.ino = ext2fs_bg_free_inodes_count(fs, i);
			pctx.ino2 = free_array[i];
			if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
					&pctx)) {
				ext2fs_bg_free_inodes_count_set(fs, i, free_array[i]);
				ext2fs_mark_super_dirty(fs);
			} else
				ext2fs_unmark_valid(fs);
		}
		if (dir_array[i] != ext2fs_bg_used_dirs_count(fs, i)) {
			pctx.group = i;
			pctx.ino = ext2fs_bg_used_dirs_count(fs, i);
			pctx.ino2 = dir_array[i];

			if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
					&pctx)) {
				ext2fs_bg_used_dirs_count_set(fs, i, dir_array[i]);
				ext2fs_mark_super_dirty(fs);
			} else
				ext2fs_unmark_valid(fs);
		}
	}
	if (free_inodes != fs->super->s_free_inodes_count) {
		pctx.group = -1;
		pctx.ino = fs->super->s_free_inodes_count;
		pctx.ino2 = free_inodes;

		if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
			fs->super->s_free_inodes_count = free_inodes;
			ext2fs_mark_super_dirty(fs);
		}
	}
errout:
	ext2fs_free_mem(&free_array);
	ext2fs_free_mem(&dir_array);
}

static void check_inode_end(e2fsck_t ctx)
{
	ext2_filsys fs = ctx->fs;
	ext2_ino_t	end, save_inodes_count, i;
	struct problem_context	pctx;

	clear_problem_context(&pctx);

	end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
	pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
						     &save_inodes_count);
	if (pctx.errcode) {
		pctx.num = 1;
		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		return;
	}
	if (save_inodes_count == end)
		return;

	/* protect loop from wrap-around if end is maxed */
	for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) {
		if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
			if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
				for (; i <= end; i++)
					ext2fs_mark_inode_bitmap(fs->inode_map,
								 i);
				ext2fs_mark_ib_dirty(fs);
			} else
				ext2fs_unmark_valid(fs);
			break;
		}
	}

	pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
						     save_inodes_count, 0);
	if (pctx.errcode) {
		pctx.num = 2;
		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		return;
	}
}

static void check_block_end(e2fsck_t ctx)
{
	ext2_filsys fs = ctx->fs;
	blk64_t	end, save_blocks_count, i;
	struct problem_context	pctx;

	clear_problem_context(&pctx);

	end = ext2fs_get_block_bitmap_start2(fs->block_map) +
		EXT2_GROUPS_TO_CLUSTERS(fs->super, fs->group_desc_count) - 1;
	pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map, end,
						     &save_blocks_count);
	if (pctx.errcode) {
		pctx.num = 3;
		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		return;
	}
	if (save_blocks_count == end)
		return;

	/* Protect loop from wrap-around if end is maxed */
	for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
		if (!ext2fs_test_block_bitmap2(fs->block_map,
					       EXT2FS_C2B(fs, i))) {
			if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
				for (; i <= end; i++)
					ext2fs_mark_block_bitmap2(fs->block_map,
							EXT2FS_C2B(fs, i));
				ext2fs_mark_bb_dirty(fs);
			} else
				ext2fs_unmark_valid(fs);
			break;
		}
	}

	pctx.errcode = ext2fs_fudge_block_bitmap_end2(fs->block_map,
						     save_blocks_count, 0);
	if (pctx.errcode) {
		pctx.num = 4;
		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
		return;
	}
}



