diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2012-08-02 20:47:46 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-08-02 20:47:46 -0400 |
commit | 721e065c6262371598d8490a32998d53bfe62ce8 (patch) | |
tree | ddfcdb23feccb7cf999a6fae4238bef855b2eed5 | |
parent | 5c8428513dc0e53af847b5435f58c94237d1cc3d (diff) | |
download | android_external_e2fsprogs-721e065c6262371598d8490a32998d53bfe62ce8.tar.gz android_external_e2fsprogs-721e065c6262371598d8490a32998d53bfe62ce8.tar.bz2 android_external_e2fsprogs-721e065c6262371598d8490a32998d53bfe62ce8.zip |
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 <djwong@us.ibm.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | e2fsck/recovery.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c index 208e1cbd..897a3ffd 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; |