Commit 488f9776 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix check_path() across subvolumes

Checking of directory structure across subvolumes was broken - we need
to look up the snapshot ID of the parent subvolume when crossing subvol
boundaries.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent ca130b9c
...@@ -1050,6 +1050,8 @@ static int inode_backpointer_exists(struct btree_trans *trans, ...@@ -1050,6 +1050,8 @@ static int inode_backpointer_exists(struct btree_trans *trans,
{ {
struct btree_iter iter; struct btree_iter iter;
struct bkey_s_c k; struct bkey_s_c k;
u32 target_subvol, target_snapshot;
u64 target_inum;
int ret; int ret;
bch2_trans_iter_init(trans, &iter, BTREE_ID_dirents, bch2_trans_iter_init(trans, &iter, BTREE_ID_dirents,
...@@ -1061,7 +1063,15 @@ static int inode_backpointer_exists(struct btree_trans *trans, ...@@ -1061,7 +1063,15 @@ static int inode_backpointer_exists(struct btree_trans *trans,
if (k.k->type != KEY_TYPE_dirent) if (k.k->type != KEY_TYPE_dirent)
goto out; goto out;
ret = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum) == inode->bi_inum; ret = __bch2_dirent_read_target(trans, bkey_s_c_to_dirent(k),
&target_subvol,
&target_snapshot,
&target_inum,
true);
if (ret)
goto out;
ret = target_inum == inode->bi_inum;
out: out:
bch2_trans_iter_exit(trans, &iter); bch2_trans_iter_exit(trans, &iter);
return ret; return ret;
...@@ -1754,7 +1764,17 @@ static int check_path(struct btree_trans *trans, ...@@ -1754,7 +1764,17 @@ static int check_path(struct btree_trans *trans,
snapshot = snapshot_t(c, snapshot)->equiv; snapshot = snapshot_t(c, snapshot)->equiv;
p->nr = 0; p->nr = 0;
while (inode->bi_inum != BCACHEFS_ROOT_INO) { while (!(inode->bi_inum == BCACHEFS_ROOT_INO &&
inode->bi_subvol == BCACHEFS_ROOT_SUBVOL)) {
if (inode->bi_parent_subvol) {
u64 inum;
ret = subvol_lookup(trans, inode->bi_parent_subvol,
&snapshot, &inum);
if (ret)
break;
}
ret = lockrestart_do(trans, ret = lockrestart_do(trans,
inode_backpointer_exists(trans, inode, snapshot)); inode_backpointer_exists(trans, inode, snapshot));
if (ret < 0) if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment