From 77aeaa2f0fcac2d68fe1af61169fe26d5fac9a22 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 19 May 2025 09:48:50 -0400 Subject: [PATCH] bcachefs: bch2_inum_snapshot_to_path() Add a better helper for printing out paths of inodes when we don't know the subvolume, for fsck. Signed-off-by: Kent Overstreet --- fs/bcachefs/error.c | 22 +++------------------- fs/bcachefs/namei.c | 18 ++++++++++++++++++ fs/bcachefs/namei.h | 2 ++ fs/bcachefs/snapshot.c | 29 +++++++++++++++++++---------- fs/bcachefs/snapshot.h | 2 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index a476dd2c196eb..c2cad28635bfa 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -742,25 +742,9 @@ void bch2_inum_offset_err_msg(struct bch_fs *c, struct printbuf *out, int bch2_inum_snap_offset_err_msg_trans(struct btree_trans *trans, struct printbuf *out, struct bpos pos) { - struct bch_fs *c = trans->c; - int ret = 0; - - if (!bch2_snapshot_is_leaf(c, pos.snapshot)) - prt_str(out, "(multiple snapshots) "); - - subvol_inum inum = { - .subvol = bch2_snapshot_tree_oldest_subvol(c, pos.snapshot), - .inum = pos.inode, - }; - - if (inum.subvol) { - ret = bch2_inum_to_path(trans, inum, out); - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) - return ret; - } - - if (!inum.subvol || ret) - prt_printf(out, "inum %llu:%u", pos.inode, pos.snapshot); + int ret = bch2_inum_snapshot_to_path(trans, pos.inode, pos.snapshot, NULL, out); + if (ret) + return ret; prt_printf(out, " offset %llu: ", pos.offset << 8); return 0; diff --git a/fs/bcachefs/namei.c b/fs/bcachefs/namei.c index e81e554b51d38..8088e810815f9 100644 --- a/fs/bcachefs/namei.c +++ b/fs/bcachefs/namei.c @@ -654,6 +654,24 @@ disconnected: goto out; } +int bch2_inum_snapshot_to_path(struct btree_trans *trans, u64 inum, u32 snapshot, + snapshot_id_list *snapshot_overwrites, + struct printbuf *path) +{ + u32 subvol = bch2_snapshot_oldest_subvol(trans->c, snapshot, snapshot_overwrites); + int ret = 0; + + if (subvol) { + ret = bch2_inum_to_path(trans, (subvol_inum) { subvol, inum }, path); + if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) + return ret; + } + + if (!subvol || ret) + prt_printf(path, "inum %llu:%u", inum, snapshot); + return 0; +} + /* fsck */ static int bch2_check_dirent_inode_dirent(struct btree_trans *trans, diff --git a/fs/bcachefs/namei.h b/fs/bcachefs/namei.h index 2e6f6364767ff..d4d2d2d69517f 100644 --- a/fs/bcachefs/namei.h +++ b/fs/bcachefs/namei.h @@ -43,6 +43,8 @@ bool bch2_reinherit_attrs(struct bch_inode_unpacked *, struct bch_inode_unpacked *); int bch2_inum_to_path(struct btree_trans *, subvol_inum, struct printbuf *); +int bch2_inum_snapshot_to_path(struct btree_trans *, u64, u32, + snapshot_id_list *, struct printbuf *); int __bch2_check_dirent_target(struct btree_trans *, struct btree_iter *, diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index 24903e7de296c..00d62d1190ef0 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -409,22 +409,31 @@ static u32 bch2_snapshot_tree_next(struct bch_fs *c, u32 id) return 0; } -u32 bch2_snapshot_tree_oldest_subvol(struct bch_fs *c, u32 snapshot_root) +u32 bch2_snapshot_oldest_subvol(struct bch_fs *c, u32 snapshot_root, + snapshot_id_list *skip) { - u32 id = snapshot_root; - u32 subvol = 0, s; - + u32 id, subvol = 0, s; +retry: + id = snapshot_root; rcu_read_lock(); while (id && bch2_snapshot_exists(c, id)) { - s = snapshot_t(c, id)->subvol; - - if (s && (!subvol || s < subvol)) - subvol = s; + if (!(skip && snapshot_list_has_id(skip, id))) { + s = snapshot_t(c, id)->subvol; + if (s && (!subvol || s < subvol)) + subvol = s; + } id = bch2_snapshot_tree_next(c, id); + if (id == snapshot_root) + break; } rcu_read_unlock(); + if (!subvol && skip) { + skip = NULL; + goto retry; + } + return subvol; } @@ -456,7 +465,7 @@ static int bch2_snapshot_tree_master_subvol(struct btree_trans *trans, if (!ret && !found) { struct bkey_i_subvolume *u; - *subvol_id = bch2_snapshot_tree_oldest_subvol(c, snapshot_root); + *subvol_id = bch2_snapshot_oldest_subvol(c, snapshot_root, NULL); u = bch2_bkey_get_mut_typed(trans, &iter, BTREE_ID_subvolumes, POS(0, *subvol_id), @@ -673,7 +682,7 @@ static int snapshot_tree_ptr_repair(struct btree_trans *trans, u = bch2_bkey_make_mut_typed(trans, &root_iter, &root.s_c, 0, snapshot); ret = PTR_ERR_OR_ZERO(u) ?: bch2_snapshot_tree_create(trans, root_id, - bch2_snapshot_tree_oldest_subvol(c, root_id), + bch2_snapshot_oldest_subvol(c, root_id, NULL), &tree_id); if (ret) goto err; diff --git a/fs/bcachefs/snapshot.h b/fs/bcachefs/snapshot.h index 63b9469eb1ebf..382a171f54132 100644 --- a/fs/bcachefs/snapshot.h +++ b/fs/bcachefs/snapshot.h @@ -105,7 +105,7 @@ static inline u32 bch2_snapshot_nth_parent(struct bch_fs *c, u32 id, u32 n) return id; } -u32 bch2_snapshot_tree_oldest_subvol(struct bch_fs *, u32); +u32 bch2_snapshot_oldest_subvol(struct bch_fs *, u32, snapshot_id_list *); u32 bch2_snapshot_skiplist_get(struct bch_fs *, u32); static inline u32 bch2_snapshot_root(struct bch_fs *c, u32 id) -- 2.39.5