From 37fad9497f5d37d89ed06faa64d580d1451be664 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 29 Sep 2023 01:15:33 -0400 Subject: bcachefs: snapshot_create_lock Add a new lock for snapshot creation - this addresses a few races with logged operations and snapshot deletion. Signed-off-by: Kent Overstreet --- fs/bcachefs/snapshot.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'fs/bcachefs/snapshot.c') diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index b8c32d1cbd76..4982468bfe11 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -1447,6 +1447,8 @@ int bch2_delete_dead_snapshots(struct bch_fs *c) } } + down_write(&c->snapshot_create_lock); + for_each_btree_key(trans, iter, BTREE_ID_snapshots, POS_MIN, 0, k, ret) { u32 snapshot = k.k->p.offset; @@ -1457,6 +1459,9 @@ int bch2_delete_dead_snapshots(struct bch_fs *c) } bch2_trans_iter_exit(trans, &iter); + if (ret) + goto err_create_lock; + /* * Fixing children of deleted snapshots can't be done completely * atomically, if we crash between here and when we delete the interior @@ -1467,14 +1472,14 @@ int bch2_delete_dead_snapshots(struct bch_fs *c) NULL, NULL, BTREE_INSERT_NOFAIL, bch2_fix_child_of_deleted_snapshot(trans, &iter, k, &deleted_interior)); if (ret) - goto err; + goto err_create_lock; darray_for_each(deleted, i) { ret = commit_do(trans, NULL, NULL, 0, bch2_snapshot_node_delete(trans, *i)); if (ret) { bch_err_msg(c, ret, "deleting snapshot %u", *i); - goto err; + goto err_create_lock; } } @@ -1483,11 +1488,13 @@ int bch2_delete_dead_snapshots(struct bch_fs *c) bch2_snapshot_node_delete(trans, *i)); if (ret) { bch_err_msg(c, ret, "deleting snapshot %u", *i); - goto err; + goto err_create_lock; } } clear_bit(BCH_FS_HAVE_DELETED_SNAPSHOTS, &c->flags); +err_create_lock: + up_write(&c->snapshot_create_lock); err: darray_exit(&deleted_interior); darray_exit(&deleted); -- cgit v1.2.3