Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 309953
b: refs/heads/master
c: c390087
h: refs/heads/master
i:
  309951: 57ddf73
v: v3
  • Loading branch information
Darrick J. Wong authored and Theodore Ts'o committed May 27, 2012
1 parent 6e7306d commit bb4942e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1f56c5890e3e815c6f4eabfc87a8a81f439b6f3d
refs/heads/master: c390087591dcbecd244c31d979ccdad49ae83364
22 changes: 22 additions & 0 deletions trunk/fs/jbd2/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,26 @@ static void jbd2_descr_block_csum_set(journal_t *j,
tail->t_checksum = cpu_to_be32(csum);
}

static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag,
struct buffer_head *bh, __u32 sequence)
{
struct page *page = bh->b_page;
__u8 *addr;
__u32 csum;

if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
return;

sequence = cpu_to_be32(sequence);
addr = kmap_atomic(page, KM_USER0);
csum = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&sequence,
sizeof(sequence));
csum = jbd2_chksum(j, csum, addr + offset_in_page(bh->b_data),
bh->b_size);
kunmap_atomic(addr, KM_USER0);

tag->t_checksum = cpu_to_be32(csum);
}
/*
* jbd2_journal_commit_transaction
*
Expand Down Expand Up @@ -669,6 +689,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
tag = (journal_block_tag_t *) tagp;
write_tag_block(tag_bytes, tag, jh2bh(jh)->b_blocknr);
tag->t_flags = cpu_to_be16(tag_flag);
jbd2_block_tag_csum_set(journal, tag, jh2bh(new_jh),
commit_transaction->t_tid);
tagp += tag_bytes;
space_left -= tag_bytes;

Expand Down
10 changes: 8 additions & 2 deletions trunk/fs/jbd2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2097,10 +2097,16 @@ int jbd2_journal_blocks_per_page(struct inode *inode)
*/
size_t journal_tag_bytes(journal_t *journal)
{
journal_block_tag_t tag;
size_t x = 0;

if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2))
x += sizeof(tag.t_checksum);

if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
return JBD2_TAG_SIZE64;
return x + JBD2_TAG_SIZE64;
else
return JBD2_TAG_SIZE32;
return x + JBD2_TAG_SIZE32;
}

/*
Expand Down
30 changes: 30 additions & 0 deletions trunk/fs/jbd2/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,23 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf)
return provided == calculated;
}

static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
void *buf, __u32 sequence)
{
__u32 provided, calculated;

if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
return 1;

sequence = cpu_to_be32(sequence);
calculated = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&sequence,
sizeof(sequence));
calculated = jbd2_chksum(j, calculated, buf, j->j_blocksize);
provided = be32_to_cpu(tag->t_checksum);

return provided == cpu_to_be32(calculated);
}

static int do_one_pass(journal_t *journal,
struct recovery_info *info, enum passtype pass)
{
Expand Down Expand Up @@ -569,6 +586,19 @@ static int do_one_pass(journal_t *journal,
goto skip_write;
}

/* Look for block corruption */
if (!jbd2_block_tag_csum_verify(
journal, tag, obh->b_data,
be32_to_cpu(tmp->h_sequence))) {
brelse(obh);
success = -EIO;
printk(KERN_ERR "JBD: Invalid "
"checksum recovering "
"block %llu in log\n",
blocknr);
continue;
}

/* Find a buffer for the new
* data being restored */
nbh = __getblk(journal->j_fs_dev,
Expand Down

0 comments on commit bb4942e

Please sign in to comment.