]> www.infradead.org Git - nvme.git/commitdiff
bcachefs: Fix check_snapshot_exists() restart handling
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 2 Apr 2025 18:31:12 +0000 (14:31 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 3 Apr 2025 16:11:43 +0000 (12:11 -0400)
Codepaths that create entries in the snapshots btree currently call
bch2_mark_snapshot(), which updates the in-memory snapshot table, before
transaction commit.

This is because bch2_mark_snapshot() is an atomic trigger, run with
btree write locks held, and isn't allowed to fail - but it might need to
reallocate the table, hence we call it early when we're still allowed to
fail.

This is generally harmless - if we fail, we'll have left an entry in the
snapshots table around, but nothing will reference it and it'll get
overwritten if reused by another transaction.

But check_snapshot_exists(), which reconstructs snapshots when the
snapshots btree has been corrupted or lost, was erronously rechecking if
the snapshot exists inside the transaction commit loop - so on
transaction restart (in this case mem_realloced), the second iteration
would return without repairing.

This code needs some cleanup: splitting out a "maybe realloc snapshots
table" helper would have avoided this, that will be in the next patch.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/snapshot.c

index c8536eb360607bba491e4ae40e6e47365550cb25..b7de29aed83917b5712261b076f77600a6373689 100644 (file)
@@ -843,9 +843,6 @@ static int check_snapshot_exists(struct btree_trans *trans, u32 id)
 {
        struct bch_fs *c = trans->c;
 
-       if (bch2_snapshot_exists(c, id))
-               return 0;
-
        /* Do we need to reconstruct the snapshot_tree entry as well? */
        struct btree_iter iter;
        struct bkey_s_c k;