aboutsummaryrefslogtreecommitdiffstats
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-03-13 21:22:24 -0400
commit3a136177f3a7929ca1ae3712267548ac4a668cf8 (patch)
tree88e779a276e7e4075ee23961bf69d1df78828892
parent688a7694097653ca9bd6b7febdf7c88763bbbb92 (diff)
downloadvfs-3a136177f3a7929ca1ae3712267548ac4a668cf8.tar.gz
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 69c1587536f9c..412a196263eae 100644
--- a/fs/bcachefs/fsck.c
+++ b/fs/bcachefs/fsck.c
@@ -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;
}