]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: bch2_inum_snapshot_to_path()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 19 May 2025 13:48:50 +0000 (09:48 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:15:09 +0000 (20:15 -0400)
Add a better helper for printing out paths of inodes when we don't know
the subvolume, for fsck.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/error.c
fs/bcachefs/namei.c
fs/bcachefs/namei.h
fs/bcachefs/snapshot.c
fs/bcachefs/snapshot.h

index a476dd2c196ebe404fa0d705474c09797dc5fc2a..c2cad28635bfa6fbd360e096c0cd09d90639c9e0 100644 (file)
@@ -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;
index e81e554b51d3813d89cdcd6ef79281c217fc6c16..8088e810815f9d638b794d40bfe594bcf657c307 100644 (file)
@@ -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,
index 2e6f6364767ff1636a475e7670db07468f33db35..d4d2d2d69517fdaaf35dc6c7f087bcb15968a3df 100644 (file)
@@ -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 *,
index 24903e7de296c76f8215f13f5326ab0c58f59e80..00d62d1190ef060c9b36b440a7a2fed3ea429653 100644 (file)
@@ -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;
index 63b9469eb1ebf04722360e7d1050fd101a6edc4d..382a171f541327f7ce21bf70a16c3ba4c2fc2fce 100644 (file)
@@ -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)