summaryrefslogtreecommitdiff
path: root/fs/bcachefs/subvolume.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-10-18 21:46:57 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:14 +0300
commitca130b9c5e120994483a34c72526dcd4bf308d84 (patch)
tree3753fbd9cbd7b1cbc2f1408e8cea775788bad6ea /fs/bcachefs/subvolume.c
parent6a0f414e2018fe7a2b001fbc8ccd4a8f4f946214 (diff)
downloadlinux-ca130b9c5e120994483a34c72526dcd4bf308d84.tar.xz
bcachefs: Fix a cache coherency bug in bch2_subvolume_create()
Subvolume deletion doesn't flush & evict the btree key cache - ideally it would, but that's tricky, so instead bch2_subvolume_create() needs to make sure the slot doesn't exist in the key cache to avoid triggering assertions. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/subvolume.c')
-rw-r--r--fs/bcachefs/subvolume.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/bcachefs/subvolume.c b/fs/bcachefs/subvolume.c
index d1c111050c35..9bd8d61c96fe 100644
--- a/fs/bcachefs/subvolume.c
+++ b/fs/bcachefs/subvolume.c
@@ -886,6 +886,7 @@ int bch2_subvolume_create(struct btree_trans *trans, u64 inode,
u32 *new_snapshotid,
bool ro)
{
+ struct bch_fs *c = trans->c;
struct btree_iter dst_iter, src_iter = (struct btree_iter) { NULL };
struct bkey_i_subvolume *new_subvol = NULL;
struct bkey_i_subvolume *src_subvol = NULL;
@@ -897,7 +898,13 @@ int bch2_subvolume_create(struct btree_trans *trans, u64 inode,
BTREE_ITER_SLOTS|BTREE_ITER_INTENT, k, ret) {
if (bkey_cmp(k.k->p, SUBVOL_POS_MAX) > 0)
break;
- if (bkey_deleted(k.k))
+
+ /*
+ * bch2_subvolume_delete() doesn't flush the btree key cache -
+ * ideally it would but that's tricky
+ */
+ if (bkey_deleted(k.k) &&
+ !bch2_btree_key_cache_find(c, BTREE_ID_subvolumes, dst_iter.pos))
goto found_slot;
}
@@ -925,7 +932,7 @@ found_slot:
goto err;
if (k.k->type != KEY_TYPE_subvolume) {
- bch_err(trans->c, "subvolume %u not found", src_subvolid);
+ bch_err(c, "subvolume %u not found", src_subvolid);
ret = -ENOENT;
goto err;
}