diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-08-28 22:17:31 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:10:12 +0300 |
commit | 097d4cc8fde898334569271c9b3e24d99788ade0 (patch) | |
tree | a119b64a2346e3f611e1bd540dce22b90d86cf0b /fs/bcachefs/snapshot.c | |
parent | cba37d81f5c34197e815bcd60f075be232ae6783 (diff) | |
download | linux-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.c | 30 |
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; |