lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 251/879] cifs: do not use tcpStatus after negotiate completes
    Date
    From: Shyam Prasad N <sprasad@microsoft.com>

    [ Upstream commit 1a6a41d4cedd9b302e2200e6f0e3c44dbbe13689 ]

    Recent changes to multichannel to allow channel reconnects to
    work in parallel and independent of each other did so by
    making use of tcpStatus for the connection, and status for the
    session. However, this did not take into account the multiuser
    scenario, where same connection is used by multiple connections.

    However, tcpStatus should be tracked only till the end of
    negotiate exchange, and not used for session setup. This change
    fixes this.

    Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
    Signed-off-by: Steve French <stfrench@microsoft.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/cifs/connect.c | 23 +++++++++++------------
    fs/cifs/smb2pdu.c | 3 ++-
    fs/cifs/smb2transport.c | 3 ++-
    3 files changed, 15 insertions(+), 14 deletions(-)

    diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
    index b28b1ff39fed..aa2d4c49e2a5 100644
    --- a/fs/cifs/connect.c
    +++ b/fs/cifs/connect.c
    @@ -3956,7 +3956,7 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
    if (rc == 0) {
    spin_lock(&cifs_tcp_ses_lock);
    if (server->tcpStatus == CifsInNegotiate)
    - server->tcpStatus = CifsNeedSessSetup;
    + server->tcpStatus = CifsGood;
    else
    rc = -EHOSTDOWN;
    spin_unlock(&cifs_tcp_ses_lock);
    @@ -3979,19 +3979,18 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
    bool is_binding = false;

    /* only send once per connect */
    + spin_lock(&ses->chan_lock);
    + is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
    + spin_unlock(&ses->chan_lock);
    +
    spin_lock(&cifs_tcp_ses_lock);
    - if ((server->tcpStatus != CifsNeedSessSetup) &&
    - (ses->status == CifsGood)) {
    + if (ses->status == CifsExiting) {
    spin_unlock(&cifs_tcp_ses_lock);
    return 0;
    }
    - server->tcpStatus = CifsInSessSetup;
    + ses->status = CifsInSessSetup;
    spin_unlock(&cifs_tcp_ses_lock);

    - spin_lock(&ses->chan_lock);
    - is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
    - spin_unlock(&ses->chan_lock);
    -
    if (!is_binding) {
    ses->capabilities = server->capabilities;
    if (!linuxExtEnabled)
    @@ -4015,13 +4014,13 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
    if (rc) {
    cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc);
    spin_lock(&cifs_tcp_ses_lock);
    - if (server->tcpStatus == CifsInSessSetup)
    - server->tcpStatus = CifsNeedSessSetup;
    + if (ses->status == CifsInSessSetup)
    + ses->status = CifsNeedSessSetup;
    spin_unlock(&cifs_tcp_ses_lock);
    } else {
    spin_lock(&cifs_tcp_ses_lock);
    - if (server->tcpStatus == CifsInSessSetup)
    - server->tcpStatus = CifsGood;
    + if (ses->status == CifsInSessSetup)
    + ses->status = CifsGood;
    /* Even if one channel is active, session is in good state */
    ses->status = CifsGood;
    spin_unlock(&cifs_tcp_ses_lock);
    diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
    index 1b7ad0c09566..f5321a3500f3 100644
    --- a/fs/cifs/smb2pdu.c
    +++ b/fs/cifs/smb2pdu.c
    @@ -3899,7 +3899,8 @@ SMB2_echo(struct TCP_Server_Info *server)
    cifs_dbg(FYI, "In echo request for conn_id %lld\n", server->conn_id);

    spin_lock(&cifs_tcp_ses_lock);
    - if (server->tcpStatus == CifsNeedNegotiate) {
    + if (server->ops->need_neg &&
    + server->ops->need_neg(server)) {
    spin_unlock(&cifs_tcp_ses_lock);
    /* No need to send echo on newly established connections */
    mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
    diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
    index 2af79093b78b..01b732641edb 100644
    --- a/fs/cifs/smb2transport.c
    +++ b/fs/cifs/smb2transport.c
    @@ -641,7 +641,8 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server)
    if (!is_signed)
    return 0;
    spin_lock(&cifs_tcp_ses_lock);
    - if (server->tcpStatus == CifsNeedNegotiate) {
    + if (server->ops->need_neg &&
    + server->ops->need_neg(server)) {
    spin_unlock(&cifs_tcp_ses_lock);
    return 0;
    }
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-08 00:27    [W:3.670 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site