@@ -960,35 +960,34 @@ static struct bkey_s_c bch2_get_key_or_hole(struct btree_iter *iter, struct bpos
960960 }
961961}
962962
963- static bool next_bucket (struct bch_fs * c , struct bpos * bucket )
963+ static bool next_bucket (struct bch_fs * c , struct bch_dev * * ca , struct bpos * bucket )
964964{
965- struct bch_dev * ca ;
966-
967- if (bch2_dev_bucket_exists (c , * bucket ))
968- return true;
965+ if (* ca ) {
966+ if (bucket -> offset < (* ca )-> mi .first_bucket )
967+ bucket -> offset = (* ca )-> mi .first_bucket ;
969968
970- if (bch2_dev_exists (c , bucket -> inode )) {
971- ca = bch2_dev_bkey_exists (c , bucket -> inode );
972-
973- if (bucket -> offset < ca -> mi .first_bucket ) {
974- bucket -> offset = ca -> mi .first_bucket ;
969+ if (bucket -> offset < (* ca )-> mi .nbuckets )
975970 return true;
976- }
977971
972+ bch2_dev_put (* ca );
973+ * ca = NULL ;
978974 bucket -> inode ++ ;
979975 bucket -> offset = 0 ;
980976 }
981977
982978 rcu_read_lock ();
983- ca = __bch2_next_dev_idx (c , bucket -> inode , NULL );
984- if (ca )
985- * bucket = POS (ca -> dev_idx , ca -> mi .first_bucket );
979+ * ca = __bch2_next_dev_idx (c , bucket -> inode , NULL );
980+ if (* ca ) {
981+ * bucket = POS ((* ca )-> dev_idx , (* ca )-> mi .first_bucket );
982+ bch2_dev_get (* ca );
983+ }
986984 rcu_read_unlock ();
987985
988- return ca != NULL ;
986+ return * ca != NULL ;
989987}
990988
991- static struct bkey_s_c bch2_get_key_or_real_bucket_hole (struct btree_iter * iter , struct bkey * hole )
989+ static struct bkey_s_c bch2_get_key_or_real_bucket_hole (struct btree_iter * iter ,
990+ struct bch_dev * * ca , struct bkey * hole )
992991{
993992 struct bch_fs * c = iter -> trans -> c ;
994993 struct bkey_s_c k ;
@@ -997,22 +996,21 @@ static struct bkey_s_c bch2_get_key_or_real_bucket_hole(struct btree_iter *iter,
997996 if (bkey_err (k ))
998997 return k ;
999998
999+ * ca = bch2_dev_iterate_noerror (c , * ca , k .k -> p .inode );
1000+
10001001 if (!k .k -> type ) {
1001- struct bpos bucket = bkey_start_pos (k .k );
1002+ struct bpos hole_start = bkey_start_pos (k .k );
10021003
1003- if (!bch2_dev_bucket_exists ( c , bucket )) {
1004- if (!next_bucket (c , & bucket ))
1004+ if (!* ca || ! bucket_valid ( * ca , hole_start . offset )) {
1005+ if (!next_bucket (c , ca , & hole_start ))
10051006 return bkey_s_c_null ;
10061007
1007- bch2_btree_iter_set_pos (iter , bucket );
1008+ bch2_btree_iter_set_pos (iter , hole_start );
10081009 goto again ;
10091010 }
10101011
1011- if (!bch2_dev_bucket_exists (c , k .k -> p )) {
1012- struct bch_dev * ca = bch2_dev_bkey_exists (c , bucket .inode );
1013-
1014- bch2_key_resize (hole , ca -> mi .nbuckets - bucket .offset );
1015- }
1012+ if (k .k -> p .offset > (* ca )-> mi .nbuckets )
1013+ bch2_key_resize (hole , (* ca )-> mi .nbuckets - hole_start .offset );
10161014 }
10171015
10181016 return k ;
@@ -1154,17 +1152,16 @@ int bch2_check_alloc_key(struct btree_trans *trans,
11541152
11551153static noinline_for_stack
11561154int bch2_check_alloc_hole_freespace (struct btree_trans * trans ,
1155+ struct bch_dev * ca ,
11571156 struct bpos start ,
11581157 struct bpos * end ,
11591158 struct btree_iter * freespace_iter )
11601159{
11611160 struct bch_fs * c = trans -> c ;
1162- struct bch_dev * ca ;
11631161 struct bkey_s_c k ;
11641162 struct printbuf buf = PRINTBUF ;
11651163 int ret ;
11661164
1167- ca = bch2_dev_bkey_exists (c , start .inode );
11681165 if (!ca -> mi .freespace_initialized )
11691166 return 0 ;
11701167
@@ -1342,30 +1339,25 @@ int bch2_check_bucket_gens_key(struct btree_trans *trans,
13421339{
13431340 struct bch_fs * c = trans -> c ;
13441341 struct bkey_i_bucket_gens g ;
1345- struct bch_dev * ca ;
13461342 u64 start = bucket_gens_pos_to_alloc (k .k -> p , 0 ).offset ;
13471343 u64 end = bucket_gens_pos_to_alloc (bpos_nosnap_successor (k .k -> p ), 0 ).offset ;
13481344 u64 b ;
1349- bool need_update = false, dev_exists ;
1345+ bool need_update = false;
13501346 struct printbuf buf = PRINTBUF ;
13511347 int ret = 0 ;
13521348
13531349 BUG_ON (k .k -> type != KEY_TYPE_bucket_gens );
13541350 bkey_reassemble (& g .k_i , k );
13551351
1356- /* if no bch_dev, skip out whether we repair or not */
1357- dev_exists = bch2_dev_exists (c , k .k -> p .inode );
1358- if (!dev_exists ) {
1359- if (fsck_err_on (!dev_exists , c ,
1360- bucket_gens_to_invalid_dev ,
1361- "bucket_gens key for invalid device:\n %s" ,
1362- (bch2_bkey_val_to_text (& buf , c , k ), buf .buf ))) {
1352+ struct bch_dev * ca = bch2_dev_tryget_noerror (c , k .k -> p .inode );
1353+ if (!ca ) {
1354+ if (fsck_err (c , bucket_gens_to_invalid_dev ,
1355+ "bucket_gens key for invalid device:\n %s" ,
1356+ (bch2_bkey_val_to_text (& buf , c , k ), buf .buf )))
13631357 ret = bch2_btree_delete_at (trans , iter , 0 );
1364- }
13651358 goto out ;
13661359 }
13671360
1368- ca = bch2_dev_bkey_exists (c , k .k -> p .inode );
13691361 if (fsck_err_on (end <= ca -> mi .first_bucket ||
13701362 start >= ca -> mi .nbuckets , c ,
13711363 bucket_gens_to_invalid_buckets ,
@@ -1403,6 +1395,7 @@ int bch2_check_bucket_gens_key(struct btree_trans *trans,
14031395 }
14041396out :
14051397fsck_err :
1398+ bch2_dev_put (ca );
14061399 printbuf_exit (& buf );
14071400 return ret ;
14081401}
@@ -1411,6 +1404,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
14111404{
14121405 struct btree_trans * trans = bch2_trans_get (c );
14131406 struct btree_iter iter , discard_iter , freespace_iter , bucket_gens_iter ;
1407+ struct bch_dev * ca = NULL ;
14141408 struct bkey hole ;
14151409 struct bkey_s_c k ;
14161410 int ret = 0 ;
@@ -1429,7 +1423,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
14291423
14301424 bch2_trans_begin (trans );
14311425
1432- k = bch2_get_key_or_real_bucket_hole (& iter , & hole );
1426+ k = bch2_get_key_or_real_bucket_hole (& iter , & ca , & hole );
14331427 ret = bkey_err (k );
14341428 if (ret )
14351429 goto bkey_err ;
@@ -1450,7 +1444,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
14501444 } else {
14511445 next = k .k -> p ;
14521446
1453- ret = bch2_check_alloc_hole_freespace (trans ,
1447+ ret = bch2_check_alloc_hole_freespace (trans , ca ,
14541448 bkey_start_pos (k .k ),
14551449 & next ,
14561450 & freespace_iter ) ?:
@@ -1478,6 +1472,8 @@ int bch2_check_alloc_info(struct bch_fs *c)
14781472 bch2_trans_iter_exit (trans , & freespace_iter );
14791473 bch2_trans_iter_exit (trans , & discard_iter );
14801474 bch2_trans_iter_exit (trans , & iter );
1475+ bch2_dev_put (ca );
1476+ ca = NULL ;
14811477
14821478 if (ret < 0 )
14831479 goto err ;
0 commit comments