From: Darrick J. Wong Date: Fri, 3 Aug 2012 00:47:46 +0000 (-0400) Subject: e2fsck: check commit block checksum during recovery X-Git-Tag: v1.43-WIP-2012-09-22~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=721e065c6262371598d8490a32998d53bfe62ce8;p=thirdparty%2Fe2fsprogs.git e2fsck: check commit block checksum during recovery When recovering a journal with checksum v2, verify the commit block checksum. Signed-off-by: Darrick J. Wong Signed-off-by: Theodore Ts'o --- diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c index 208e1cbd4..897a3ffd3 100644 --- a/e2fsck/recovery.c +++ b/e2fsck/recovery.c @@ -373,6 +373,26 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh, return 0; } +static int jbd2_commit_block_csum_verify(journal_t *j, void *buf) +{ + struct commit_header *h; + __u32 provided, calculated; + + if (!JFS_HAS_INCOMPAT_FEATURE(j, JFS_FEATURE_INCOMPAT_CSUM_V2)) + return 1; + + h = buf; + provided = h->h_chksum[0]; + h->h_chksum[0] = 0; + calculated = ext2fs_crc32c_le(~0, j->j_superblock->s_uuid, + sizeof(j->j_superblock->s_uuid)); + calculated = ext2fs_crc32c_le(calculated, buf, j->j_blocksize); + h->h_chksum[0] = provided; + + provided = ext2fs_be32_to_cpu(provided); + return provided == calculated; +} + static int do_one_pass(journal_t *journal, struct recovery_info *info, enum passtype pass) { @@ -695,6 +715,19 @@ static int do_one_pass(journal_t *journal, } crc32_sum = ~0; } + if (pass == PASS_SCAN && + !jbd2_commit_block_csum_verify(journal, + bh->b_data)) { + info->end_transaction = next_commit_ID; + + if (!JFS_HAS_INCOMPAT_FEATURE(journal, + JFS_FEATURE_INCOMPAT_ASYNC_COMMIT)) { + journal->j_failed_commit = + next_commit_ID; + brelse(bh); + break; + } + } brelse(bh); next_commit_ID++; continue;