@@ -485,6 +485,105 @@ static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
485
485
return tag -> t_checksum == cpu_to_be16 (csum32 );
486
486
}
487
487
488
+ static __always_inline int jbd2_do_replay (journal_t * journal ,
489
+ struct recovery_info * info ,
490
+ struct buffer_head * bh ,
491
+ unsigned long * next_log_block ,
492
+ unsigned int next_commit_ID ,
493
+ int * success , int * block_error )
494
+ {
495
+ char * tagp ;
496
+ int flags ;
497
+ int err ;
498
+ int tag_bytes = journal_tag_bytes (journal );
499
+ int descr_csum_size = 0 ;
500
+ unsigned long io_block ;
501
+ journal_block_tag_t tag ;
502
+ struct buffer_head * obh ;
503
+ struct buffer_head * nbh ;
504
+
505
+ if (jbd2_journal_has_csum_v2or3 (journal ))
506
+ descr_csum_size = sizeof (struct jbd2_journal_block_tail );
507
+
508
+ tagp = & bh -> b_data [sizeof (journal_header_t )];
509
+ while (tagp - bh -> b_data + tag_bytes <=
510
+ journal -> j_blocksize - descr_csum_size ) {
511
+
512
+ memcpy (& tag , tagp , sizeof (tag ));
513
+ flags = be16_to_cpu (tag .t_flags );
514
+
515
+ io_block = (* next_log_block )++ ;
516
+ wrap (journal , * next_log_block );
517
+ err = jread (& obh , journal , io_block );
518
+ if (err ) {
519
+ /* Recover what we can, but report failure at the end. */
520
+ * success = err ;
521
+ pr_err ("JBD2: IO error %d recovering block %lu in log\n" ,
522
+ err , io_block );
523
+ } else {
524
+ unsigned long long blocknr ;
525
+
526
+ J_ASSERT (obh != NULL );
527
+ blocknr = read_tag_block (journal , & tag );
528
+
529
+ /* If the block has been revoked, then we're all done here. */
530
+ if (jbd2_journal_test_revoke (journal , blocknr ,
531
+ next_commit_ID )) {
532
+ brelse (obh );
533
+ ++ info -> nr_revoke_hits ;
534
+ goto skip_write ;
535
+ }
536
+
537
+ /* Look for block corruption */
538
+ if (!jbd2_block_tag_csum_verify (journal , & tag ,
539
+ (journal_block_tag3_t * )tagp ,
540
+ obh -> b_data , next_commit_ID )) {
541
+ brelse (obh );
542
+ * success = - EFSBADCRC ;
543
+ pr_err ("JBD2: Invalid checksum recovering data block %llu in journal block %lu\n" ,
544
+ blocknr , io_block );
545
+ * block_error = 1 ;
546
+ goto skip_write ;
547
+ }
548
+
549
+ /* Find a buffer for the new data being restored */
550
+ nbh = __getblk (journal -> j_fs_dev , blocknr ,
551
+ journal -> j_blocksize );
552
+ if (nbh == NULL ) {
553
+ pr_err ("JBD2: Out of memory during recovery.\n" );
554
+ brelse (obh );
555
+ return - ENOMEM ;
556
+ }
557
+
558
+ lock_buffer (nbh );
559
+ memcpy (nbh -> b_data , obh -> b_data , journal -> j_blocksize );
560
+ if (flags & JBD2_FLAG_ESCAPE ) {
561
+ * ((__be32 * )nbh -> b_data ) =
562
+ cpu_to_be32 (JBD2_MAGIC_NUMBER );
563
+ }
564
+
565
+ BUFFER_TRACE (nbh , "marking dirty" );
566
+ set_buffer_uptodate (nbh );
567
+ mark_buffer_dirty (nbh );
568
+ BUFFER_TRACE (nbh , "marking uptodate" );
569
+ ++ info -> nr_replays ;
570
+ unlock_buffer (nbh );
571
+ brelse (obh );
572
+ brelse (nbh );
573
+ }
574
+
575
+ skip_write :
576
+ tagp += tag_bytes ;
577
+ if (!(flags & JBD2_FLAG_SAME_UUID ))
578
+ tagp += 16 ;
579
+
580
+ if (flags & JBD2_FLAG_LAST_TAG )
581
+ break ;
582
+ }
583
+
584
+ return 0 ;
585
+ }
586
+
488
587
static int do_one_pass (journal_t * journal ,
489
588
struct recovery_info * info , enum passtype pass )
490
589
{
@@ -496,9 +595,7 @@ static int do_one_pass(journal_t *journal,
496
595
struct buffer_head * bh = NULL ;
497
596
unsigned int sequence ;
498
597
int blocktype ;
499
- int tag_bytes = journal_tag_bytes (journal );
500
598
__u32 crc32_sum = ~0 ; /* Transactional Checksums */
501
- int descr_csum_size = 0 ;
502
599
int block_error = 0 ;
503
600
bool need_check_commit_time = false;
504
601
__u64 last_trans_commit_time = 0 , commit_time ;
@@ -528,12 +625,6 @@ static int do_one_pass(journal_t *journal,
528
625
*/
529
626
530
627
while (1 ) {
531
- int flags ;
532
- char * tagp ;
533
- journal_block_tag_t tag ;
534
- struct buffer_head * obh ;
535
- struct buffer_head * nbh ;
536
-
537
628
cond_resched ();
538
629
539
630
/* If we already know where to stop the log traversal,
@@ -587,11 +678,7 @@ static int do_one_pass(journal_t *journal,
587
678
switch (blocktype ) {
588
679
case JBD2_DESCRIPTOR_BLOCK :
589
680
/* Verify checksum first */
590
- if (jbd2_journal_has_csum_v2or3 (journal ))
591
- descr_csum_size =
592
- sizeof (struct jbd2_journal_block_tail );
593
- if (descr_csum_size > 0 &&
594
- !jbd2_descriptor_block_csum_verify (journal ,
681
+ if (!jbd2_descriptor_block_csum_verify (journal ,
595
682
bh -> b_data )) {
596
683
/*
597
684
* PASS_SCAN can see stale blocks due to lazy
@@ -628,102 +715,16 @@ static int do_one_pass(journal_t *journal,
628
715
continue ;
629
716
}
630
717
631
- /* A descriptor block: we can now write all of
632
- * the data blocks. Yay, useful work is finally
633
- * getting done here! */
634
-
635
- tagp = & bh -> b_data [sizeof (journal_header_t )];
636
- while ((tagp - bh -> b_data + tag_bytes )
637
- <= journal -> j_blocksize - descr_csum_size ) {
638
- unsigned long io_block ;
639
-
640
- memcpy (& tag , tagp , sizeof (tag ));
641
- flags = be16_to_cpu (tag .t_flags );
642
-
643
- io_block = next_log_block ++ ;
644
- wrap (journal , next_log_block );
645
- err = jread (& obh , journal , io_block );
646
- if (err ) {
647
- /* Recover what we can, but
648
- * report failure at the end. */
649
- success = err ;
650
- printk (KERN_ERR
651
- "JBD2: IO error %d recovering "
652
- "block %lu in log\n" ,
653
- err , io_block );
654
- } else {
655
- unsigned long long blocknr ;
656
-
657
- J_ASSERT (obh != NULL );
658
- blocknr = read_tag_block (journal ,
659
- & tag );
660
-
661
- /* If the block has been
662
- * revoked, then we're all done
663
- * here. */
664
- if (jbd2_journal_test_revoke
665
- (journal , blocknr ,
666
- next_commit_ID )) {
667
- brelse (obh );
668
- ++ info -> nr_revoke_hits ;
669
- goto skip_write ;
670
- }
671
-
672
- /* Look for block corruption */
673
- if (!jbd2_block_tag_csum_verify (
674
- journal , & tag , (journal_block_tag3_t * )tagp ,
675
- obh -> b_data , be32_to_cpu (tmp -> h_sequence ))) {
676
- brelse (obh );
677
- success = - EFSBADCRC ;
678
- printk (KERN_ERR "JBD2: Invalid "
679
- "checksum recovering "
680
- "data block %llu in "
681
- "journal block %lu\n" ,
682
- blocknr , io_block );
683
- block_error = 1 ;
684
- goto skip_write ;
685
- }
686
-
687
- /* Find a buffer for the new
688
- * data being restored */
689
- nbh = __getblk (journal -> j_fs_dev ,
690
- blocknr ,
691
- journal -> j_blocksize );
692
- if (nbh == NULL ) {
693
- printk (KERN_ERR
694
- "JBD2: Out of memory "
695
- "during recovery.\n" );
696
- err = - ENOMEM ;
697
- brelse (obh );
698
- goto failed ;
699
- }
700
-
701
- lock_buffer (nbh );
702
- memcpy (nbh -> b_data , obh -> b_data ,
703
- journal -> j_blocksize );
704
- if (flags & JBD2_FLAG_ESCAPE ) {
705
- * ((__be32 * )nbh -> b_data ) =
706
- cpu_to_be32 (JBD2_MAGIC_NUMBER );
707
- }
708
-
709
- BUFFER_TRACE (nbh , "marking dirty" );
710
- set_buffer_uptodate (nbh );
711
- mark_buffer_dirty (nbh );
712
- BUFFER_TRACE (nbh , "marking uptodate" );
713
- ++ info -> nr_replays ;
714
- unlock_buffer (nbh );
715
- brelse (obh );
716
- brelse (nbh );
717
- }
718
-
719
- skip_write :
720
- tagp += tag_bytes ;
721
- if (!(flags & JBD2_FLAG_SAME_UUID ))
722
- tagp += 16 ;
723
-
724
- if (flags & JBD2_FLAG_LAST_TAG )
725
- break ;
726
- }
718
+ /*
719
+ * A descriptor block: we can now write all of the
720
+ * data blocks. Yay, useful work is finally getting
721
+ * done here!
722
+ */
723
+ err = jbd2_do_replay (journal , info , bh , & next_log_block ,
724
+ next_commit_ID , & success ,
725
+ & block_error );
726
+ if (err )
727
+ goto failed ;
727
728
728
729
continue ;
729
730
0 commit comments