summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2016-02-22 23:19:09 -0500
committerTheodore Ts'o <tytso@mit.edu>2016-02-22 23:19:09 -0500
commit1101cd4d13ba2f42c5da4c1b9081f35a73b5df31 (patch)
treec7808f5f15396fba6e5e3e68209bbe4bf4cd073f
parent32ab671599a89534f37e97d146c27690e371b661 (diff)
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>
-rw-r--r--fs/jbd2/commit.c18
-rw-r--r--fs/jbd2/journal.c15
-rw-r--r--fs/jbd2/recovery.c31
-rw-r--r--fs/jbd2/revoke.c19
-rw-r--r--include/linux/jbd2.h8
5 files changed, 25 insertions, 66 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index cf221f3d955a..ae832cd44dd8 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -317,22 +317,6 @@ static void write_tag_block(journal_t *j, journal_block_tag_t *tag,
317 tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); 317 tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
318} 318}
319 319
320static 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
336static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, 320static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag,
337 struct buffer_head *bh, __u32 sequence) 321 struct buffer_head *bh, __u32 sequence)
338{ 322{
@@ -714,7 +698,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
714 698
715 tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG); 699 tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG);
716 700
717 jbd2_descr_block_csum_set(journal, descriptor); 701 jbd2_descriptor_block_csum_set(journal, descriptor);
718start_journal_io: 702start_journal_io:
719 for (i = 0; i < bufs; i++) { 703 for (i = 0; i < bufs; i++) {
720 struct buffer_head *bh = wbuf[i]; 704 struct buffer_head *bh = wbuf[i];
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 28d05bd9a588..defa962a8e15 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -834,6 +834,21 @@ jbd2_journal_get_descriptor_buffer(transaction_t *transaction, int type)
834 return bh; 834 return bh;
835} 835}
836 836
837void 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 * Return tid of the oldest transaction in the journal and block in the journal 853 * Return tid of the oldest transaction in the journal and block in the journal
839 * where the transaction starts. 854 * where the transaction starts.
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 7f277e49fe88..08a456b96e4e 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -174,8 +174,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
174 return 0; 174 return 0;
175} 175}
176 176
177static int jbd2_descr_block_csum_verify(journal_t *j, 177static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf)
178 void *buf)
179{ 178{
180 struct jbd2_journal_block_tail *tail; 179 struct jbd2_journal_block_tail *tail;
181 __be32 provided; 180 __be32 provided;
@@ -522,8 +521,8 @@ static int do_one_pass(journal_t *journal,
522 descr_csum_size = 521 descr_csum_size =
523 sizeof(struct jbd2_journal_block_tail); 522 sizeof(struct jbd2_journal_block_tail);
524 if (descr_csum_size > 0 && 523 if (descr_csum_size > 0 &&
525 !jbd2_descr_block_csum_verify(journal, 524 !jbd2_descriptor_block_csum_verify(journal,
526 bh->b_data)) { 525 bh->b_data)) {
527 printk(KERN_ERR "JBD2: Invalid checksum " 526 printk(KERN_ERR "JBD2: Invalid checksum "
528 "recovering block %lu in log\n", 527 "recovering block %lu in log\n",
529 next_log_block); 528 next_log_block);
@@ -811,26 +810,6 @@ static int do_one_pass(journal_t *journal,
811 return err; 810 return err;
812} 811}
813 812
814static int jbd2_revoke_block_csum_verify(journal_t *j,
815 void *buf)
816{
817 struct jbd2_journal_revoke_tail *tail;
818 __be32 provided;
819 __u32 calculated;
820
821 if (!jbd2_journal_has_csum_v2or3(j))
822 return 1;
823
824 tail = (struct jbd2_journal_revoke_tail *)(buf + j->j_blocksize -
825 sizeof(struct jbd2_journal_revoke_tail));
826 provided = tail->r_checksum;
827 tail->r_checksum = 0;
828 calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
829 tail->r_checksum = provided;
830
831 return provided == cpu_to_be32(calculated);
832}
833
834/* Scan a revoke record, marking all blocks mentioned as revoked. */ 813/* Scan a revoke record, marking all blocks mentioned as revoked. */
835 814
836static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, 815static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
@@ -846,11 +825,11 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
846 offset = sizeof(jbd2_journal_revoke_header_t); 825 offset = sizeof(jbd2_journal_revoke_header_t);
847 rcount = be32_to_cpu(header->r_count); 826 rcount = be32_to_cpu(header->r_count);
848 827
849 if (!jbd2_revoke_block_csum_verify(journal, header)) 828 if (!jbd2_descriptor_block_csum_verify(journal, header))
850 return -EFSBADCRC; 829 return -EFSBADCRC;
851 830
852 if (jbd2_journal_has_csum_v2or3(journal)) 831 if (jbd2_journal_has_csum_v2or3(journal))
853 csum_size = sizeof(struct jbd2_journal_revoke_tail); 832 csum_size = sizeof(struct jbd2_journal_block_tail);
854 if (rcount > journal->j_blocksize - csum_size) 833 if (rcount > journal->j_blocksize - csum_size)
855 return -EINVAL; 834 return -EINVAL;
856 max = rcount; 835 max = rcount;
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index d1ebb1d41d17..91171dc352cb 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -583,7 +583,7 @@ static void write_one_revoke_record(transaction_t *transaction,
583 583
584 /* Do we need to leave space at the end for a checksum? */ 584 /* Do we need to leave space at the end for a checksum? */
585 if (jbd2_journal_has_csum_v2or3(journal)) 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 if (jbd2_has_feature_64bit(journal)) 588 if (jbd2_has_feature_64bit(journal))
589 sz = 8; 589 sz = 8;
@@ -623,21 +623,6 @@ static void write_one_revoke_record(transaction_t *transaction,
623 *offsetp = offset; 623 *offsetp = offset;
624} 624}
625 625
626static 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 * Flush a revoke descriptor out to the journal. If we are aborting, 627 * Flush a revoke descriptor out to the journal. If we are aborting,
643 * this is a noop; otherwise we are generating a buffer which needs to 628 * this is a noop; otherwise we are generating a buffer which needs to
@@ -658,7 +643,7 @@ static void flush_descriptor(journal_t *journal,
658 643
659 header = (jbd2_journal_revoke_header_t *)descriptor->b_data; 644 header = (jbd2_journal_revoke_header_t *)descriptor->b_data;
660 header->r_count = cpu_to_be32(offset); 645 header->r_count = cpu_to_be32(offset);
661 jbd2_revoke_csum_set(journal, descriptor); 646 jbd2_descriptor_block_csum_set(journal, descriptor);
662 647
663 set_buffer_jwrite(descriptor); 648 set_buffer_jwrite(descriptor);
664 BUFFER_TRACE(descriptor, "write"); 649 BUFFER_TRACE(descriptor, "write");
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 3649cb8d3a41..fd1083c46c61 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -200,7 +200,7 @@ typedef struct journal_block_tag_s
200 __be32 t_blocknr_high; /* most-significant high 32bits. */ 200 __be32 t_blocknr_high; /* most-significant high 32bits. */
201} journal_block_tag_t; 201} journal_block_tag_t;
202 202
203/* Tail of descriptor block, for checksumming */ 203/* Tail of descriptor or revoke block, for checksumming */
204struct jbd2_journal_block_tail { 204struct jbd2_journal_block_tail {
205 __be32 t_checksum; /* crc32c(uuid+descr_block) */ 205 __be32 t_checksum; /* crc32c(uuid+descr_block) */
206}; 206};
@@ -215,11 +215,6 @@ typedef struct jbd2_journal_revoke_header_s
215 __be32 r_count; /* Count of bytes used in the block */ 215 __be32 r_count; /* Count of bytes used in the block */
216} jbd2_journal_revoke_header_t; 216} jbd2_journal_revoke_header_t;
217 217
218/* Tail of revoke block, for checksumming */
219struct jbd2_journal_revoke_tail {
220 __be32 r_checksum; /* crc32c(uuid+revoke_block) */
221};
222
223/* Definitions for the journal tag flags word: */ 218/* Definitions for the journal tag flags word: */
224#define JBD2_FLAG_ESCAPE 1 /* on-disk block is escaped */ 219#define JBD2_FLAG_ESCAPE 1 /* on-disk block is escaped */
225#define JBD2_FLAG_SAME_UUID 2 /* block has same uuid as previous */ 220#define JBD2_FLAG_SAME_UUID 2 /* block has same uuid as previous */
@@ -1138,6 +1133,7 @@ static inline void jbd2_unfile_log_bh(struct buffer_head *bh)
1138 1133
1139/* Log buffer allocation */ 1134/* Log buffer allocation */
1140struct buffer_head *jbd2_journal_get_descriptor_buffer(transaction_t *, int); 1135struct buffer_head *jbd2_journal_get_descriptor_buffer(transaction_t *, int);
1136void jbd2_descriptor_block_csum_set(journal_t *, struct buffer_head *);
1141int jbd2_journal_next_log_block(journal_t *, unsigned long long *); 1137int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
1142int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid, 1138int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
1143 unsigned long *block); 1139 unsigned long *block);