bcachefs: Fix missing transaction commit
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 12 Nov 2023 20:47:02 +0000 (15:47 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 15 Nov 2023 04:44:43 +0000 (23:44 -0500)
In may_delete_deleted_inode(), there's a corner case when a snapshot was
taken while we had an unlinked inode: we don't want to delete the inode
in the internal (shared) snapshot node, since it might have been
reattached in a descendent snapshot.

Instead we propagate the key to any snapshot leaves it doesn't exist in,
so that it can be deleted there if necessary, and then clear the
unlinked flag in the internal node.

But we forgot to commit after clearing the unlinked flag, causing us to
go into an infinite loop.

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

index dab12c14d1ade23ce49eee081c0f2c7d3e410922..c7849b0753e7a115d563aa4cfdf5bdf33b319ec0 100644 (file)
@@ -1169,8 +1169,10 @@ again:
         */
        for_each_btree_key(trans, iter, BTREE_ID_deleted_inodes, POS_MIN,
                           BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k, ret) {
-               ret = lockrestart_do(trans, may_delete_deleted_inode(trans, &iter, k.k->p,
-                                                                    &need_another_pass));
+               ret = commit_do(trans, NULL, NULL,
+                               BTREE_INSERT_NOFAIL|
+                               BTREE_INSERT_LAZY_RW,
+                       may_delete_deleted_inode(trans, &iter, k.k->p, &need_another_pass));
                if (ret < 0)
                        break;