lkml.org 
[lkml]   [2019]   [Dec]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 217/243] CIFS: Fix SMB2 oplock break processing
    Date
    From: Pavel Shilovsky <pshilov@microsoft.com>

    commit fa9c2362497fbd64788063288dc4e74daf977ebb upstream.

    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@vger.kernel.org>
    Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
    Signed-off-by: Steve French <stfrench@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/cifs/smb2misc.c | 7 +++----
    1 file changed, 3 insertions(+), 4 deletions(-)

    --- a/fs/cifs/smb2misc.c
    +++ b/fs/cifs/smb2misc.c
    @@ -673,10 +673,10 @@ smb2_is_valid_oplock_break(char *buffer,
    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,
    @@ -688,6 +688,8 @@ smb2_is_valid_oplock_break(char *buffer,
    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) &&
    @@ -720,9 +722,6 @@ smb2_is_valid_oplock_break(char *buffer,
    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);

    \
     
     \ /
      Last update: 2019-12-11 16:25    [W:4.021 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site