Re: [PATCH] cifs: Fix busy dentry used after unmounting
Steve French <[email protected]> Tue, 19 May 2026 11:13:54 -0500
| Newsgroups | gmane.linux.kernel,gmane.linux.kernel.cifs,gmane.network.samba.internals |
|---|---|
| Message-ID | <CAH2r5mtBdyNOqYQEFicOv9P-PAVc23jxK2cw4D7zjLKwmCpNRg@mail.gmail.com> |
merged into cifs-2.6.git for-next Sashiko had some followup patch ideas, but it looks like no changes to this patch needed: https://sashiko.dev/#/patchset/20260519091805.220902-1-chengzhihao1%40huawei.com On Tue, May 19, 2026 at 4:28 AM Zhihao Cheng <[email protected]> wrote: > > Since commit 340cea84f691c ("cifs: open files should not hold ref on > superblock"), cifs file only holds the dentry ref_cnt, the cifs file > close work(cfile->deferred) could be executed after unmounting, which > will trigger a warning in generic_shutdown_super: > BUG: Dentry 00000000a14a6845{i=c,n=file} still in use (1) [unmount of > cifs cifs] > > The detailed processs is: > process A process B kworker > fd = open(PATH) > vfs_open > file->__f_path = *path // dentry->d_lockref.count = 1 > cifs_open > cifs_new_fileinfo > cfile->dentry = dget(dentry) // dentry->d_lockref.count = 2 > close(fd) > __fput > cifs_close > queue_delayed_work(deferredclose_wq, cfile->deferred) > dput(dentry) // dentry->d_lockref.count = 1 > smb2_deferred_work_close > _cifsFileInfo_put > list_del(&cifs_file->flist) > umount > cleanup_mnt > deactivate_super > cifs_kill_sb > cifs_close_all_deferred_files_sb > cifs_close_all_deferred_files > // cannot find cfile, skip _cifsFileInfo_put > kill_anon_super > generic_shutdown_super > shrink_dcache_for_umount > umount_check > WARN ! // dentry->d_lockref.count = 1 > cifsFileInfo_put_final > dput(cifs_file->dentry) > // dentry->d_lockref.count = 0 > > Fix it by flushing 'deferredclose_wq' before calling kill_anon_super. > > Fetch a reproducer in https://bugzilla.kernel.org/show_bug.cgi?id=221548. > > Fixes: 340cea84f691c ("cifs: open files should not hold ref on superblock") > Signed-off-by: Zhihao Cheng <[email protected]> > --- > fs/smb/client/cifsfs.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c > index f557eb7875c7..ce23924f01b3 100644 > --- a/fs/smb/client/cifsfs.c > +++ b/fs/smb/client/cifsfs.c > @@ -306,6 +306,8 @@ static void cifs_kill_sb(struct super_block *sb) > > /* Wait for all pending oplock breaks to complete */ > flush_workqueue(cifsoplockd_wq); > + /* Wait for all opened files to release */ > + flush_workqueue(deferredclose_wq); > > /* finally release root dentry */ > dput(cifs_sb->root); > -- > 2.52.0 > > -- Thanks, Steve