aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifssmb.c12
-rw-r--r--fs/cifs/connect.c3
-rw-r--r--fs/cifs/smb2pdu.c12
3 files changed, 26 insertions, 1 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 48455afefec8..7cbe28315971 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -178,6 +178,18 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
178 * reconnect the same SMB session 178 * reconnect the same SMB session
179 */ 179 */
180 mutex_lock(&ses->session_mutex); 180 mutex_lock(&ses->session_mutex);
181
182 /*
183 * Recheck after acquire mutex. If another thread is negotiating
184 * and the server never sends an answer the socket will be closed
185 * and tcpStatus set to reconnect.
186 */
187 if (server->tcpStatus == CifsNeedReconnect) {
188 rc = -EHOSTDOWN;
189 mutex_unlock(&ses->session_mutex);
190 goto out;
191 }
192
181 rc = cifs_negotiate_protocol(0, ses); 193 rc = cifs_negotiate_protocol(0, ses);
182 if (rc == 0 && ses->need_reconnect) 194 if (rc == 0 && ses->need_reconnect)
183 rc = cifs_setup_session(0, ses, nls_codepage); 195 rc = cifs_setup_session(0, ses, nls_codepage);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 83a8f52cd879..5aa2d278ca84 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -509,7 +509,8 @@ server_unresponsive(struct TCP_Server_Info *server)
509 * 65s kernel_recvmsg times out, and we see that we haven't gotten 509 * 65s kernel_recvmsg times out, and we see that we haven't gotten
510 * a response in >60s. 510 * a response in >60s.
511 */ 511 */
512 if (server->tcpStatus == CifsGood && 512 if ((server->tcpStatus == CifsGood ||
513 server->tcpStatus == CifsNeedNegotiate) &&
513 time_after(jiffies, server->lstrp + 2 * server->echo_interval)) { 514 time_after(jiffies, server->lstrp + 2 * server->echo_interval)) {
514 cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", 515 cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n",
515 server->hostname, (2 * server->echo_interval) / HZ); 516 server->hostname, (2 * server->echo_interval) / HZ);
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index d7595e735304..5531e7ee1210 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -238,6 +238,18 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
238 * the same SMB session 238 * the same SMB session
239 */ 239 */
240 mutex_lock(&tcon->ses->session_mutex); 240 mutex_lock(&tcon->ses->session_mutex);
241
242 /*
243 * Recheck after acquire mutex. If another thread is negotiating
244 * and the server never sends an answer the socket will be closed
245 * and tcpStatus set to reconnect.
246 */
247 if (server->tcpStatus == CifsNeedReconnect) {
248 rc = -EHOSTDOWN;
249 mutex_unlock(&tcon->ses->session_mutex);
250 goto out;
251 }
252
241 rc = cifs_negotiate_protocol(0, tcon->ses); 253 rc = cifs_negotiate_protocol(0, tcon->ses);
242 if (!rc && tcon->ses->need_reconnect) 254 if (!rc && tcon->ses->need_reconnect)
243 rc = cifs_setup_session(0, tcon->ses, nls_codepage); 255 rc = cifs_setup_session(0, tcon->ses, nls_codepage);