@@ -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