diff options
author | Bharath SM <bharathsm@microsoft.com> | 2023-04-26 14:05:16 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-05-11 23:03:36 +0900 |
commit | 32dce45c8eed3001726e67e4b46ef5e2008a92fa (patch) | |
tree | 0680c904f02760b3d7f0dcf2cc1e30026f8024cd | |
parent | 3aa9d065b0685b4e6052f3f2a2462966fdc44fd2 (diff) |
SMB3: Close deferred file handles in case of handle lease break
[ Upstream commit d906be3fa571f6fc9381911304a0eca99f1b6951 ]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | fs/cifs/file.c | 16 | ||||
-rw-r--r-- | fs/cifs/misc.c | 2 |
2 files changed, 17 insertions, 1 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 6f5fbbbebec3..158a0a5f4007 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -5087,6 +5087,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); @@ -5123,6 +5125,20 @@ void cifs_oplock_break(struct work_struct *work) 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 * not bother sending an oplock release if session to server still is diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index f3903ae0cc6b..31e06133acc3 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); } |