@@ -479,8 +479,20 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
479479
480480 percpu_down_read (& c -> mark_lock );
481481
482+ rcu_read_lock ();
482483 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+
484496 struct bucket * g = PTR_GC_BUCKET (ca , & p .ptr );
485497 enum bch_data_type data_type = bch2_bkey_ptr_data_type (k , p , entry_c );
486498
@@ -590,6 +602,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
590602 do_update = true;
591603 }
592604 }
605+ rcu_read_unlock ();
593606
594607 if (do_update ) {
595608 if (flags & BTREE_TRIGGER_is_root ) {
@@ -603,26 +616,33 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
603616 if (ret )
604617 goto err ;
605618
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+
606623 if (level ) {
607624 /*
608625 * We don't want to drop btree node pointers - if the
609626 * btree node isn't there anymore, the read path will
610627 * sort it out:
611628 */
612629 struct bkey_ptrs ptrs = bch2_bkey_ptrs (bkey_i_to_s (new ));
630+ rcu_read_lock ();
613631 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 );
615633 struct bucket * g = PTR_GC_BUCKET (ca , ptr );
616634
617635 ptr -> gen = g -> gen ;
618636 }
637+ rcu_read_unlock ();
619638 } else {
620639 struct bkey_ptrs ptrs ;
621640 union bch_extent_entry * entry ;
622641restart_drop_ptrs :
623642 ptrs = bch2_bkey_ptrs (bkey_i_to_s (new ));
643+ rcu_read_lock ();
624644 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 );
626646 struct bucket * g = PTR_GC_BUCKET (ca , & p .ptr );
627647 enum bch_data_type data_type = bch2_bkey_ptr_data_type (bkey_i_to_s_c (new ), p , entry );
628648
@@ -637,6 +657,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
637657 goto restart_drop_ptrs ;
638658 }
639659 }
660+ rcu_read_unlock ();
640661again :
641662 ptrs = bch2_bkey_ptrs (bkey_i_to_s (new ));
642663 bkey_extent_entry_for_each (ptrs , entry ) {
0 commit comments