From 2d33036ca9360bacef23ba32e7768ff9ea87f2be Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 16 Mar 2023 11:04:28 -0400 Subject: [PATCH] bcachefs: Fix for 'missing subvolume' error Subvolumes, including their root inodes, get deleted asynchronously after an unlink. But we still need to ensure that we tell the VFS the inode has been deleted, otherwise VFS writeback could fire after asynchronous deletion has finished, and try to write to an inode/subvolume that no longer exists. Signed-off-by: Kent Overstreet --- fs/bcachefs/fs.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index 15ab77ebb8c6..828887abc261 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -442,19 +442,27 @@ int __bch2_unlink(struct inode *vdir, struct dentry *dentry, bch2_trans_init(&trans, c, 4, 1024); ret = commit_do(&trans, NULL, NULL, - BTREE_INSERT_NOFAIL, - bch2_unlink_trans(&trans, - inode_inum(dir), &dir_u, - &inode_u, &dentry->d_name, - deleting_snapshot)); + BTREE_INSERT_NOFAIL, + bch2_unlink_trans(&trans, + inode_inum(dir), &dir_u, + &inode_u, &dentry->d_name, + deleting_snapshot)); + if (unlikely(ret)) + goto err; - if (likely(!ret)) { - bch2_inode_update_after_write(&trans, dir, &dir_u, - ATTR_MTIME|ATTR_CTIME); - bch2_inode_update_after_write(&trans, inode, &inode_u, - ATTR_MTIME); + bch2_inode_update_after_write(&trans, dir, &dir_u, + ATTR_MTIME|ATTR_CTIME); + bch2_inode_update_after_write(&trans, inode, &inode_u, + ATTR_MTIME); + + if (inode_u.bi_subvol) { + /* + * Subvolume deletion is asynchronous, but we still want to tell + * the VFS that it's been deleted here: + */ + set_nlink(&inode->v, 0); } - +err: bch2_trans_exit(&trans); bch2_unlock_inodes(INODE_UPDATE_LOCK, dir, inode);