aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/recovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/recovery.c')
-rw-r--r--fs/jbd2/recovery.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 980f3d6b5f88..728ecd0705d9 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -706,6 +706,25 @@ static int do_one_pass(journal_t *journal,
706 return err; 706 return err;
707} 707}
708 708
709static int jbd2_revoke_block_csum_verify(journal_t *j,
710 void *buf)
711{
712 struct jbd2_journal_revoke_tail *tail;
713 __u32 provided, calculated;
714
715 if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
716 return 1;
717
718 tail = (struct jbd2_journal_revoke_tail *)(buf + j->j_blocksize -
719 sizeof(struct jbd2_journal_revoke_tail));
720 provided = tail->r_checksum;
721 tail->r_checksum = 0;
722 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
723 tail->r_checksum = provided;
724
725 provided = be32_to_cpu(provided);
726 return provided == calculated;
727}
709 728
710/* Scan a revoke record, marking all blocks mentioned as revoked. */ 729/* Scan a revoke record, marking all blocks mentioned as revoked. */
711 730
@@ -720,6 +739,9 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
720 offset = sizeof(jbd2_journal_revoke_header_t); 739 offset = sizeof(jbd2_journal_revoke_header_t);
721 max = be32_to_cpu(header->r_count); 740 max = be32_to_cpu(header->r_count);
722 741
742 if (!jbd2_revoke_block_csum_verify(journal, header))
743 return -EINVAL;
744
723 if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) 745 if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
724 record_len = 8; 746 record_len = 8;
725 747