summaryrefslogtreecommitdiff
path: root/fs/bcachefs/snapshot.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-08-28 22:17:31 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:10:12 +0300
commit097d4cc8fde898334569271c9b3e24d99788ade0 (patch)
treea119b64a2346e3f611e1bd540dce22b90d86cf0b /fs/bcachefs/snapshot.c
parentcba37d81f5c34197e815bcd60f075be232ae6783 (diff)
downloadlinux-097d4cc8fde898334569271c9b3e24d99788ade0.tar.xz
bcachefs: Fix snapshot_skiplist_good()
We weren't correctly checking snapshot skiplist nodes - we were checking if they were in the same tree, not if they were an actual ancestor. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/snapshot.c')
-rw-r--r--fs/bcachefs/snapshot.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c
index 07e5c1b44b06..9da09911466e 100644
--- a/fs/bcachefs/snapshot.c
+++ b/fs/bcachefs/snapshot.c
@@ -655,28 +655,18 @@ u32 bch2_snapshot_skiplist_get(struct bch_fs *c, u32 id)
return id;
}
-static int snapshot_skiplist_good(struct btree_trans *trans, struct bch_snapshot s)
+static int snapshot_skiplist_good(struct btree_trans *trans, u32 id, struct bch_snapshot s)
{
- struct bch_snapshot a;
unsigned i;
- int ret;
-
- for (i = 0; i < 3; i++) {
- if (!s.parent != !s.skip[i])
- return false;
-
- if (!s.parent)
- continue;
- ret = bch2_snapshot_lookup(trans, le32_to_cpu(s.skip[i]), &a);
- if (bch2_err_matches(ret, ENOENT))
- return false;
- if (ret)
- return ret;
-
- if (a.tree != s.tree)
- return false;
- }
+ for (i = 0; i < 3; i++)
+ if (!s.parent) {
+ if (s.skip[i])
+ return false;
+ } else {
+ if (!bch2_snapshot_is_ancestor_early(trans->c, id, le32_to_cpu(s.skip[i])))
+ return false;
+ }
return true;
}
@@ -856,7 +846,7 @@ static int check_snapshot(struct btree_trans *trans,
s = u->v;
}
- ret = snapshot_skiplist_good(trans, s);
+ ret = snapshot_skiplist_good(trans, k.k->p.offset, s);
if (ret < 0)
goto err;