@@ -993,19 +993,25 @@ static int bch2_gc_alloc_start(struct bch_fs *c)
993993 rcu_assign_pointer (ca -> buckets_gc , buckets );
994994 }
995995
996+ struct bch_dev * ca = NULL ;
996997 int ret = bch2_trans_run (c ,
997998 for_each_btree_key (trans , iter , BTREE_ID_alloc , POS_MIN ,
998999 BTREE_ITER_prefetch , k , ({
999- struct bch_dev * ca = bch2_dev_bkey_exists (c , k .k -> p .inode );
1000- struct bucket * g = gc_bucket (ca , k .k -> p .offset );
1000+ ca = bch2_dev_iterate (c , ca , k .k -> p .inode );
1001+ if (!ca ) {
1002+ bch2_btree_iter_set_pos (& iter , POS (k .k -> p .inode + 1 , 0 ));
1003+ continue ;
1004+ }
10011005
10021006 struct bch_alloc_v4 a_convert ;
10031007 const struct bch_alloc_v4 * a = bch2_alloc_to_v4 (k , & a_convert );
10041008
1009+ struct bucket * g = gc_bucket (ca , k .k -> p .offset );
10051010 g -> gen_valid = 1 ;
10061011 g -> gen = a -> gen ;
10071012 0 ;
10081013 })));
1014+ bch2_dev_put (ca );
10091015 bch_err_fn (c , ret );
10101016 return ret ;
10111017}
@@ -1254,22 +1260,29 @@ static int gc_btree_gens_key(struct btree_trans *trans,
12541260 return - EROFS ;
12551261
12561262 percpu_down_read (& c -> mark_lock );
1263+ rcu_read_lock ();
12571264 bkey_for_each_ptr (ptrs , ptr ) {
1258- struct bch_dev * ca = bch2_dev_bkey_exists (c , ptr -> dev );
1265+ struct bch_dev * ca = bch2_dev_rcu (c , ptr -> dev );
1266+ if (!ca )
1267+ continue ;
12591268
12601269 if (dev_ptr_stale (ca , ptr ) > 16 ) {
1270+ rcu_read_unlock ();
12611271 percpu_up_read (& c -> mark_lock );
12621272 goto update ;
12631273 }
12641274 }
12651275
12661276 bkey_for_each_ptr (ptrs , ptr ) {
1267- struct bch_dev * ca = bch2_dev_bkey_exists (c , ptr -> dev );
1268- u8 * gen = & ca -> oldest_gen [PTR_BUCKET_NR (ca , ptr )];
1277+ struct bch_dev * ca = bch2_dev_rcu (c , ptr -> dev );
1278+ if (!ca )
1279+ continue ;
12691280
1281+ u8 * gen = & ca -> oldest_gen [PTR_BUCKET_NR (ca , ptr )];
12701282 if (gen_after (* gen , ptr -> gen ))
12711283 * gen = ptr -> gen ;
12721284 }
1285+ rcu_read_unlock ();
12731286 percpu_up_read (& c -> mark_lock );
12741287 return 0 ;
12751288update :
@@ -1282,10 +1295,9 @@ static int gc_btree_gens_key(struct btree_trans *trans,
12821295 return 0 ;
12831296}
12841297
1285- static int bch2_alloc_write_oldest_gen (struct btree_trans * trans , struct btree_iter * iter ,
1286- struct bkey_s_c k )
1298+ static int bch2_alloc_write_oldest_gen (struct btree_trans * trans , struct bch_dev * ca ,
1299+ struct btree_iter * iter , struct bkey_s_c k )
12871300{
1288- struct bch_dev * ca = bch2_dev_bkey_exists (trans -> c , iter -> pos .inode );
12891301 struct bch_alloc_v4 a_convert ;
12901302 const struct bch_alloc_v4 * a = bch2_alloc_to_v4 (k , & a_convert );
12911303 struct bkey_i_alloc_v4 * a_mut ;
@@ -1355,14 +1367,23 @@ int bch2_gc_gens(struct bch_fs *c)
13551367 goto err ;
13561368 }
13571369
1370+ struct bch_dev * ca = NULL ;
13581371 ret = bch2_trans_run (c ,
13591372 for_each_btree_key_commit (trans , iter , BTREE_ID_alloc ,
13601373 POS_MIN ,
13611374 BTREE_ITER_prefetch ,
13621375 k ,
13631376 NULL , NULL ,
1364- BCH_TRANS_COMMIT_no_enospc ,
1365- bch2_alloc_write_oldest_gen (trans , & iter , k )));
1377+ BCH_TRANS_COMMIT_no_enospc , ({
1378+ ca = bch2_dev_iterate (c , ca , k .k -> p .inode );
1379+ if (!ca ) {
1380+ bch2_btree_iter_set_pos (& iter , POS (k .k -> p .inode + 1 , 0 ));
1381+ continue ;
1382+ }
1383+ bch2_alloc_write_oldest_gen (trans , ca , & iter , k );
1384+ })));
1385+ bch2_dev_put (ca );
1386+
13661387 if (ret )
13671388 goto err ;
13681389
0 commit comments