]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Make sure to initialize equiv when creating new snapshots
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 23 Sep 2023 20:55:03 +0000 (16:55 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:15 +0000 (17:10 -0400)
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>
fs/bcachefs/snapshot.c
fs/bcachefs/snapshot.h

index f27e8c4fc10a034080603e9b3423f0dd7c4afae1..cdf9eda2ee0284c764583a3ddb8a535d67459680 100644 (file)
@@ -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);
index dabc9b9d921b4766be3f84d1b9bc4c494a518f8f..de215d9d1252549db99d7d8c6cea352f90264382 100644 (file)
@@ -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,