@@ -28,6 +28,7 @@ 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)
{
@@ -66,6 +67,7 @@ void e2fsck_pass5(e2fsck_t ctx)
return;
check_inode_bitmap_checksum(ctx);
+ check_block_bitmap_checksum(ctx);
ext2fs_free_inode_bitmap(ctx->inode_used_map);
ctx->inode_used_map = 0;
@@ -136,6 +138,67 @@ static void check_inode_bitmap_checksum(e2fsck_t ctx)
ext2fs_free_mem(&buf);
}
+static void check_block_bitmap_checksum(e2fsck_t ctx)
+{
+ struct problem_context pctx;
+ struct ext4_group_desc *gdp;
+ char *buf;
+ dgrp_t i;
+ int nbytes;
+ blk64_t blk_itr;
+ errcode_t retval;
+
+ if (!EXT2_HAS_RO_COMPAT_FEATURE(ctx->fs->super,
+ EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+ 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_memalign(ctx->fs->blocksize, ctx->fs->blocksize,
+ &buf);
+ if (retval) {
+ com_err(ctx->program_name, 0,
+ _("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) +
+ (i * (nbytes << 3));
+ gdp = (struct ext4_group_desc *)ext2fs_group_desc(ctx->fs,
+ ctx->fs->group_desc, i);
+ 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, io_manager manager,
blk64_t start, blk64_t count)
{
@@ -1689,6 +1689,11 @@ static struct e2fsck_problem problem_table[] = {
N_("@g %g @i bitmap does not match checksum\n"),
PROMPT_FIX, PR_LATCH_IBITMAP | PR_PREEN_OK },
+ /* Group N block bitmap does not match checksum */
+ { PR_5_BLOCK_BITMAP_CSUM_INVALID,
+ N_("@g %g @b bitmap does not match checksum\n"),
+ PROMPT_FIX, PR_LATCH_BBITMAP | PR_PREEN_OK },
+
/* Post-Pass 5 errors */
/* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */
@@ -1022,6 +1022,9 @@ struct problem_context {
/* Inode bitmap checksum does not match */
#define PR_5_INODE_BITMAP_CSUM_INVALID 0x05001A
+/* Block bitmap checksum does not match */
+#define PR_5_BLOCK_BITMAP_CSUM_INVALID 0x05001B
+
/*
* Post-Pass 5 errors
*/
Check block bitmap checksum and write a new checksum if the verification fails. This is ok because e2fsck has already computed the correct block bitmap. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> --- e2fsck/pass5.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ e2fsck/problem.c | 5 ++++ e2fsck/problem.h | 3 +++ 3 files changed, 71 insertions(+), 0 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html