diff options
| author | Paulo Alcantara <pc@manguebit.com> | 2025-04-28 11:05:00 -0300 |
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2025-05-14 19:26:42 -0500 |
| commit | c94ef99937ec2add5e524f77bf777aef21acc201 (patch) | |
| tree | ff37646fc0d1fa2e57a609619a82054079f3fc3d | |
| parent | 3965c23773e81c476f6de30ccc5d201c59ff9714 (diff) | |
| download | linux-c94ef99937ec2add5e524f77bf777aef21acc201.tar.gz linux-c94ef99937ec2add5e524f77bf777aef21acc201.tar.bz2 linux-c94ef99937ec2add5e524f77bf777aef21acc201.zip | |
smb: client: fix delay on concurrent opens
Customers have reported open(2) calls being delayed by 30s or so, and
looking through the network traces, it is related to the client not
sending lease break acks to the server when a lease is being
downgraded from RWH to RW while having an open handle, causing
concurrent opens to be delayed and then impacting performance.
MS-SMB2 3.2.5.19.2:
| If all open handles on this file are closed (that is, File.OpenTable
| is empty for this file), the client SHOULD consider it as an implicit
| acknowledgment of the lease break. No explicit acknowledgment is
| required.
Since we hold an active reference of the open file to process the
lease break, then we should always send a lease break ack if required
by the server.
Cc: linux-cifs@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Reported-by: Pierguido Lambri <plambri@redhat.com>
Fixes: da787d5b7498 ("SMB3: Do not send lease break acknowledgment if all file handles have been closed")
Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
| -rw-r--r-- | fs/smb/client/file.c | 32 |
1 files changed, 10 insertions, 22 deletions
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 950aa4f912f5..a9233b33a002 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -3085,11 +3085,10 @@ void cifs_oplock_break(struct work_struct *work) struct cifsInodeInfo *cinode = CIFS_I(inode); struct cifs_tcon *tcon; struct TCP_Server_Info *server; + bool purge_cache = false; struct tcon_link *tlink; + struct cifs_fid *fid; int rc = 0; - bool purge_cache = false, oplock_break_cancelled; - __u64 persistent_fid, volatile_fid; - __u16 net_fid; wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, TASK_UNINTERRUPTIBLE); @@ -3136,32 +3135,21 @@ oplock_break_ack: * file handles but cached, then schedule deferred close immediately. * So, new open will not use cached handle. */ - if (!CIFS_CACHE_HANDLE(cinode) && !list_empty(&cinode->deferred_closes)) cifs_close_deferred_file(cinode); - persistent_fid = cfile->fid.persistent_fid; - volatile_fid = cfile->fid.volatile_fid; - net_fid = cfile->fid.netfid; - oplock_break_cancelled = cfile->oplock_break_cancelled; - - _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); - /* - * 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. - */ - spin_lock(&cinode->open_file_lock); - /* check list empty since can race with kill_sb calling tree disconnect */ - if (!oplock_break_cancelled && !list_empty(&cinode->openFileList)) { - spin_unlock(&cinode->open_file_lock); - rc = server->ops->oplock_response(tcon, persistent_fid, - volatile_fid, net_fid, cinode); + fid = &cfile->fid; + /* MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) */ + if (!cfile->oplock_break_cancelled) { + rc = server->ops->oplock_response(tcon, fid->persistent_fid, + fid->volatile_fid, + fid->netfid, cinode); cifs_dbg(FYI, "Oplock release rc = %d\n", rc); - } else - spin_unlock(&cinode->open_file_lock); + } cifs_put_tlink(tlink); out: + _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); cifs_done_oplock_break(cinode); } |
