Skip to content

Commit e94e882

Browse files
paliSteve French
authored andcommitted
cifs: Fix negotiate retry functionality
SMB negotiate retry functionality in cifs_negotiate() is currently broken and does not work when doing socket reconnect. Caller of this function, which is cifs_negotiate_protocol() requires that tcpStatus after successful execution of negotiate callback stay in CifsInNegotiate. But if the CIFSSMBNegotiate() called from cifs_negotiate() fails due to connection issues then tcpStatus is changed as so repeated CIFSSMBNegotiate() call does not help. Fix this problem by moving retrying code from negotiate callback (which is either cifs_negotiate() or smb2_negotiate()) to cifs_negotiate_protocol() which is caller of those callbacks. This allows to properly handle and implement correct transistions between tcpStatus states as function cifs_negotiate_protocol() already handles it. With this change, cifs_negotiate_protocol() now handles also -EAGAIN error set by the RFC1002_NEGATIVE_SESSION_RESPONSE processing after reconnecting with NetBIOS session. Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 665e187 commit e94e882

File tree

3 files changed

+10
-10
lines changed

3 files changed

+10
-10
lines changed

fs/smb/client/connect.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4202,11 +4202,13 @@ int
42024202
cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
42034203
struct TCP_Server_Info *server)
42044204
{
4205+
bool in_retry = false;
42054206
int rc = 0;
42064207

42074208
if (!server->ops->need_neg || !server->ops->negotiate)
42084209
return -ENOSYS;
42094210

4211+
retry:
42104212
/* only send once per connect */
42114213
spin_lock(&server->srv_lock);
42124214
if (server->tcpStatus != CifsGood &&
@@ -4226,6 +4228,14 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
42264228
spin_unlock(&server->srv_lock);
42274229

42284230
rc = server->ops->negotiate(xid, ses, server);
4231+
if (rc == -EAGAIN) {
4232+
/* Allow one retry attempt */
4233+
if (!in_retry) {
4234+
in_retry = true;
4235+
goto retry;
4236+
}
4237+
rc = -EHOSTDOWN;
4238+
}
42294239
if (rc == 0) {
42304240
spin_lock(&server->srv_lock);
42314241
if (server->tcpStatus == CifsInNegotiate)

fs/smb/client/smb1ops.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,6 @@ cifs_negotiate(const unsigned int xid,
426426
{
427427
int rc;
428428
rc = CIFSSMBNegotiate(xid, ses, server);
429-
if (rc == -EAGAIN) {
430-
/* retry only once on 1st time connection */
431-
set_credits(server, 1);
432-
rc = CIFSSMBNegotiate(xid, ses, server);
433-
if (rc == -EAGAIN)
434-
rc = -EHOSTDOWN;
435-
}
436429
return rc;
437430
}
438431

fs/smb/client/smb2ops.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,6 @@ smb2_negotiate(const unsigned int xid,
464464
server->CurrentMid = 0;
465465
spin_unlock(&server->mid_lock);
466466
rc = SMB2_negotiate(xid, ses, server);
467-
/* BB we probably don't need to retry with modern servers */
468-
if (rc == -EAGAIN)
469-
rc = -EHOSTDOWN;
470467
return rc;
471468
}
472469

0 commit comments

Comments
 (0)