@@ -479,8 +479,20 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
479
479
480
480
percpu_down_read (& c -> mark_lock );
481
481
482
+ rcu_read_lock ();
482
483
bkey_for_each_ptr_decode (k .k , ptrs_c , p , entry_c ) {
483
- struct bch_dev * ca = bch2_dev_bkey_exists (c , p .ptr .dev );
484
+ struct bch_dev * ca = bch2_dev_rcu (c , p .ptr .dev );
485
+ if (!ca ) {
486
+ if (fsck_err (c , ptr_to_invalid_device ,
487
+ "pointer to missing device %u\n"
488
+ "while marking %s" ,
489
+ p .ptr .dev ,
490
+ (printbuf_reset (& buf ),
491
+ bch2_bkey_val_to_text (& buf , c , k ), buf .buf )))
492
+ do_update = true;
493
+ continue ;
494
+ }
495
+
484
496
struct bucket * g = PTR_GC_BUCKET (ca , & p .ptr );
485
497
enum bch_data_type data_type = bch2_bkey_ptr_data_type (k , p , entry_c );
486
498
@@ -590,6 +602,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
590
602
do_update = true;
591
603
}
592
604
}
605
+ rcu_read_unlock ();
593
606
594
607
if (do_update ) {
595
608
if (flags & BTREE_TRIGGER_is_root ) {
@@ -603,26 +616,33 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
603
616
if (ret )
604
617
goto err ;
605
618
619
+ rcu_read_lock ();
620
+ bch2_bkey_drop_ptrs (bkey_i_to_s (new ), ptr , !bch2_dev_rcu (c , ptr -> dev ));
621
+ rcu_read_unlock ();
622
+
606
623
if (level ) {
607
624
/*
608
625
* We don't want to drop btree node pointers - if the
609
626
* btree node isn't there anymore, the read path will
610
627
* sort it out:
611
628
*/
612
629
struct bkey_ptrs ptrs = bch2_bkey_ptrs (bkey_i_to_s (new ));
630
+ rcu_read_lock ();
613
631
bkey_for_each_ptr (ptrs , ptr ) {
614
- struct bch_dev * ca = bch2_dev_bkey_exists (c , ptr -> dev );
632
+ struct bch_dev * ca = bch2_dev_rcu (c , ptr -> dev );
615
633
struct bucket * g = PTR_GC_BUCKET (ca , ptr );
616
634
617
635
ptr -> gen = g -> gen ;
618
636
}
637
+ rcu_read_unlock ();
619
638
} else {
620
639
struct bkey_ptrs ptrs ;
621
640
union bch_extent_entry * entry ;
622
641
restart_drop_ptrs :
623
642
ptrs = bch2_bkey_ptrs (bkey_i_to_s (new ));
643
+ rcu_read_lock ();
624
644
bkey_for_each_ptr_decode (bkey_i_to_s (new ).k , ptrs , p , entry ) {
625
- struct bch_dev * ca = bch2_dev_bkey_exists (c , p .ptr .dev );
645
+ struct bch_dev * ca = bch2_dev_rcu (c , p .ptr .dev );
626
646
struct bucket * g = PTR_GC_BUCKET (ca , & p .ptr );
627
647
enum bch_data_type data_type = bch2_bkey_ptr_data_type (bkey_i_to_s_c (new ), p , entry );
628
648
@@ -637,6 +657,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
637
657
goto restart_drop_ptrs ;
638
658
}
639
659
}
660
+ rcu_read_unlock ();
640
661
again :
641
662
ptrs = bch2_bkey_ptrs (bkey_i_to_s (new ));
642
663
bkey_extent_entry_for_each (ptrs , entry ) {
0 commit comments