@@ -1436,6 +1436,7 @@ static int check_key_has_inode(struct btree_trans *trans,
14361436{
14371437 struct bch_fs * c = trans -> c ;
14381438 struct printbuf buf = PRINTBUF ;
1439+ struct btree_iter iter2 = {};
14391440 int ret = PTR_ERR_OR_ZERO (i );
14401441 if (ret )
14411442 return ret ;
@@ -1445,40 +1446,105 @@ static int check_key_has_inode(struct btree_trans *trans,
14451446
14461447 bool have_inode = i && !i -> whiteout ;
14471448
1448- if (!have_inode && (c -> sb .btrees_lost_data & BIT_ULL (BTREE_ID_inodes ))) {
1449- ret = reconstruct_inode (trans , iter -> btree_id , k .k -> p .snapshot , k .k -> p .inode ) ?:
1450- bch2_trans_commit (trans , NULL , NULL , BCH_TRANS_COMMIT_no_enospc );
1451- if (ret )
1452- goto err ;
1449+ if (!have_inode && (c -> sb .btrees_lost_data & BIT_ULL (BTREE_ID_inodes )))
1450+ goto reconstruct ;
14531451
1454- inode -> last_pos .inode -- ;
1455- ret = bch_err_throw (c , transaction_restart_nested );
1456- goto err ;
1452+ if (have_inode && btree_matches_i_mode (iter -> btree_id , i -> inode .bi_mode ))
1453+ goto out ;
1454+
1455+ prt_printf (& buf , ", " );
1456+
1457+ bool have_old_inode = false;
1458+ darray_for_each (inode -> inodes , i2 )
1459+ if (!i2 -> whiteout &&
1460+ bch2_snapshot_is_ancestor (c , k .k -> p .snapshot , i2 -> inode .bi_snapshot ) &&
1461+ btree_matches_i_mode (iter -> btree_id , i2 -> inode .bi_mode )) {
1462+ prt_printf (& buf , "but found good inode in older snapshot\n" );
1463+ bch2_inode_unpacked_to_text (& buf , & i2 -> inode );
1464+ prt_newline (& buf );
1465+ have_old_inode = true;
1466+ break ;
1467+ }
1468+
1469+ struct bkey_s_c k2 ;
1470+ unsigned nr_keys = 0 ;
1471+
1472+ prt_printf (& buf , "found keys:\n" );
1473+
1474+ for_each_btree_key_max_norestart (trans , iter2 , iter -> btree_id ,
1475+ SPOS (k .k -> p .inode , 0 , k .k -> p .snapshot ),
1476+ POS (k .k -> p .inode , U64_MAX ),
1477+ 0 , k2 , ret ) {
1478+ nr_keys ++ ;
1479+ if (nr_keys <= 10 ) {
1480+ bch2_bkey_val_to_text (& buf , c , k2 );
1481+ prt_newline (& buf );
1482+ }
1483+ if (nr_keys >= 100 )
1484+ break ;
14571485 }
14581486
1459- if (fsck_err_on (!have_inode ,
1460- trans , key_in_missing_inode ,
1461- "key in missing inode:\n%s" ,
1462- (printbuf_reset (& buf ),
1463- bch2_bkey_val_to_text (& buf , c , k ), buf .buf )))
1464- goto delete ;
1487+ if (ret )
1488+ goto err ;
14651489
1466- if (fsck_err_on (have_inode && !btree_matches_i_mode (iter -> btree_id , i -> inode .bi_mode ),
1467- trans , key_in_wrong_inode_type ,
1468- "key for wrong inode mode %o:\n%s" ,
1469- i -> inode .bi_mode ,
1470- (printbuf_reset (& buf ),
1471- bch2_bkey_val_to_text (& buf , c , k ), buf .buf )))
1472- goto delete ;
1490+ if (nr_keys > 100 )
1491+ prt_printf (& buf , "found > %u keys for this missing inode\n" , nr_keys );
1492+ else if (nr_keys > 10 )
1493+ prt_printf (& buf , "found %u keys for this missing inode\n" , nr_keys );
1494+
1495+ if (!have_inode ) {
1496+ if (fsck_err_on (!have_inode ,
1497+ trans , key_in_missing_inode ,
1498+ "key in missing inode%s" , buf .buf )) {
1499+ /*
1500+ * Maybe a deletion that raced with data move, or something
1501+ * weird like that? But if we know the inode was deleted, or
1502+ * it's just a few keys, we can safely delete them.
1503+ *
1504+ * If it's many keys, we should probably recreate the inode
1505+ */
1506+ if (have_old_inode || nr_keys <= 2 )
1507+ goto delete ;
1508+ else
1509+ goto reconstruct ;
1510+ }
1511+ } else {
1512+ /*
1513+ * not autofix, this one would be a giant wtf - bit error in the
1514+ * inode corrupting i_mode?
1515+ *
1516+ * may want to try repairing inode instead of deleting
1517+ */
1518+ if (fsck_err_on (!btree_matches_i_mode (iter -> btree_id , i -> inode .bi_mode ),
1519+ trans , key_in_wrong_inode_type ,
1520+ "key for wrong inode mode %o%s" ,
1521+ i -> inode .bi_mode , buf .buf ))
1522+ goto delete ;
1523+ }
14731524out :
14741525err :
14751526fsck_err :
1527+ bch2_trans_iter_exit (trans , & iter2 );
14761528 printbuf_exit (& buf );
14771529 bch_err_fn (c , ret );
14781530 return ret ;
14791531delete :
1532+ /*
1533+ * XXX: print out more info
1534+ * count up extents for this inode, check if we have different inode in
1535+ * an older snapshot version, perhaps decide if we want to reconstitute
1536+ */
14801537 ret = bch2_btree_delete_at (trans , iter , BTREE_UPDATE_internal_snapshot_node );
14811538 goto out ;
1539+ reconstruct :
1540+ ret = reconstruct_inode (trans , iter -> btree_id , k .k -> p .snapshot , k .k -> p .inode ) ?:
1541+ bch2_trans_commit (trans , NULL , NULL , BCH_TRANS_COMMIT_no_enospc );
1542+ if (ret )
1543+ goto err ;
1544+
1545+ inode -> last_pos .inode -- ;
1546+ ret = bch_err_throw (c , transaction_restart_nested );
1547+ goto out ;
14821548}
14831549
14841550static int check_i_sectors_notnested (struct btree_trans * trans , struct inode_walker * w )
0 commit comments