/*
 * 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"

#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

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 succint */
#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;
	}
}



