bcachefs: check_path() now prints full inode when reattaching
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 9 Feb 2024 04:08:21 +0000 (23:08 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 14 Mar 2024 01:22:24 +0000 (21:22 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fsck.c

index 69c1587536f9cec4eb520a2f9b8c38cca0d8f7ea..412a196263eae0da0f6c25b0ee1c67aff3d15b00 100644 (file)
@@ -2108,7 +2108,9 @@ static int path_down(struct bch_fs *c, pathbuf *p,
 static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c inode_k)
 {
        struct bch_fs *c = trans->c;
+       struct btree_iter inode_iter = {};
        struct bch_inode_unpacked inode;
+       struct printbuf buf = PRINTBUF;
        u32 snapshot = bch2_snapshot_equiv(c, inode_k.k->p.snapshot);
        int ret = 0;
 
@@ -2134,14 +2136,12 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
 
                if (bch2_err_matches(ret, ENOENT)) {
                        if (fsck_err(c, inode_unreachable,
-                                    "unreachable inode %llu:%u, type %s nlink %u backptr %llu:%llu",
-                                    inode.bi_inum, snapshot,
-                                    bch2_d_type_str(inode_d_type(&inode)),
-                                    inode.bi_nlink,
-                                    inode.bi_dir,
-                                    inode.bi_dir_offset))
+                                    "unreachable inode\n%s",
+                                    (printbuf_reset(&buf),
+                                     bch2_bkey_val_to_text(&buf, c, inode_k),
+                                     buf.buf)))
                                ret = reattach_inode(trans, &inode, snapshot);
-                       break;
+                       goto out;
                }
 
                bch2_trans_iter_exit(trans, &dirent_iter);
@@ -2157,7 +2157,12 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
 
                snapshot = parent_snapshot;
 
-               ret = lookup_inode(trans, inode.bi_dir, &inode, &snapshot);
+               bch2_trans_iter_exit(trans, &inode_iter);
+               inode_k = bch2_bkey_get_iter(trans, &inode_iter, BTREE_ID_inodes,
+                                            SPOS(0, inode.bi_dir, snapshot), 0);
+               ret = bkey_err(inode_k) ?:
+                       !bkey_is_inode(inode_k.k) ? -BCH_ERR_ENOENT_inode
+                       : bch2_inode_unpack(inode_k, &inode);
                if (ret) {
                        /* Should have been caught in dirents pass */
                        if (!bch2_err_matches(ret, BCH_ERR_transaction_restart))
@@ -2165,6 +2170,8 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
                        break;
                }
 
+               snapshot = inode_k.k->p.snapshot;
+
                if (path_is_dup(p, inode.bi_inum, snapshot)) {
                        /* XXX print path */
                        bch_err(c, "directory structure loop");
@@ -2188,7 +2195,10 @@ static int check_path(struct btree_trans *trans, pathbuf *p, struct bkey_s_c ino
                        break;
                }
        }
+out:
 fsck_err:
+       bch2_trans_iter_exit(trans, &inode_iter);
+       printbuf_exit(&buf);
        bch_err_fn(c, ret);
        return ret;
 }