177
static int jbd2_descr_block_csum_verify(journal_t *j,
180
struct jbd2_journal_block_tail *tail;
181
__u32 provided, calculated;
183
if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
186
tail = (struct jbd2_journal_block_tail *)(buf + j->j_blocksize -
187
sizeof(struct jbd2_journal_block_tail));
188
provided = tail->t_checksum;
189
tail->t_checksum = 0;
190
calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
191
tail->t_checksum = provided;
193
provided = be32_to_cpu(provided);
194
return provided == calculated;
179
198
* Count the number of in-use tags in a journal descriptor block.
186
205
int nr = 0, size = journal->j_blocksize;
187
206
int tag_bytes = journal_tag_bytes(journal);
208
if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2))
209
size -= sizeof(struct jbd2_journal_block_tail);
189
211
tagp = &bh->b_data[sizeof(journal_header_t)];
191
213
while ((tagp - bh->b_data + tag_bytes) <= size) {
195
217
tagp += tag_bytes;
196
if (!(tag->t_flags & cpu_to_be32(JBD2_FLAG_SAME_UUID)))
218
if (!(tag->t_flags & cpu_to_be16(JBD2_FLAG_SAME_UUID)))
199
if (tag->t_flags & cpu_to_be32(JBD2_FLAG_LAST_TAG))
221
if (tag->t_flags & cpu_to_be16(JBD2_FLAG_LAST_TAG))
378
static int jbd2_commit_block_csum_verify(journal_t *j, void *buf)
380
struct commit_header *h;
381
__u32 provided, calculated;
383
if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
387
provided = h->h_chksum[0];
389
calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
390
h->h_chksum[0] = provided;
392
provided = be32_to_cpu(provided);
393
return provided == calculated;
396
static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
397
void *buf, __u32 sequence)
399
__u32 provided, calculated;
401
if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
404
sequence = cpu_to_be32(sequence);
405
calculated = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&sequence,
407
calculated = jbd2_chksum(j, calculated, buf, j->j_blocksize);
408
provided = be32_to_cpu(tag->t_checksum);
410
return provided == cpu_to_be32(calculated);
356
413
static int do_one_pass(journal_t *journal,
357
414
struct recovery_info *info, enum passtype pass)
452
510
switch(blocktype) {
453
511
case JBD2_DESCRIPTOR_BLOCK:
512
/* Verify checksum first */
513
if (JBD2_HAS_INCOMPAT_FEATURE(journal,
514
JBD2_FEATURE_INCOMPAT_CSUM_V2))
516
sizeof(struct jbd2_journal_block_tail);
517
if (descr_csum_size > 0 &&
518
!jbd2_descr_block_csum_verify(journal,
454
524
/* If it is a valid descriptor block, replay it
455
525
* in pass REPLAY; if journal_checksums enabled, then
456
526
* calculate checksums in PASS_SCAN, otherwise,
482
552
tagp = &bh->b_data[sizeof(journal_header_t)];
483
553
while ((tagp - bh->b_data + tag_bytes)
484
<= journal->j_blocksize) {
554
<= journal->j_blocksize - descr_csum_size) {
485
555
unsigned long io_block;
487
557
tag = (journal_block_tag_t *) tagp;
488
flags = be32_to_cpu(tag->t_flags);
558
flags = be16_to_cpu(tag->t_flags);
490
560
io_block = next_log_block++;
491
561
wrap(journal, next_log_block);
589
/* Look for block corruption */
590
if (!jbd2_block_tag_csum_verify(
591
journal, tag, obh->b_data,
592
be32_to_cpu(tmp->h_sequence))) {
595
printk(KERN_ERR "JBD: Invalid "
596
"checksum recovering "
597
"block %llu in log\n",
519
602
/* Find a buffer for the new
520
603
* data being restored */
521
604
nbh = __getblk(journal->j_fs_dev,
736
if (pass == PASS_SCAN &&
737
!jbd2_commit_block_csum_verify(journal,
739
info->end_transaction = next_commit_ID;
741
if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
742
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
743
journal->j_failed_commit =
654
750
next_commit_ID++;
805
static int jbd2_revoke_block_csum_verify(journal_t *j,
808
struct jbd2_journal_revoke_tail *tail;
809
__u32 provided, calculated;
811
if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2))
814
tail = (struct jbd2_journal_revoke_tail *)(buf + j->j_blocksize -
815
sizeof(struct jbd2_journal_revoke_tail));
816
provided = tail->r_checksum;
817
tail->r_checksum = 0;
818
calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize);
819
tail->r_checksum = provided;
821
provided = be32_to_cpu(provided);
822
return provided == calculated;
710
825
/* Scan a revoke record, marking all blocks mentioned as revoked. */
720
835
offset = sizeof(jbd2_journal_revoke_header_t);
721
836
max = be32_to_cpu(header->r_count);
838
if (!jbd2_revoke_block_csum_verify(journal, header))
723
841
if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))