Skip to content

Commit 4ce7aa4

Browse files
smfrenchgregkh
authored andcommitted
Fix reconnect to not defer smb3 session reconnect long after socket reconnect
commit 4fcd1813e6404dd4420c7d12fb483f9320f0bf93 upstream. 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. Signed-off-by: Steve French <steve.french@primarydata.com> Acked-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent ddbe16b commit 4ce7aa4

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

fs/cifs/connect.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,9 @@ cifs_echo_request(struct work_struct *work)
425425
* server->ops->need_neg() == true. Also, no need to ping if
426426
* we got a response recently.
427427
*/
428-
if (!server->ops->need_neg || server->ops->need_neg(server) ||
428+
429+
if (server->tcpStatus == CifsNeedReconnect ||
430+
server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
429431
(server->ops->can_echo && !server->ops->can_echo(server)) ||
430432
time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
431433
goto requeue_echo;

fs/cifs/smb2pdu.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,33 @@ SMB2_echo(struct TCP_Server_Info *server)
18201820

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

1823+
if (server->tcpStatus == CifsNeedNegotiate) {
1824+
struct list_head *tmp, *tmp2;
1825+
struct cifs_ses *ses;
1826+
struct cifs_tcon *tcon;
1827+
1828+
cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
1829+
spin_lock(&cifs_tcp_ses_lock);
1830+
list_for_each(tmp, &server->smb_ses_list) {
1831+
ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
1832+
list_for_each(tmp2, &ses->tcon_list) {
1833+
tcon = list_entry(tmp2, struct cifs_tcon,
1834+
tcon_list);
1835+
/* add check for persistent handle reconnect */
1836+
if (tcon && tcon->need_reconnect) {
1837+
spin_unlock(&cifs_tcp_ses_lock);
1838+
rc = smb2_reconnect(SMB2_ECHO, tcon);
1839+
spin_lock(&cifs_tcp_ses_lock);
1840+
}
1841+
}
1842+
}
1843+
spin_unlock(&cifs_tcp_ses_lock);
1844+
}
1845+
1846+
/* if no session, renegotiate failed above */
1847+
if (server->tcpStatus == CifsNeedNegotiate)
1848+
return -EIO;
1849+
18231850
rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
18241851
if (rc)
18251852
return rc;

0 commit comments

Comments
 (0)