mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 09:09:55 -04:00
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 <kent.overstreet@linux.dev>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -654,6 +654,24 @@ int bch2_inum_to_path(struct btree_trans *trans, subvol_inum inum, struct printb
|
||||
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,
|
||||
|
||||
@@ -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 *,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user