Skip to content

Commit a7ea35b

Browse files
committed
Merge tag 'v6.14-rc7-smb3-client-fix' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client fix from Steve French: "smb3 client reconnect fix" * tag 'v6.14-rc7-smb3-client-fix' of git://git.samba.org/sfrench/cifs-2.6: smb: client: don't retry IO on failed negprotos with soft mounts
2 parents a1cffe8 + 7643dbd commit a7ea35b

File tree

2 files changed

+69
-73
lines changed

2 files changed

+69
-73
lines changed

fs/smb/client/cifssmb.c

+27-19
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,23 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
114114

115115
mutex_lock(&ses->session_mutex);
116116
/*
117-
* Recheck after acquire mutex. If another thread is negotiating
118-
* and the server never sends an answer the socket will be closed
119-
* and tcpStatus set to reconnect.
117+
* Handle the case where a concurrent thread failed to negotiate or
118+
* killed a channel.
120119
*/
121120
spin_lock(&server->srv_lock);
122-
if (server->tcpStatus == CifsNeedReconnect) {
121+
switch (server->tcpStatus) {
122+
case CifsExiting:
123123
spin_unlock(&server->srv_lock);
124124
mutex_unlock(&ses->session_mutex);
125-
126-
if (tcon->retry)
127-
goto again;
128-
rc = -EHOSTDOWN;
129-
goto out;
125+
return -EHOSTDOWN;
126+
case CifsNeedReconnect:
127+
spin_unlock(&server->srv_lock);
128+
mutex_unlock(&ses->session_mutex);
129+
if (!tcon->retry)
130+
return -EHOSTDOWN;
131+
goto again;
132+
default:
133+
break;
130134
}
131135
spin_unlock(&server->srv_lock);
132136

@@ -152,16 +156,20 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
152156
spin_unlock(&ses->ses_lock);
153157

154158
rc = cifs_negotiate_protocol(0, ses, server);
155-
if (!rc) {
156-
rc = cifs_setup_session(0, ses, server, ses->local_nls);
157-
if ((rc == -EACCES) || (rc == -EHOSTDOWN) || (rc == -EKEYREVOKED)) {
158-
/*
159-
* Try alternate password for next reconnect if an alternate
160-
* password is available.
161-
*/
162-
if (ses->password2)
163-
swap(ses->password2, ses->password);
164-
}
159+
if (rc) {
160+
mutex_unlock(&ses->session_mutex);
161+
if (!tcon->retry)
162+
return -EHOSTDOWN;
163+
goto again;
164+
}
165+
rc = cifs_setup_session(0, ses, server, ses->local_nls);
166+
if ((rc == -EACCES) || (rc == -EHOSTDOWN) || (rc == -EKEYREVOKED)) {
167+
/*
168+
* Try alternate password for next reconnect if an alternate
169+
* password is available.
170+
*/
171+
if (ses->password2)
172+
swap(ses->password2, ses->password);
165173
}
166174

167175
/* do we need to reconnect tcon? */

fs/smb/client/smb2pdu.c

+42-54
Original file line numberDiff line numberDiff line change
@@ -300,32 +300,23 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
300300

301301
mutex_lock(&ses->session_mutex);
302302
/*
303-
* if this is called by delayed work, and the channel has been disabled
304-
* in parallel, the delayed work can continue to execute in parallel
305-
* there's a chance that this channel may not exist anymore
303+
* Handle the case where a concurrent thread failed to negotiate or
304+
* killed a channel.
306305
*/
307306
spin_lock(&server->srv_lock);
308-
if (server->tcpStatus == CifsExiting) {
307+
switch (server->tcpStatus) {
308+
case CifsExiting:
309309
spin_unlock(&server->srv_lock);
310310
mutex_unlock(&ses->session_mutex);
311-
rc = -EHOSTDOWN;
312-
goto out;
313-
}
314-
315-
/*
316-
* Recheck after acquire mutex. If another thread is negotiating
317-
* and the server never sends an answer the socket will be closed
318-
* and tcpStatus set to reconnect.
319-
*/
320-
if (server->tcpStatus == CifsNeedReconnect) {
311+
return -EHOSTDOWN;
312+
case CifsNeedReconnect:
321313
spin_unlock(&server->srv_lock);
322314
mutex_unlock(&ses->session_mutex);
323-
324-
if (tcon->retry)
325-
goto again;
326-
327-
rc = -EHOSTDOWN;
328-
goto out;
315+
if (!tcon->retry)
316+
return -EHOSTDOWN;
317+
goto again;
318+
default:
319+
break;
329320
}
330321
spin_unlock(&server->srv_lock);
331322

@@ -350,43 +341,41 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
350341
spin_unlock(&ses->ses_lock);
351342

352343
rc = cifs_negotiate_protocol(0, ses, server);
353-
if (!rc) {
354-
/*
355-
* if server stopped supporting multichannel
356-
* and the first channel reconnected, disable all the others.
357-
*/
358-
if (ses->chan_count > 1 &&
359-
!(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
360-
rc = cifs_chan_skip_or_disable(ses, server,
361-
from_reconnect);
362-
if (rc) {
363-
mutex_unlock(&ses->session_mutex);
364-
goto out;
365-
}
366-
}
367-
368-
rc = cifs_setup_session(0, ses, server, ses->local_nls);
369-
if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED)) {
370-
/*
371-
* Try alternate password for next reconnect (key rotation
372-
* could be enabled on the server e.g.) if an alternate
373-
* password is available and the current password is expired,
374-
* but do not swap on non pwd related errors like host down
375-
*/
376-
if (ses->password2)
377-
swap(ses->password2, ses->password);
378-
}
379-
380-
if ((rc == -EACCES) && !tcon->retry) {
381-
mutex_unlock(&ses->session_mutex);
382-
rc = -EHOSTDOWN;
383-
goto failed;
384-
} else if (rc) {
344+
if (rc) {
345+
mutex_unlock(&ses->session_mutex);
346+
if (!tcon->retry)
347+
return -EHOSTDOWN;
348+
goto again;
349+
}
350+
/*
351+
* if server stopped supporting multichannel
352+
* and the first channel reconnected, disable all the others.
353+
*/
354+
if (ses->chan_count > 1 &&
355+
!(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
356+
rc = cifs_chan_skip_or_disable(ses, server,
357+
from_reconnect);
358+
if (rc) {
385359
mutex_unlock(&ses->session_mutex);
386360
goto out;
387361
}
388-
} else {
362+
}
363+
364+
rc = cifs_setup_session(0, ses, server, ses->local_nls);
365+
if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED)) {
366+
/*
367+
* Try alternate password for next reconnect (key rotation
368+
* could be enabled on the server e.g.) if an alternate
369+
* password is available and the current password is expired,
370+
* but do not swap on non pwd related errors like host down
371+
*/
372+
if (ses->password2)
373+
swap(ses->password2, ses->password);
374+
}
375+
if (rc) {
389376
mutex_unlock(&ses->session_mutex);
377+
if (rc == -EACCES && !tcon->retry)
378+
return -EHOSTDOWN;
390379
goto out;
391380
}
392381

@@ -490,7 +479,6 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
490479
case SMB2_IOCTL:
491480
rc = -EAGAIN;
492481
}
493-
failed:
494482
return rc;
495483
}
496484

0 commit comments

Comments
 (0)