@@ -1096,10 +1096,36 @@ static int check_inode_dirent_inode(struct btree_trans *trans,
1096
1096
return ret ;
1097
1097
}
1098
1098
1099
+ static int get_snapshot_root_inode (struct btree_trans * trans ,
1100
+ struct bch_inode_unpacked * root ,
1101
+ u64 inum )
1102
+ {
1103
+ struct btree_iter iter ;
1104
+ struct bkey_s_c k ;
1105
+ int ret = 0 ;
1106
+
1107
+ for_each_btree_key_reverse_norestart (trans , iter , BTREE_ID_inodes ,
1108
+ SPOS (0 , inum , U32_MAX ),
1109
+ BTREE_ITER_all_snapshots , k , ret ) {
1110
+ if (k .k -> p .offset != inum )
1111
+ break ;
1112
+ if (bkey_is_inode (k .k ))
1113
+ goto found_root ;
1114
+ }
1115
+ if (ret )
1116
+ goto err ;
1117
+ BUG ();
1118
+ found_root :
1119
+ BUG_ON (bch2_inode_unpack (k , root ));
1120
+ err :
1121
+ bch2_trans_iter_exit (trans , & iter );
1122
+ return ret ;
1123
+ }
1124
+
1099
1125
static int check_inode (struct btree_trans * trans ,
1100
1126
struct btree_iter * iter ,
1101
1127
struct bkey_s_c k ,
1102
- struct bch_inode_unpacked * prev ,
1128
+ struct bch_inode_unpacked * snapshot_root ,
1103
1129
struct snapshots_seen * s )
1104
1130
{
1105
1131
struct bch_fs * c = trans -> c ;
@@ -1123,16 +1149,19 @@ static int check_inode(struct btree_trans *trans,
1123
1149
1124
1150
BUG_ON (bch2_inode_unpack (k , & u ));
1125
1151
1126
- if (prev -> bi_inum != u .bi_inum )
1127
- * prev = u ;
1152
+ if (snapshot_root -> bi_inum != u .bi_inum ) {
1153
+ ret = get_snapshot_root_inode (trans , snapshot_root , u .bi_inum );
1154
+ if (ret )
1155
+ goto err ;
1156
+ }
1128
1157
1129
- if (fsck_err_on (prev -> bi_hash_seed != u . bi_hash_seed ||
1130
- inode_d_type ( prev ) != inode_d_type ( & u ),
1158
+ if (fsck_err_on (u . bi_hash_seed != snapshot_root -> bi_hash_seed ||
1159
+ INODE_STR_HASH ( & u ) != INODE_STR_HASH ( snapshot_root ),
1131
1160
trans , inode_snapshot_mismatch ,
1132
1161
"inodes in different snapshots don't match" )) {
1133
- bch_err ( c , "repair not implemented yet" ) ;
1134
- ret = - BCH_ERR_fsck_repair_unimplemented ;
1135
- goto err_noprint ;
1162
+ u . bi_hash_seed = snapshot_root -> bi_hash_seed ;
1163
+ SET_INODE_STR_HASH ( & u , INODE_STR_HASH ( snapshot_root )) ;
1164
+ do_update = true ;
1136
1165
}
1137
1166
1138
1167
if (u .bi_dir || u .bi_dir_offset ) {
@@ -1285,7 +1314,7 @@ static int check_inode(struct btree_trans *trans,
1285
1314
1286
1315
int bch2_check_inodes (struct bch_fs * c )
1287
1316
{
1288
- struct bch_inode_unpacked prev = { 0 };
1317
+ struct bch_inode_unpacked snapshot_root = {};
1289
1318
struct snapshots_seen s ;
1290
1319
1291
1320
snapshots_seen_init (& s );
@@ -1295,7 +1324,7 @@ int bch2_check_inodes(struct bch_fs *c)
1295
1324
POS_MIN ,
1296
1325
BTREE_ITER_prefetch |BTREE_ITER_all_snapshots , k ,
1297
1326
NULL , NULL , BCH_TRANS_COMMIT_no_enospc ,
1298
- check_inode (trans , & iter , k , & prev , & s )));
1327
+ check_inode (trans , & iter , k , & snapshot_root , & s )));
1299
1328
1300
1329
snapshots_seen_exit (& s );
1301
1330
bch_err_fn (c , ret );
0 commit comments