Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

jbd2: unify revoke and tag block checksum handling

Revoke and tag descriptor blocks are just different kinds of descriptor
blocks and thus have checksum in the same place. Unify computation and
checking of checksums for these.

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Jan Kara and committed by
Theodore Ts'o
1101cd4d 32ab6715

+25 -66
+1 -17
fs/jbd2/commit.c
··· 317 317 tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); 318 318 } 319 319 320 - static void jbd2_descr_block_csum_set(journal_t *j, 321 - struct buffer_head *bh) 322 - { 323 - struct jbd2_journal_block_tail *tail; 324 - __u32 csum; 325 - 326 - if (!jbd2_journal_has_csum_v2or3(j)) 327 - return; 328 - 329 - tail = (struct jbd2_journal_block_tail *)(bh->b_data + j->j_blocksize - 330 - sizeof(struct jbd2_journal_block_tail)); 331 - tail->t_checksum = 0; 332 - csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize); 333 - tail->t_checksum = cpu_to_be32(csum); 334 - } 335 - 336 320 static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, 337 321 struct buffer_head *bh, __u32 sequence) 338 322 { ··· 698 714 699 715 tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG); 700 716 701 - jbd2_descr_block_csum_set(journal, descriptor); 717 + jbd2_descriptor_block_csum_set(journal, descriptor); 702 718 start_journal_io: 703 719 for (i = 0; i < bufs; i++) { 704 720 struct buffer_head *bh = wbuf[i];
+15
fs/jbd2/journal.c
··· 834 834 return bh; 835 835 } 836 836 837 + void jbd2_descriptor_block_csum_set(journal_t *j, struct buffer_head *bh) 838 + { 839 + struct jbd2_journal_block_tail *tail; 840 + __u32 csum; 841 + 842 + if (!jbd2_journal_has_csum_v2or3(j)) 843 + return; 844 + 845 + tail = (struct jbd2_journal_block_tail *)(bh->b_data + j->j_blocksize - 846 + sizeof(struct jbd2_journal_block_tail)); 847 + tail->t_checksum = 0; 848 + csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize); 849 + tail->t_checksum = cpu_to_be32(csum); 850 + } 851 + 837 852 /* 838 853 * Return tid of the oldest transaction in the journal and block in the journal 839 854 * where the transaction starts.
+5 -26
fs/jbd2/recovery.c
··· 174 174 return 0; 175 175 } 176 176 177 - static int jbd2_descr_block_csum_verify(journal_t *j, 178 - void *buf) 177 + static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf) 179 178 { 180 179 struct jbd2_journal_block_tail *tail; 181 180 __be32 provided; ··· 521 522 descr_csum_size = 522 523 sizeof(struct jbd2_journal_block_tail); 523 524 if (descr_csum_size > 0 && 524 - !jbd2_descr_block_csum_verify(journal, 525 - bh->b_data)) { 525 + !jbd2_descriptor_block_csum_verify(journal, 526 + bh->b_data)) { 526 527 printk(KERN_ERR "JBD2: Invalid checksum " 527 528 "recovering block %lu in log\n", 528 529 next_log_block); ··· 810 811 return err; 811 812 } 812 813 813 - static int jbd2_revoke_block_csum_verify(journal_t *j, 814 - void *buf) 815 - { 816 - struct jbd2_journal_revoke_tail *tail; 817 - __be32 provided; 818 - __u32 calculated; 819 - 820 - if (!jbd2_journal_has_csum_v2or3(j)) 821 - return 1; 822 - 823 - tail = (struct jbd2_journal_revoke_tail *)(buf + j->j_blocksize - 824 - sizeof(struct jbd2_journal_revoke_tail)); 825 - provided = tail->r_checksum; 826 - tail->r_checksum = 0; 827 - calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize); 828 - tail->r_checksum = provided; 829 - 830 - return provided == cpu_to_be32(calculated); 831 - } 832 - 833 814 /* Scan a revoke record, marking all blocks mentioned as revoked. */ 834 815 835 816 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, ··· 825 846 offset = sizeof(jbd2_journal_revoke_header_t); 826 847 rcount = be32_to_cpu(header->r_count); 827 848 828 - if (!jbd2_revoke_block_csum_verify(journal, header)) 849 + if (!jbd2_descriptor_block_csum_verify(journal, header)) 829 850 return -EFSBADCRC; 830 851 831 852 if (jbd2_journal_has_csum_v2or3(journal)) 832 - csum_size = sizeof(struct jbd2_journal_revoke_tail); 853 + csum_size = sizeof(struct jbd2_journal_block_tail); 833 854 if (rcount > journal->j_blocksize - csum_size) 834 855 return -EINVAL; 835 856 max = rcount;
+2 -17
fs/jbd2/revoke.c
··· 583 583 584 584 /* Do we need to leave space at the end for a checksum? */ 585 585 if (jbd2_journal_has_csum_v2or3(journal)) 586 - csum_size = sizeof(struct jbd2_journal_revoke_tail); 586 + csum_size = sizeof(struct jbd2_journal_block_tail); 587 587 588 588 if (jbd2_has_feature_64bit(journal)) 589 589 sz = 8; ··· 623 623 *offsetp = offset; 624 624 } 625 625 626 - static void jbd2_revoke_csum_set(journal_t *j, struct buffer_head *bh) 627 - { 628 - struct jbd2_journal_revoke_tail *tail; 629 - __u32 csum; 630 - 631 - if (!jbd2_journal_has_csum_v2or3(j)) 632 - return; 633 - 634 - tail = (struct jbd2_journal_revoke_tail *)(bh->b_data + j->j_blocksize - 635 - sizeof(struct jbd2_journal_revoke_tail)); 636 - tail->r_checksum = 0; 637 - csum = jbd2_chksum(j, j->j_csum_seed, bh->b_data, j->j_blocksize); 638 - tail->r_checksum = cpu_to_be32(csum); 639 - } 640 - 641 626 /* 642 627 * Flush a revoke descriptor out to the journal. If we are aborting, 643 628 * this is a noop; otherwise we are generating a buffer which needs to ··· 643 658 644 659 header = (jbd2_journal_revoke_header_t *)descriptor->b_data; 645 660 header->r_count = cpu_to_be32(offset); 646 - jbd2_revoke_csum_set(journal, descriptor); 661 + jbd2_descriptor_block_csum_set(journal, descriptor); 647 662 648 663 set_buffer_jwrite(descriptor); 649 664 BUFFER_TRACE(descriptor, "write");
+2 -6
include/linux/jbd2.h
··· 200 200 __be32 t_blocknr_high; /* most-significant high 32bits. */ 201 201 } journal_block_tag_t; 202 202 203 - /* Tail of descriptor block, for checksumming */ 203 + /* Tail of descriptor or revoke block, for checksumming */ 204 204 struct jbd2_journal_block_tail { 205 205 __be32 t_checksum; /* crc32c(uuid+descr_block) */ 206 206 }; ··· 214 214 journal_header_t r_header; 215 215 __be32 r_count; /* Count of bytes used in the block */ 216 216 } jbd2_journal_revoke_header_t; 217 - 218 - /* Tail of revoke block, for checksumming */ 219 - struct jbd2_journal_revoke_tail { 220 - __be32 r_checksum; /* crc32c(uuid+revoke_block) */ 221 - }; 222 217 223 218 /* Definitions for the journal tag flags word: */ 224 219 #define JBD2_FLAG_ESCAPE 1 /* on-disk block is escaped */ ··· 1133 1138 1134 1139 /* Log buffer allocation */ 1135 1140 struct buffer_head *jbd2_journal_get_descriptor_buffer(transaction_t *, int); 1141 + void jbd2_descriptor_block_csum_set(journal_t *, struct buffer_head *); 1136 1142 int jbd2_journal_next_log_block(journal_t *, unsigned long long *); 1137 1143 int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid, 1138 1144 unsigned long *block);