@@ -397,7 +397,11 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
397397 continue ;
398398 }
399399
400- ret = btree_check_node_boundaries (trans , b , prev , cur , pulled_from_scan );
400+ ret = lockrestart_do (trans ,
401+ btree_check_node_boundaries (trans , b , prev , cur , pulled_from_scan ));
402+ if (ret < 0 )
403+ goto err ;
404+
401405 if (ret == DID_FILL_FROM_SCAN ) {
402406 new_pass = true;
403407 ret = 0 ;
@@ -438,7 +442,8 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
438442
439443 if (!ret && !IS_ERR_OR_NULL (prev )) {
440444 BUG_ON (cur );
441- ret = btree_repair_node_end (trans , b , prev , pulled_from_scan );
445+ ret = lockrestart_do (trans ,
446+ btree_repair_node_end (trans , b , prev , pulled_from_scan ));
442447 if (ret == DID_FILL_FROM_SCAN ) {
443448 new_pass = true;
444449 ret = 0 ;
@@ -519,49 +524,65 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
519524 bch2_bkey_buf_exit (& prev_k , c );
520525 bch2_bkey_buf_exit (& cur_k , c );
521526 printbuf_exit (& buf );
527+ bch_err_fn (c , ret );
528+ return ret ;
529+ }
530+
531+ static int bch2_check_root (struct btree_trans * trans , enum btree_id i ,
532+ bool * reconstructed_root )
533+ {
534+ struct bch_fs * c = trans -> c ;
535+ struct btree_root * r = bch2_btree_id_root (c , i );
536+ struct printbuf buf = PRINTBUF ;
537+ int ret = 0 ;
538+
539+ bch2_btree_id_to_text (& buf , i );
540+
541+ if (r -> error ) {
542+ bch_info (c , "btree root %s unreadable, must recover from scan" , buf .buf );
543+
544+ r -> alive = false;
545+ r -> error = 0 ;
546+
547+ if (!bch2_btree_has_scanned_nodes (c , i )) {
548+ __fsck_err (trans ,
549+ FSCK_CAN_FIX |(!btree_id_important (i ) ? FSCK_AUTOFIX : 0 ),
550+ btree_root_unreadable_and_scan_found_nothing ,
551+ "no nodes found for btree %s, continue?" , buf .buf );
552+ bch2_btree_root_alloc_fake_trans (trans , i , 0 );
553+ } else {
554+ bch2_btree_root_alloc_fake_trans (trans , i , 1 );
555+ bch2_shoot_down_journal_keys (c , i , 1 , BTREE_MAX_DEPTH , POS_MIN , SPOS_MAX );
556+ ret = bch2_get_scanned_nodes (c , i , 0 , POS_MIN , SPOS_MAX );
557+ if (ret )
558+ goto err ;
559+ }
560+
561+ * reconstructed_root = true;
562+ }
563+ err :
564+ fsck_err :
565+ printbuf_exit (& buf );
566+ bch_err_fn (c , ret );
522567 return ret ;
523568}
524569
525570int bch2_check_topology (struct bch_fs * c )
526571{
527572 struct btree_trans * trans = bch2_trans_get (c );
528573 struct bpos pulled_from_scan = POS_MIN ;
529- struct printbuf buf = PRINTBUF ;
530574 int ret = 0 ;
531575
532576 bch2_trans_srcu_unlock (trans );
533577
534578 for (unsigned i = 0 ; i < btree_id_nr_alive (c ) && !ret ; i ++ ) {
535- struct btree_root * r = bch2_btree_id_root (c , i );
536579 bool reconstructed_root = false;
580+ recover :
581+ ret = lockrestart_do (trans , bch2_check_root (trans , i , & reconstructed_root ));
582+ if (ret )
583+ break ;
537584
538- printbuf_reset (& buf );
539- bch2_btree_id_to_text (& buf , i );
540-
541- if (r -> error ) {
542- reconstruct_root :
543- bch_info (c , "btree root %s unreadable, must recover from scan" , buf .buf );
544-
545- r -> alive = false;
546- r -> error = 0 ;
547-
548- if (!bch2_btree_has_scanned_nodes (c , i )) {
549- __fsck_err (trans ,
550- FSCK_CAN_FIX |(!btree_id_important (i ) ? FSCK_AUTOFIX : 0 ),
551- btree_root_unreadable_and_scan_found_nothing ,
552- "no nodes found for btree %s, continue?" , buf .buf );
553- bch2_btree_root_alloc_fake_trans (trans , i , 0 );
554- } else {
555- bch2_btree_root_alloc_fake_trans (trans , i , 1 );
556- bch2_shoot_down_journal_keys (c , i , 1 , BTREE_MAX_DEPTH , POS_MIN , SPOS_MAX );
557- ret = bch2_get_scanned_nodes (c , i , 0 , POS_MIN , SPOS_MAX );
558- if (ret )
559- break ;
560- }
561-
562- reconstructed_root = true;
563- }
564-
585+ struct btree_root * r = bch2_btree_id_root (c , i );
565586 struct btree * b = r -> b ;
566587
567588 btree_node_lock_nopath_nofail (trans , & b -> c , SIX_LOCK_read );
@@ -575,17 +596,21 @@ int bch2_check_topology(struct bch_fs *c)
575596
576597 r -> b = NULL ;
577598
578- if (!reconstructed_root )
579- goto reconstruct_root ;
599+ if (!reconstructed_root ) {
600+ r -> error = - EIO ;
601+ goto recover ;
602+ }
580603
604+ struct printbuf buf = PRINTBUF ;
605+ bch2_btree_id_to_text (& buf , i );
581606 bch_err (c , "empty btree root %s" , buf .buf );
607+ printbuf_exit (& buf );
582608 bch2_btree_root_alloc_fake_trans (trans , i , 0 );
583609 r -> alive = false;
584610 ret = 0 ;
585611 }
586612 }
587- fsck_err :
588- printbuf_exit (& buf );
613+
589614 bch2_trans_put (trans );
590615 return ret ;
591616}
0 commit comments