summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/smb/client/file.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 051283386e22..1a854dc20482 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -4936,20 +4936,19 @@ oplock_break_ack:
_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
/*
- * 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
- * disconnected since oplock already released by the server
+ * MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) do not require
+ * an acknowledgment to be sent when the file has already been closed.
+ * check for server null, since can race with kill_sb calling tree disconnect.
*/
- if (!oplock_break_cancelled) {
- /* check for server null since can race with kill_sb calling tree disconnect */
- if (tcon->ses && tcon->ses->server) {
- rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
- volatile_fid, net_fid, cinode);
- cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
- } else
- pr_warn_once("lease break not sent for unmounted share\n");
- }
+ spin_lock(&cinode->open_file_lock);
+ if (tcon->ses && tcon->ses->server && !oplock_break_cancelled &&
+ !list_empty(&cinode->openFileList)) {
+ spin_unlock(&cinode->open_file_lock);
+ rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
+ volatile_fid, net_fid, cinode);
+ cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
+ } else
+ spin_unlock(&cinode->open_file_lock);
cifs_done_oplock_break(cinode);
}