Commit 1f56c589 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Theodore Ts'o

jbd2: checksum commit blocks

Calculate and verify the checksum of commit blocks.  In checksum v2,
deprecate most of the checksum v1 commit block checksum fields, since
each block has its own checksum.
Signed-off-by: default avatarDarrick J. Wong <djwong@us.ibm.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 3caa487f
...@@ -85,6 +85,24 @@ static void release_buffer_page(struct buffer_head *bh) ...@@ -85,6 +85,24 @@ static void release_buffer_page(struct buffer_head *bh)
__brelse(bh); __brelse(bh);
} }
static void jbd2_commit_block_csum_set(journal_t *j,
struct journal_head *descriptor)
{
struct commit_header *h;
__u32 csum;
if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
return;
h = (struct commit_header *)(jh2bh(descriptor)->b_data);
h->h_chksum_type = 0;
h->h_chksum_size = 0;
h->h_chksum[0] = 0;
csum = jbd2_chksum(j, j->j_csum_seed, jh2bh(descriptor)->b_data,
j->j_blocksize);
h->h_chksum[0] = cpu_to_be32(csum);
}
/* /*
* Done it all: now submit the commit record. We should have * Done it all: now submit the commit record. We should have
* cleaned up our previous buffers by now, so if we are in abort * cleaned up our previous buffers by now, so if we are in abort
...@@ -128,6 +146,7 @@ static int journal_submit_commit_record(journal_t *journal, ...@@ -128,6 +146,7 @@ static int journal_submit_commit_record(journal_t *journal,
tmp->h_chksum_size = JBD2_CRC32_CHKSUM_SIZE; tmp->h_chksum_size = JBD2_CRC32_CHKSUM_SIZE;
tmp->h_chksum[0] = cpu_to_be32(crc32_sum); tmp->h_chksum[0] = cpu_to_be32(crc32_sum);
} }
jbd2_commit_block_csum_set(journal, descriptor);
JBUFFER_TRACE(descriptor, "submit commit block"); JBUFFER_TRACE(descriptor, "submit commit block");
lock_buffer(bh); lock_buffer(bh);
......
...@@ -375,6 +375,24 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh, ...@@ -375,6 +375,24 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh,
return 0; return 0;
} }
static int jbd2_commit_block_csum_verify(journal_t *j, void *buf)
{
struct commit_header *h;
__u32 provided, calculated;
if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
return 1;
h = buf;
provided = h->h_chksum[0];
h->h_chksum[0] = 0;
calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
h->h_chksum[0] = provided;
provided = be32_to_cpu(provided);
return provided == calculated;
}
static int do_one_pass(journal_t *journal, static int do_one_pass(journal_t *journal,
struct recovery_info *info, enum passtype pass) struct recovery_info *info, enum passtype pass)
{ {
...@@ -685,6 +703,19 @@ static int do_one_pass(journal_t *journal, ...@@ -685,6 +703,19 @@ static int do_one_pass(journal_t *journal,
} }
crc32_sum = ~0; crc32_sum = ~0;
} }
if (pass == PASS_SCAN &&
!jbd2_commit_block_csum_verify(journal,
bh->b_data)) {
info->end_transaction = next_commit_ID;
if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
journal->j_failed_commit =
next_commit_ID;
brelse(bh);
break;
}
}
brelse(bh); brelse(bh);
next_commit_ID++; next_commit_ID++;
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment