tentatively added to for-next pending testing On Wed, Apr 26, 2023 at 9:15 AM Bharath SM <bharathsm.hsk@xxxxxxxxx> wrote: > > We should not cache deferred file handles if we dont have > handle lease on a file. And we should immediately close all > deferred handles in case of handle lease break. > > Fixes: 9e31678fb403 ("SMB3: fix lease break timeout when multiple deferred close handles for the same file.") > Signed-off-by: Bharath SM <bharathsm@xxxxxxxxxxxxx> > --- > fs/cifs/file.c | 16 ++++++++++++++++ > fs/cifs/misc.c | 2 +- > 2 files changed, 17 insertions(+), 1 deletion(-) > > diff --git a/fs/cifs/file.c b/fs/cifs/file.c > index 4d4a2d82636d..791a12575109 100644 > --- a/fs/cifs/file.c > +++ b/fs/cifs/file.c > @@ -4886,6 +4886,8 @@ void cifs_oplock_break(struct work_struct *work) > struct TCP_Server_Info *server = tcon->ses->server; > int rc = 0; > bool purge_cache = false; > + struct cifs_deferred_close *dclose; > + bool is_deferred = false; > > wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, > TASK_UNINTERRUPTIBLE); > @@ -4921,6 +4923,20 @@ void cifs_oplock_break(struct work_struct *work) > cifs_dbg(VFS, "Push locks rc = %d\n", rc); > > oplock_break_ack: > + /* > + * When oplock break is received and there are no active > + * file handles but cached, then schedule deferred close immediately. > + * So, new open will not use cached handle. > + */ > + spin_lock(&CIFS_I(inode)->deferred_lock); > + is_deferred = cifs_is_deferred_close(cfile, &dclose); > + spin_unlock(&CIFS_I(inode)->deferred_lock); > + > + if (!CIFS_CACHE_HANDLE(cinode) && is_deferred && > + cfile->deferred_close_scheduled && delayed_work_pending(&cfile->deferred)) { > + cifs_close_deferred_file(cinode); > + } > + > /* > * releasing stale oplock after recent reconnect of smb session using > * a now incorrect file handle is not a data integrity issue but do > diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c > index 5f874e9c1554..0cfb46d7773c 100644 > --- a/fs/cifs/misc.c > +++ b/fs/cifs/misc.c > @@ -757,7 +757,7 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode) > spin_unlock(&cifs_inode->open_file_lock); > > list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) { > - _cifsFileInfo_put(tmp_list->cfile, true, false); > + _cifsFileInfo_put(tmp_list->cfile, false, false); > list_del(&tmp_list->list); > kfree(tmp_list); > } > -- > 2.34.1 > -- Thanks, Steve