@@ -1029,6 +1029,7 @@ static int check_inode(struct btree_trans *trans,
10291029 bool full )
10301030{
10311031 struct bch_fs * c = trans -> c ;
1032+ struct printbuf buf = PRINTBUF ;
10321033 struct bch_inode_unpacked u ;
10331034 bool do_update = false;
10341035 int ret ;
@@ -1062,7 +1063,24 @@ static int check_inode(struct btree_trans *trans,
10621063 trans , inode_snapshot_mismatch ,
10631064 "inodes in different snapshots don't match" )) {
10641065 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;
10661084 }
10671085
10681086 if ((u .bi_flags & (BCH_INODE_i_size_dirty |BCH_INODE_unlinked )) &&
@@ -1079,11 +1097,11 @@ static int check_inode(struct btree_trans *trans,
10791097
10801098 bch_err_msg (c , ret , "in fsck updating inode" );
10811099 if (ret )
1082- return ret ;
1100+ goto err_noprint ;
10831101
10841102 if (!bpos_eq (new_min_pos , POS_MIN ))
10851103 bch2_btree_iter_set_pos (iter , bpos_predecessor (new_min_pos ));
1086- return 0 ;
1104+ goto err_noprint ;
10871105 }
10881106
10891107 if (u .bi_flags & BCH_INODE_unlinked ) {
@@ -1100,7 +1118,7 @@ static int check_inode(struct btree_trans *trans,
11001118 */
11011119 ret = check_inode_deleted_list (trans , k .k -> p );
11021120 if (ret < 0 )
1103- return ret ;
1121+ goto err_noprint ;
11041122
11051123 fsck_err_on (!ret ,
11061124 trans , unlinked_inode_not_on_deleted_list ,
@@ -1117,7 +1135,7 @@ static int check_inode(struct btree_trans *trans,
11171135 u .bi_inum , u .bi_snapshot )) {
11181136 ret = bch2_inode_rm_snapshot (trans , u .bi_inum , iter -> pos .snapshot );
11191137 bch_err_msg (c , ret , "in fsck deleting inode" );
1120- return ret ;
1138+ goto err_noprint ;
11211139 }
11221140 }
11231141 }
@@ -1182,12 +1200,6 @@ static int check_inode(struct btree_trans *trans,
11821200 do_update = true;
11831201 }
11841202
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-
11911203 if (fsck_err_on (u .bi_parent_subvol &&
11921204 (u .bi_subvol == 0 ||
11931205 u .bi_subvol == BCACHEFS_ROOT_SUBVOL ),
@@ -1232,11 +1244,13 @@ static int check_inode(struct btree_trans *trans,
12321244 ret = __bch2_fsck_write_inode (trans , & u , iter -> pos .snapshot );
12331245 bch_err_msg (c , ret , "in fsck updating inode" );
12341246 if (ret )
1235- return ret ;
1247+ goto err_noprint ;
12361248 }
12371249err :
12381250fsck_err :
12391251 bch_err_fn (c , ret );
1252+ err_noprint :
1253+ printbuf_exit (& buf );
12401254 return ret ;
12411255}
12421256
@@ -1831,11 +1845,22 @@ static int check_dirent_inode_dirent(struct btree_trans *trans,
18311845 fsck_err_on (S_ISDIR (target -> bi_mode ),
18321846 trans , inode_dir_missing_backpointer ,
18331847 "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" ),
18361851 bch2_inode_unpacked_to_text (& buf , target ),
18371852 buf .buf ));
18381853
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 ;
18391864 target -> bi_dir = d .k -> p .inode ;
18401865 target -> bi_dir_offset = d .k -> p .offset ;
18411866 return __bch2_fsck_write_inode (trans , target , target_snapshot );
0 commit comments