diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-08-28 15:17:31 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-09-11 01:31:12 -0400 |
commit | 15f0c370403082d61e8571a9d0bf258593631981 (patch) | |
tree | edc0f0aa44bb1a063365882b1058b44856a90255 | |
parent | df057c6c02c66d3c229aeea8b8c9fa47a3c2d88a (diff) |
bcachefs: Fix snapshot_skiplist_good()bcachefs-v6.4
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>
-rw-r--r-- | fs/bcachefs/snapshot.c | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index 5a690a6f9962..03ae280aee3a 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -636,28 +636,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; } @@ -837,7 +827,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; |