diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2012-05-27 08:08:24 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-05-27 08:08:24 -0400 |
commit | 42a7106de636ebf9c0b93d25b4230e14f5f2682e (patch) | |
tree | 321f2e97768bc12962babb018004f8f6b1f7e57f /fs/jbd2/revoke.c | |
parent | 4fd5ea43bc11602bfabe2c8f5378586d34bd2b0a (diff) |
jbd2: checksum revocation blocks
Compute and verify revoke blocks inside the journal.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2/revoke.c')
-rw-r--r-- | fs/jbd2/revoke.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 6973705d6a3d..f30b80b4ce8b 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -578,6 +578,7 @@ static void write_one_revoke_record(journal_t *journal, | |||
578 | struct jbd2_revoke_record_s *record, | 578 | struct jbd2_revoke_record_s *record, |
579 | int write_op) | 579 | int write_op) |
580 | { | 580 | { |
581 | int csum_size = 0; | ||
581 | struct journal_head *descriptor; | 582 | struct journal_head *descriptor; |
582 | int offset; | 583 | int offset; |
583 | journal_header_t *header; | 584 | journal_header_t *header; |
@@ -592,9 +593,13 @@ static void write_one_revoke_record(journal_t *journal, | |||
592 | descriptor = *descriptorp; | 593 | descriptor = *descriptorp; |
593 | offset = *offsetp; | 594 | offset = *offsetp; |
594 | 595 | ||
596 | /* Do we need to leave space at the end for a checksum? */ | ||
597 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | ||
598 | csum_size = sizeof(struct jbd2_journal_revoke_tail); | ||
599 | |||
595 | /* Make sure we have a descriptor with space left for the record */ | 600 | /* Make sure we have a descriptor with space left for the record */ |
596 | if (descriptor) { | 601 | if (descriptor) { |
597 | if (offset == journal->j_blocksize) { | 602 | if (offset >= journal->j_blocksize - csum_size) { |
598 | flush_descriptor(journal, descriptor, offset, write_op); | 603 | flush_descriptor(journal, descriptor, offset, write_op); |
599 | descriptor = NULL; | 604 | descriptor = NULL; |
600 | } | 605 | } |
@@ -631,6 +636,24 @@ static void write_one_revoke_record(journal_t *journal, | |||
631 | *offsetp = offset; | 636 | *offsetp = offset; |
632 | } | 637 | } |
633 | 638 | ||
639 | static void jbd2_revoke_csum_set(journal_t *j, | ||
640 | struct journal_head *descriptor) | ||
641 | { | ||
642 | struct jbd2_journal_revoke_tail *tail; | ||
643 | __u32 csum; | ||
644 | |||
645 | if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) | ||
646 | return; | ||
647 | |||
648 | tail = (struct jbd2_journal_revoke_tail *) | ||
649 | (jh2bh(descriptor)->b_data + j->j_blocksize - | ||
650 | sizeof(struct jbd2_journal_revoke_tail)); | ||
651 | tail->r_checksum = 0; | ||
652 | csum = jbd2_chksum(j, j->j_csum_seed, jh2bh(descriptor)->b_data, | ||
653 | j->j_blocksize); | ||
654 | tail->r_checksum = cpu_to_be32(csum); | ||
655 | } | ||
656 | |||
634 | /* | 657 | /* |
635 | * Flush a revoke descriptor out to the journal. If we are aborting, | 658 | * Flush a revoke descriptor out to the journal. If we are aborting, |
636 | * this is a noop; otherwise we are generating a buffer which needs to | 659 | * this is a noop; otherwise we are generating a buffer which needs to |
@@ -652,6 +675,8 @@ static void flush_descriptor(journal_t *journal, | |||
652 | 675 | ||
653 | header = (jbd2_journal_revoke_header_t *) jh2bh(descriptor)->b_data; | 676 | header = (jbd2_journal_revoke_header_t *) jh2bh(descriptor)->b_data; |
654 | header->r_count = cpu_to_be32(offset); | 677 | header->r_count = cpu_to_be32(offset); |
678 | jbd2_revoke_csum_set(journal, descriptor); | ||
679 | |||
655 | set_buffer_jwrite(bh); | 680 | set_buffer_jwrite(bh); |
656 | BUFFER_TRACE(bh, "write"); | 681 | BUFFER_TRACE(bh, "write"); |
657 | set_buffer_dirty(bh); | 682 | set_buffer_dirty(bh); |