Skip to content

Commit

Permalink
Fix reconnect to not defer smb3 session reconnect long after socket r…
Browse files Browse the repository at this point in the history
…econnect

Azure server blocks clients that open a socket and don't do anything on it.
In our reconnect scenarios, we can reconnect the tcp session and
detect the socket is available but we defer the negprot and SMB3 session
setup and tree connect reconnection until the next i/o is requested, but
this looks suspicous to some servers who expect SMB3 negprog and session
setup soon after a socket is created.

In the echo thread, reconnect SMB3 sessions and tree connections
that are disconnected.  A later patch will replay persistent (and
resilient) handle opens.

CC: Stable <[email protected]>
Signed-off-by: Steve French <[email protected]>
Acked-by: Pavel Shilovsky <[email protected]>
  • Loading branch information
smfrench committed Jun 24, 2016
1 parent a6b6bef commit 4fcd181
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
4 changes: 3 additions & 1 deletion fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,9 @@ cifs_echo_request(struct work_struct *work)
* server->ops->need_neg() == true. Also, no need to ping if
* we got a response recently.
*/
if (!server->ops->need_neg || server->ops->need_neg(server) ||

if (server->tcpStatus == CifsNeedReconnect ||
server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
(server->ops->can_echo && !server->ops->can_echo(server)) ||
time_before(jiffies, server->lstrp + echo_interval - HZ))
goto requeue_echo;
Expand Down
27 changes: 27 additions & 0 deletions fs/cifs/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,33 @@ SMB2_echo(struct TCP_Server_Info *server)

cifs_dbg(FYI, "In echo request\n");

if (server->tcpStatus == CifsNeedNegotiate) {
struct list_head *tmp, *tmp2;
struct cifs_ses *ses;
struct cifs_tcon *tcon;

cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
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(tmp2, &ses->tcon_list) {
tcon = list_entry(tmp2, struct cifs_tcon,
tcon_list);
/* add check for persistent handle reconnect */
if (tcon && tcon->need_reconnect) {
spin_unlock(&cifs_tcp_ses_lock);
rc = smb2_reconnect(SMB2_ECHO, tcon);
spin_lock(&cifs_tcp_ses_lock);
}
}
}
spin_unlock(&cifs_tcp_ses_lock);
}

/* if no session, renegotiate failed above */
if (server->tcpStatus == CifsNeedNegotiate)
return -EIO;

rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
if (rc)
return rc;
Expand Down

0 comments on commit 4fcd181

Please sign in to comment.