diff mbox series

SMB3: Close deferred file handles in case of handle lease break

Message ID 20230426140516.12532-1-bharathsm.hsk@gmail.com (mailing list archive)
State New, archived
Headers show
Series SMB3: Close deferred file handles in case of handle lease break | expand

Commit Message

Bharath SM April 26, 2023, 2:05 p.m. UTC
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@microsoft.com>
---
 fs/cifs/file.c | 16 ++++++++++++++++
 fs/cifs/misc.c |  2 +-
 2 files changed, 17 insertions(+), 1 deletion(-)

Comments

Steve French April 27, 2023, 4:04 p.m. UTC | #1
tentatively added to for-next pending testing

On Wed, Apr 26, 2023 at 9:15 AM Bharath SM <bharathsm.hsk@gmail.com> 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@microsoft.com>
> ---
>  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
>
diff mbox series

Patch

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);
 	}