Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcachefs: Improved backpointer messages in fsck

When we have a key to print, we should print it.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+22 -28
+22 -28
fs/bcachefs/fsck.c
··· 1023 1023 : le64_to_cpu(d.v->d_inum) == inode->bi_inum; 1024 1024 } 1025 1025 1026 - static int inode_backpointer_exists(struct btree_trans *trans, 1027 - struct bch_inode_unpacked *inode, 1028 - u32 snapshot) 1029 - { 1030 - struct btree_iter iter; 1031 - struct bkey_s_c_dirent d; 1032 - int ret; 1033 - 1034 - d = dirent_get_by_pos(trans, &iter, 1035 - SPOS(inode->bi_dir, inode->bi_dir_offset, snapshot)); 1036 - ret = bkey_err(d); 1037 - if (ret) 1038 - return bch2_err_matches(ret, ENOENT) ? 0 : ret; 1039 - 1040 - ret = dirent_points_to_inode(d, inode); 1041 - bch2_trans_iter_exit(trans, &iter); 1042 - return ret; 1043 - } 1044 - 1045 1026 static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w) 1046 1027 { 1047 1028 struct bch_fs *c = trans->c; ··· 1534 1553 { 1535 1554 struct bch_fs *c = trans->c; 1536 1555 struct bkey_i_dirent *n; 1537 - bool backpointer_exists = true; 1538 1556 struct printbuf buf = PRINTBUF; 1557 + struct btree_iter bp_iter = { NULL }; 1539 1558 int ret = 0; 1540 1559 1541 1560 if (!target->bi_dir && ··· 1549 1568 } 1550 1569 1551 1570 if (!inode_points_to_dirent(target, d)) { 1552 - ret = inode_backpointer_exists(trans, target, d.k->p.snapshot); 1553 - if (ret < 0) 1571 + struct bkey_s_c_dirent bp_dirent = dirent_get_by_pos(trans, &bp_iter, 1572 + SPOS(target->bi_dir, target->bi_dir_offset, target_snapshot)); 1573 + ret = bkey_err(bp_dirent); 1574 + if (ret && !bch2_err_matches(ret, ENOENT)) 1554 1575 goto err; 1555 1576 1556 - backpointer_exists = ret; 1577 + bool backpointer_exists = !ret; 1557 1578 ret = 0; 1579 + 1580 + bch2_bkey_val_to_text(&buf, c, d.s_c); 1581 + prt_newline(&buf); 1582 + if (backpointer_exists) 1583 + bch2_bkey_val_to_text(&buf, c, bp_dirent.s_c); 1558 1584 1559 1585 if (fsck_err_on(S_ISDIR(target->bi_mode) && backpointer_exists, 1560 1586 c, inode_dir_multiple_links, 1561 - "directory %llu with multiple links", 1562 - target->bi_inum)) { 1587 + "directory %llu:%u with multiple links\n%s", 1588 + target->bi_inum, target_snapshot, buf.buf)) { 1563 1589 ret = __remove_dirent(trans, d.k->p); 1564 1590 goto out; 1565 1591 } 1566 1592 1593 + /* 1594 + * hardlinked file with nlink 0: 1595 + * We're just adjusting nlink here so check_nlinks() will pick 1596 + * it up, it ignores inodes with nlink 0 1597 + */ 1567 1598 if (fsck_err_on(backpointer_exists && !target->bi_nlink, 1568 1599 c, inode_multiple_links_but_nlink_0, 1569 - "inode %llu type %s has multiple links but i_nlink 0", 1570 - target->bi_inum, bch2_d_types[d.v->d_type])) { 1600 + "inode %llu:%u type %s has multiple links but i_nlink 0\n%s", 1601 + target->bi_inum, target_snapshot, bch2_d_types[d.v->d_type], buf.buf)) { 1571 1602 target->bi_nlink++; 1572 1603 target->bi_flags &= ~BCH_INODE_unlinked; 1573 1604 ··· 1653 1660 out: 1654 1661 err: 1655 1662 fsck_err: 1663 + bch2_trans_iter_exit(trans, &bp_iter); 1656 1664 printbuf_exit(&buf); 1657 1665 bch_err_fn(c, ret); 1658 1666 return ret; ··· 2395 2401 NULL, NULL, BTREE_INSERT_LAZY_RW|BTREE_INSERT_NOFAIL, 2396 2402 check_nlinks_update_inode(trans, &iter, k, links, &idx, range_end))); 2397 2403 if (ret < 0) { 2398 - bch_err(c, "error in fsck: btree error %i while walking inodes", ret); 2404 + bch_err(c, "error in fsck walking inodes: %s", bch2_err_str(ret)); 2399 2405 return ret; 2400 2406 } 2401 2407