@@ -1096,10 +1096,36 @@ static int check_inode_dirent_inode(struct btree_trans *trans,
10961096 return ret ;
10971097}
10981098
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+
10991125static int check_inode (struct btree_trans * trans ,
11001126 struct btree_iter * iter ,
11011127 struct bkey_s_c k ,
1102- struct bch_inode_unpacked * prev ,
1128+ struct bch_inode_unpacked * snapshot_root ,
11031129 struct snapshots_seen * s )
11041130{
11051131 struct bch_fs * c = trans -> c ;
@@ -1123,16 +1149,19 @@ static int check_inode(struct btree_trans *trans,
11231149
11241150 BUG_ON (bch2_inode_unpack (k , & u ));
11251151
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+ }
11281157
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 ),
11311160 trans , inode_snapshot_mismatch ,
11321161 "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 ;
11361165 }
11371166
11381167 if (u .bi_dir || u .bi_dir_offset ) {
@@ -1285,7 +1314,7 @@ static int check_inode(struct btree_trans *trans,
12851314
12861315int bch2_check_inodes (struct bch_fs * c )
12871316{
1288- struct bch_inode_unpacked prev = { 0 };
1317+ struct bch_inode_unpacked snapshot_root = {};
12891318 struct snapshots_seen s ;
12901319
12911320 snapshots_seen_init (& s );
@@ -1295,7 +1324,7 @@ int bch2_check_inodes(struct bch_fs *c)
12951324 POS_MIN ,
12961325 BTREE_ITER_prefetch |BTREE_ITER_all_snapshots , k ,
12971326 NULL , NULL , BCH_TRANS_COMMIT_no_enospc ,
1298- check_inode (trans , & iter , k , & prev , & s )));
1327+ check_inode (trans , & iter , k , & snapshot_root , & s )));
12991328
13001329 snapshots_seen_exit (& s );
13011330 bch_err_fn (c , ret );
0 commit comments