diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-09-23 16:55:03 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:10:15 -0400 |
commit | eebe8a8459f78bbac5a12d0ef76838929d736ad2 (patch) | |
tree | 0eeef4900e9d5311b2114cef5110bbb991b5ac0b | |
parent | 82142a5541063addd15c84fcda890675035df8aa (diff) |
bcachefs: Make sure to initialize equiv when creating new snapshots
Previously, equiv was set in the snapshot deletion path, which is where
it's needed - equiv, for snapshot ID equivalence classes, would ideally
be a private data structure to the snapshot deletion path.
But if a new snapshot is created while snapshot deletion is running,
move_key_to_correct_snapshot() moves a key to snapshot id 0 - oops.
Fixes: https://github.com/koverstreet/bcachefs/issues/593
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/snapshot.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/snapshot.h | 2 |
2 files changed, 6 insertions, 4 deletions
diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index f27e8c4fc10a..cdf9eda2ee02 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -343,7 +343,7 @@ int bch2_snapshot_lookup(struct btree_trans *trans, u32 id, BTREE_ITER_WITH_UPDATES, snapshot, s); } -int bch2_snapshot_live(struct btree_trans *trans, u32 id) +static int bch2_snapshot_live(struct btree_trans *trans, u32 id) { struct bch_snapshot v; int ret; @@ -370,7 +370,7 @@ int bch2_snapshot_live(struct btree_trans *trans, u32 id) * it's part of such a linear chain: this correctly sets equivalence classes on * startup if we run leaf to root (i.e. in natural key order). */ -int bch2_snapshot_set_equiv(struct btree_trans *trans, struct bkey_s_c k) +static int bch2_snapshot_set_equiv(struct btree_trans *trans, struct bkey_s_c k) { struct bch_fs *c = trans->c; unsigned i, nr_live = 0, live_idx = 0; @@ -1071,6 +1071,10 @@ static int create_snapids(struct btree_trans *trans, u32 parent, u32 tree, goto err; new_snapids[i] = iter.pos.offset; + + mutex_lock(&c->snapshot_table_lock); + snapshot_t_mut(c, new_snapids[i])->equiv = new_snapids[i]; + mutex_unlock(&c->snapshot_table_lock); } err: bch2_trans_iter_exit(trans, &iter); diff --git a/fs/bcachefs/snapshot.h b/fs/bcachefs/snapshot.h index dabc9b9d921b..de215d9d1252 100644 --- a/fs/bcachefs/snapshot.h +++ b/fs/bcachefs/snapshot.h @@ -235,8 +235,6 @@ int bch2_snapshot_lookup(struct btree_trans *trans, u32 id, struct bch_snapshot *s); int bch2_snapshot_get_subvol(struct btree_trans *, u32, struct bch_subvolume *); -int bch2_snapshot_live(struct btree_trans *trans, u32 id); -int bch2_snapshot_set_equiv(struct btree_trans *trans, struct bkey_s_c k); /* only exported for tests: */ int bch2_snapshot_node_create(struct btree_trans *, u32, |