@@ -485,6 +485,105 @@ static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag,
485485 return tag -> t_checksum == cpu_to_be16 (csum32 );
486486}
487487
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+
488587static int do_one_pass (journal_t * journal ,
489588 struct recovery_info * info , enum passtype pass )
490589{
@@ -496,9 +595,7 @@ static int do_one_pass(journal_t *journal,
496595 struct buffer_head * bh = NULL ;
497596 unsigned int sequence ;
498597 int blocktype ;
499- int tag_bytes = journal_tag_bytes (journal );
500598 __u32 crc32_sum = ~0 ; /* Transactional Checksums */
501- int descr_csum_size = 0 ;
502599 int block_error = 0 ;
503600 bool need_check_commit_time = false;
504601 __u64 last_trans_commit_time = 0 , commit_time ;
@@ -528,12 +625,6 @@ static int do_one_pass(journal_t *journal,
528625 */
529626
530627 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-
537628 cond_resched ();
538629
539630 /* If we already know where to stop the log traversal,
@@ -587,11 +678,7 @@ static int do_one_pass(journal_t *journal,
587678 switch (blocktype ) {
588679 case JBD2_DESCRIPTOR_BLOCK :
589680 /* 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 ,
595682 bh -> b_data )) {
596683 /*
597684 * PASS_SCAN can see stale blocks due to lazy
@@ -628,102 +715,16 @@ static int do_one_pass(journal_t *journal,
628715 continue ;
629716 }
630717
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 ;
727728
728729 continue ;
729730
0 commit comments