@@ -960,35 +960,34 @@ static struct bkey_s_c bch2_get_key_or_hole(struct btree_iter *iter, struct bpos
960
960
}
961
961
}
962
962
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 )
964
964
{
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 ;
969
968
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 )
975
970
return true;
976
- }
977
971
972
+ bch2_dev_put (* ca );
973
+ * ca = NULL ;
978
974
bucket -> inode ++ ;
979
975
bucket -> offset = 0 ;
980
976
}
981
977
982
978
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
+ }
986
984
rcu_read_unlock ();
987
985
988
- return ca != NULL ;
986
+ return * ca != NULL ;
989
987
}
990
988
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 )
992
991
{
993
992
struct bch_fs * c = iter -> trans -> c ;
994
993
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,
997
996
if (bkey_err (k ))
998
997
return k ;
999
998
999
+ * ca = bch2_dev_iterate_noerror (c , * ca , k .k -> p .inode );
1000
+
1000
1001
if (!k .k -> type ) {
1001
- struct bpos bucket = bkey_start_pos (k .k );
1002
+ struct bpos hole_start = bkey_start_pos (k .k );
1002
1003
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 ))
1005
1006
return bkey_s_c_null ;
1006
1007
1007
- bch2_btree_iter_set_pos (iter , bucket );
1008
+ bch2_btree_iter_set_pos (iter , hole_start );
1008
1009
goto again ;
1009
1010
}
1010
1011
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 );
1016
1014
}
1017
1015
1018
1016
return k ;
@@ -1154,17 +1152,16 @@ int bch2_check_alloc_key(struct btree_trans *trans,
1154
1152
1155
1153
static noinline_for_stack
1156
1154
int bch2_check_alloc_hole_freespace (struct btree_trans * trans ,
1155
+ struct bch_dev * ca ,
1157
1156
struct bpos start ,
1158
1157
struct bpos * end ,
1159
1158
struct btree_iter * freespace_iter )
1160
1159
{
1161
1160
struct bch_fs * c = trans -> c ;
1162
- struct bch_dev * ca ;
1163
1161
struct bkey_s_c k ;
1164
1162
struct printbuf buf = PRINTBUF ;
1165
1163
int ret ;
1166
1164
1167
- ca = bch2_dev_bkey_exists (c , start .inode );
1168
1165
if (!ca -> mi .freespace_initialized )
1169
1166
return 0 ;
1170
1167
@@ -1342,30 +1339,25 @@ int bch2_check_bucket_gens_key(struct btree_trans *trans,
1342
1339
{
1343
1340
struct bch_fs * c = trans -> c ;
1344
1341
struct bkey_i_bucket_gens g ;
1345
- struct bch_dev * ca ;
1346
1342
u64 start = bucket_gens_pos_to_alloc (k .k -> p , 0 ).offset ;
1347
1343
u64 end = bucket_gens_pos_to_alloc (bpos_nosnap_successor (k .k -> p ), 0 ).offset ;
1348
1344
u64 b ;
1349
- bool need_update = false, dev_exists ;
1345
+ bool need_update = false;
1350
1346
struct printbuf buf = PRINTBUF ;
1351
1347
int ret = 0 ;
1352
1348
1353
1349
BUG_ON (k .k -> type != KEY_TYPE_bucket_gens );
1354
1350
bkey_reassemble (& g .k_i , k );
1355
1351
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 )))
1363
1357
ret = bch2_btree_delete_at (trans , iter , 0 );
1364
- }
1365
1358
goto out ;
1366
1359
}
1367
1360
1368
- ca = bch2_dev_bkey_exists (c , k .k -> p .inode );
1369
1361
if (fsck_err_on (end <= ca -> mi .first_bucket ||
1370
1362
start >= ca -> mi .nbuckets , c ,
1371
1363
bucket_gens_to_invalid_buckets ,
@@ -1403,6 +1395,7 @@ int bch2_check_bucket_gens_key(struct btree_trans *trans,
1403
1395
}
1404
1396
out :
1405
1397
fsck_err :
1398
+ bch2_dev_put (ca );
1406
1399
printbuf_exit (& buf );
1407
1400
return ret ;
1408
1401
}
@@ -1411,6 +1404,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
1411
1404
{
1412
1405
struct btree_trans * trans = bch2_trans_get (c );
1413
1406
struct btree_iter iter , discard_iter , freespace_iter , bucket_gens_iter ;
1407
+ struct bch_dev * ca = NULL ;
1414
1408
struct bkey hole ;
1415
1409
struct bkey_s_c k ;
1416
1410
int ret = 0 ;
@@ -1429,7 +1423,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
1429
1423
1430
1424
bch2_trans_begin (trans );
1431
1425
1432
- k = bch2_get_key_or_real_bucket_hole (& iter , & hole );
1426
+ k = bch2_get_key_or_real_bucket_hole (& iter , & ca , & hole );
1433
1427
ret = bkey_err (k );
1434
1428
if (ret )
1435
1429
goto bkey_err ;
@@ -1450,7 +1444,7 @@ int bch2_check_alloc_info(struct bch_fs *c)
1450
1444
} else {
1451
1445
next = k .k -> p ;
1452
1446
1453
- ret = bch2_check_alloc_hole_freespace (trans ,
1447
+ ret = bch2_check_alloc_hole_freespace (trans , ca ,
1454
1448
bkey_start_pos (k .k ),
1455
1449
& next ,
1456
1450
& freespace_iter ) ?:
@@ -1478,6 +1472,8 @@ int bch2_check_alloc_info(struct bch_fs *c)
1478
1472
bch2_trans_iter_exit (trans , & freespace_iter );
1479
1473
bch2_trans_iter_exit (trans , & discard_iter );
1480
1474
bch2_trans_iter_exit (trans , & iter );
1475
+ bch2_dev_put (ca );
1476
+ ca = NULL ;
1481
1477
1482
1478
if (ret < 0 )
1483
1479
goto err ;
0 commit comments