summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-02-08 23:08:21 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2024-02-27 13:59:05 -0500
commitf0340e20452d7604a561d6665fb1d2ff0352a2da (patch)
treed44f52f9727ec75d136ca3c6a44b24508515b9cc
parent188a8c307388aa82f15eab5ed2e689101d31ac33 (diff)
bcachefs: check_path() now prints full inode when reattaching
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/fsck.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c
index c93558ff7a48..ce4d556198e3 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -2111,7 +2111,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;
@@ -2137,14 +2139,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);
@@ -2160,7 +2160,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))
@@ -2168,6 +2173,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");
@@ -2191,7 +2198,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;
}