@@ -397,7 +397,11 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
397
397
continue ;
398
398
}
399
399
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
+
401
405
if (ret == DID_FILL_FROM_SCAN ) {
402
406
new_pass = true;
403
407
ret = 0 ;
@@ -438,7 +442,8 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
438
442
439
443
if (!ret && !IS_ERR_OR_NULL (prev )) {
440
444
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 ));
442
447
if (ret == DID_FILL_FROM_SCAN ) {
443
448
new_pass = true;
444
449
ret = 0 ;
@@ -519,49 +524,65 @@ static int bch2_btree_repair_topology_recurse(struct btree_trans *trans, struct
519
524
bch2_bkey_buf_exit (& prev_k , c );
520
525
bch2_bkey_buf_exit (& cur_k , c );
521
526
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 );
522
567
return ret ;
523
568
}
524
569
525
570
int bch2_check_topology (struct bch_fs * c )
526
571
{
527
572
struct btree_trans * trans = bch2_trans_get (c );
528
573
struct bpos pulled_from_scan = POS_MIN ;
529
- struct printbuf buf = PRINTBUF ;
530
574
int ret = 0 ;
531
575
532
576
bch2_trans_srcu_unlock (trans );
533
577
534
578
for (unsigned i = 0 ; i < btree_id_nr_alive (c ) && !ret ; i ++ ) {
535
- struct btree_root * r = bch2_btree_id_root (c , i );
536
579
bool reconstructed_root = false;
580
+ recover :
581
+ ret = lockrestart_do (trans , bch2_check_root (trans , i , & reconstructed_root ));
582
+ if (ret )
583
+ break ;
537
584
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 );
565
586
struct btree * b = r -> b ;
566
587
567
588
btree_node_lock_nopath_nofail (trans , & b -> c , SIX_LOCK_read );
@@ -575,17 +596,21 @@ int bch2_check_topology(struct bch_fs *c)
575
596
576
597
r -> b = NULL ;
577
598
578
- if (!reconstructed_root )
579
- goto reconstruct_root ;
599
+ if (!reconstructed_root ) {
600
+ r -> error = - EIO ;
601
+ goto recover ;
602
+ }
580
603
604
+ struct printbuf buf = PRINTBUF ;
605
+ bch2_btree_id_to_text (& buf , i );
581
606
bch_err (c , "empty btree root %s" , buf .buf );
607
+ printbuf_exit (& buf );
582
608
bch2_btree_root_alloc_fake_trans (trans , i , 0 );
583
609
r -> alive = false;
584
610
ret = 0 ;
585
611
}
586
612
}
587
- fsck_err :
588
- printbuf_exit (& buf );
613
+
589
614
bch2_trans_put (trans );
590
615
return ret ;
591
616
}
0 commit comments