summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-11-12 23:47:02 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-11-15 07:44:43 +0300
commitf42fa17883e73d8509fff5925781d4157db82f00 (patch)
tree02602d511f63ebf20b3b9bc1bb239263fe79e768 /fs
parent178c4873fd06c0361d260547ce70fcdc29b74809 (diff)
downloadlinux-f42fa17883e73d8509fff5925781d4157db82f00.tar.xz
bcachefs: Fix missing transaction commit
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/inode.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/bcachefs/inode.c b/fs/bcachefs/inode.c
index dab12c14d1ad..c7849b0753e7 100644
--- a/fs/bcachefs/inode.c
+++ b/fs/bcachefs/inode.c
@@ -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;