SMB3: Close deferred file handles in case of handle lease break
authorBharath SM <bharathsm@microsoft.com>
Wed, 26 Apr 2023 14:05:16 +0000 (14:05 +0000)
committerSteve French <stfrench@microsoft.com>
Thu, 27 Apr 2023 16:03:33 +0000 (11:03 -0500)
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>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/file.c
fs/cifs/misc.c

index b33d2e7b0f984490e9db987a535201de0fe79e1e..c5fcefdfd7976666fdf01d4bda1b5f8da14388dc 100644 (file)
@@ -4882,6 +4882,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);
@@ -4917,6 +4919,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
index f76e9bb7d74231682439628efde5c806c4ac895f..cd914be905b244d69b560edf1e005e9f255cbb4e 100644 (file)
@@ -764,7 +764,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);
        }