Re: [PATCH] CIFS: Fix SMB2 oplock break processing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



tentatively merged into cifs-2.6.git for-next pending review and
buildbot regression test runs

On Thu, Oct 31, 2019 at 5:50 PM Pavel Shilovsky <piastryyy@xxxxxxxxx> wrote:
>
> Even when mounting modern protocol version the server may be
> configured without supporting SMB2.1 leases and the client
> uses SMB2 oplock to optimize IO performance through local caching.
>
> However there is a problem in oplock break handling that leads
> to missing a break notification on the client who has a file
> opened. It latter causes big latencies to other clients that
> are trying to open the same file.
>
> The problem reproduces when there are multiple shares from the
> same server mounted on the client. The processing code tries to
> match persistent and volatile file ids from the break notification
> with an open file but it skips all share besides the first one.
> Fix this by looking up in all shares belonging to the server that
> issued the oplock break.
>
> Cc: Stable <stable@xxxxxxxxxxxxxxx>
> Signed-off-by: Pavel Shilovsky <pshilov@xxxxxxxxxxxxx>
> ---
>  fs/cifs/smb2misc.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
> index 8db6201b18ba..527c9efd3de0 100644
> --- a/fs/cifs/smb2misc.c
> +++ b/fs/cifs/smb2misc.c
> @@ -664,10 +664,10 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
>         spin_lock(&cifs_tcp_ses_lock);
>         list_for_each(tmp, &server->smb_ses_list) {
>                 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
> +
>                 list_for_each(tmp1, &ses->tcon_list) {
>                         tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
>
> -                       cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
>                         spin_lock(&tcon->open_file_lock);
>                         list_for_each(tmp2, &tcon->openFileList) {
>                                 cfile = list_entry(tmp2, struct cifsFileInfo,
> @@ -679,6 +679,8 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
>                                         continue;
>
>                                 cifs_dbg(FYI, "file id match, oplock break\n");
> +                               cifs_stats_inc(
> +                                   &tcon->stats.cifs_stats.num_oplock_brks);
>                                 cinode = CIFS_I(d_inode(cfile->dentry));
>                                 spin_lock(&cfile->file_info_lock);
>                                 if (!CIFS_CACHE_WRITE(cinode) &&
> @@ -702,9 +704,6 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
>                                 return true;
>                         }
>                         spin_unlock(&tcon->open_file_lock);
> -                       spin_unlock(&cifs_tcp_ses_lock);
> -                       cifs_dbg(FYI, "No matching file for oplock break\n");
> -                       return true;
>                 }
>         }
>         spin_unlock(&cifs_tcp_ses_lock);
> --
> 2.17.1
>


-- 
Thanks,

Steve



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux