@@ -1029,6 +1029,7 @@ static int check_inode(struct btree_trans *trans,
1029
1029
bool full )
1030
1030
{
1031
1031
struct bch_fs * c = trans -> c ;
1032
+ struct printbuf buf = PRINTBUF ;
1032
1033
struct bch_inode_unpacked u ;
1033
1034
bool do_update = false;
1034
1035
int ret ;
@@ -1062,7 +1063,24 @@ static int check_inode(struct btree_trans *trans,
1062
1063
trans , inode_snapshot_mismatch ,
1063
1064
"inodes in different snapshots don't match" )) {
1064
1065
bch_err (c , "repair not implemented yet" );
1065
- return - BCH_ERR_fsck_repair_unimplemented ;
1066
+ ret = - BCH_ERR_fsck_repair_unimplemented ;
1067
+ goto err_noprint ;
1068
+ }
1069
+
1070
+ if (u .bi_dir || u .bi_dir_offset ) {
1071
+ ret = check_inode_dirent_inode (trans , & u , & do_update );
1072
+ if (ret )
1073
+ goto err ;
1074
+ }
1075
+
1076
+ if (fsck_err_on (u .bi_dir && (u .bi_flags & BCH_INODE_unlinked ),
1077
+ trans , inode_unlinked_but_has_dirent ,
1078
+ "inode unlinked but has dirent\n%s" ,
1079
+ (printbuf_reset (& buf ),
1080
+ bch2_inode_unpacked_to_text (& buf , & u ),
1081
+ buf .buf ))) {
1082
+ u .bi_flags &= ~BCH_INODE_unlinked ;
1083
+ do_update = true;
1066
1084
}
1067
1085
1068
1086
if ((u .bi_flags & (BCH_INODE_i_size_dirty |BCH_INODE_unlinked )) &&
@@ -1079,11 +1097,11 @@ static int check_inode(struct btree_trans *trans,
1079
1097
1080
1098
bch_err_msg (c , ret , "in fsck updating inode" );
1081
1099
if (ret )
1082
- return ret ;
1100
+ goto err_noprint ;
1083
1101
1084
1102
if (!bpos_eq (new_min_pos , POS_MIN ))
1085
1103
bch2_btree_iter_set_pos (iter , bpos_predecessor (new_min_pos ));
1086
- return 0 ;
1104
+ goto err_noprint ;
1087
1105
}
1088
1106
1089
1107
if (u .bi_flags & BCH_INODE_unlinked ) {
@@ -1100,7 +1118,7 @@ static int check_inode(struct btree_trans *trans,
1100
1118
*/
1101
1119
ret = check_inode_deleted_list (trans , k .k -> p );
1102
1120
if (ret < 0 )
1103
- return ret ;
1121
+ goto err_noprint ;
1104
1122
1105
1123
fsck_err_on (!ret ,
1106
1124
trans , unlinked_inode_not_on_deleted_list ,
@@ -1117,7 +1135,7 @@ static int check_inode(struct btree_trans *trans,
1117
1135
u .bi_inum , u .bi_snapshot )) {
1118
1136
ret = bch2_inode_rm_snapshot (trans , u .bi_inum , iter -> pos .snapshot );
1119
1137
bch_err_msg (c , ret , "in fsck deleting inode" );
1120
- return ret ;
1138
+ goto err_noprint ;
1121
1139
}
1122
1140
}
1123
1141
}
@@ -1182,12 +1200,6 @@ static int check_inode(struct btree_trans *trans,
1182
1200
do_update = true;
1183
1201
}
1184
1202
1185
- if (u .bi_dir || u .bi_dir_offset ) {
1186
- ret = check_inode_dirent_inode (trans , & u , & do_update );
1187
- if (ret )
1188
- goto err ;
1189
- }
1190
-
1191
1203
if (fsck_err_on (u .bi_parent_subvol &&
1192
1204
(u .bi_subvol == 0 ||
1193
1205
u .bi_subvol == BCACHEFS_ROOT_SUBVOL ),
@@ -1232,11 +1244,13 @@ static int check_inode(struct btree_trans *trans,
1232
1244
ret = __bch2_fsck_write_inode (trans , & u , iter -> pos .snapshot );
1233
1245
bch_err_msg (c , ret , "in fsck updating inode" );
1234
1246
if (ret )
1235
- return ret ;
1247
+ goto err_noprint ;
1236
1248
}
1237
1249
err :
1238
1250
fsck_err :
1239
1251
bch_err_fn (c , ret );
1252
+ err_noprint :
1253
+ printbuf_exit (& buf );
1240
1254
return ret ;
1241
1255
}
1242
1256
@@ -1831,11 +1845,22 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
1831
1845
fsck_err_on (S_ISDIR (target -> bi_mode ),
1832
1846
trans , inode_dir_missing_backpointer ,
1833
1847
"directory with missing backpointer\n%s" ,
1834
- (bch2_bkey_val_to_text (& buf , c , d .s_c ),
1835
- prt_printf (& buf , "\n " ),
1848
+ (printbuf_reset (& buf ),
1849
+ bch2_bkey_val_to_text (& buf , c , d .s_c ),
1850
+ prt_printf (& buf , "\n" ),
1836
1851
bch2_inode_unpacked_to_text (& buf , target ),
1837
1852
buf .buf ));
1838
1853
1854
+ fsck_err_on (target -> bi_flags & BCH_INODE_unlinked ,
1855
+ trans , inode_unlinked_but_has_dirent ,
1856
+ "inode unlinked but has dirent\n%s" ,
1857
+ (printbuf_reset (& buf ),
1858
+ bch2_bkey_val_to_text (& buf , c , d .s_c ),
1859
+ prt_printf (& buf , "\n" ),
1860
+ bch2_inode_unpacked_to_text (& buf , target ),
1861
+ buf .buf ));
1862
+
1863
+ target -> bi_flags &= ~BCH_INODE_unlinked ;
1839
1864
target -> bi_dir = d .k -> p .inode ;
1840
1865
target -> bi_dir_offset = d .k -> p .offset ;
1841
1866
return __bch2_fsck_write_inode (trans , target , target_snapshot );
0 commit comments