[PATCH] cifs: Fix busy dentry used after unmounting

Zhihao Cheng posted 1 patch 5 days, 17 hours ago
fs/smb/client/cifsfs.c | 2 ++
1 file changed, 2 insertions(+)
[PATCH] cifs: Fix busy dentry used after unmounting
Posted by Zhihao Cheng 5 days, 17 hours ago
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 <chengzhihao1@huawei.com>
---
 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
Re: [PATCH] cifs: Fix busy dentry used after unmounting
Posted by Steve French 5 days, 10 hours ago
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 <chengzhihao1@huawei.com> 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 <chengzhihao1@huawei.com>
> ---
>  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
Re: [PATCH] cifs: Fix busy dentry used after unmounting
Posted by Steve French 5 days, 10 hours ago
Also added Cc: stable

On Tue, May 19, 2026 at 11:13 AM Steve French <smfrench@gmail.com> wrote:
>
> 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 <chengzhihao1@huawei.com> 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 <chengzhihao1@huawei.com>
> > ---
> >  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



-- 
Thanks,

Steve