@@ -166,8 +166,11 @@ static void cifs_resolve_server(struct work_struct *work)
166166 * Mark all sessions and tcons for reconnect.
167167 *
168168 * @server needs to be previously set to CifsNeedReconnect.
169+ *
169170 */
170- static void cifs_mark_tcp_ses_conns_for_reconnect (struct TCP_Server_Info * server )
171+ static void
172+ cifs_mark_tcp_ses_conns_for_reconnect (struct TCP_Server_Info * server ,
173+ bool mark_smb_session )
171174{
172175 unsigned int num_sessions = 0 ;
173176 struct cifs_ses * ses ;
@@ -193,13 +196,16 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
193196 spin_lock (& cifs_tcp_ses_lock );
194197 list_for_each_entry (ses , & pserver -> smb_ses_list , smb_ses_list ) {
195198 spin_lock (& ses -> chan_lock );
196- if (cifs_chan_needs_reconnect (ses , server ))
199+ if (! mark_smb_session && cifs_chan_needs_reconnect (ses , server ))
197200 goto next_session ;
198201
199- cifs_chan_set_need_reconnect (ses , server );
202+ if (mark_smb_session )
203+ CIFS_SET_ALL_CHANS_NEED_RECONNECT (ses );
204+ else
205+ cifs_chan_set_need_reconnect (ses , server );
200206
201207 /* If all channels need reconnect, then tcon needs reconnect */
202- if (!CIFS_ALL_CHANS_NEED_RECONNECT (ses ))
208+ if (!mark_smb_session && ! CIFS_ALL_CHANS_NEED_RECONNECT (ses ))
203209 goto next_session ;
204210
205211 num_sessions ++ ;
@@ -271,16 +277,16 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
271277
272278static bool cifs_tcp_ses_needs_reconnect (struct TCP_Server_Info * server , int num_targets )
273279{
274- spin_lock (& GlobalMid_Lock );
280+ spin_lock (& cifs_tcp_ses_lock );
275281 server -> nr_targets = num_targets ;
276282 if (server -> tcpStatus == CifsExiting ) {
277283 /* the demux thread will exit normally next time through the loop */
278- spin_unlock (& GlobalMid_Lock );
284+ spin_unlock (& cifs_tcp_ses_lock );
279285 wake_up (& server -> response_q );
280286 return false;
281287 }
282288 server -> tcpStatus = CifsNeedReconnect ;
283- spin_unlock (& GlobalMid_Lock );
289+ spin_unlock (& cifs_tcp_ses_lock );
284290 return true;
285291}
286292
@@ -291,15 +297,21 @@ static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num
291297 * mark all smb sessions as reconnecting for tcp session
292298 * reconnect tcp session
293299 * wake up waiters on reconnection? - (not needed currently)
300+ *
301+ * if mark_smb_session is passed as true, unconditionally mark
302+ * the smb session (and tcon) for reconnect as well. This value
303+ * doesn't really matter for non-multichannel scenario.
304+ *
294305 */
295- static int __cifs_reconnect (struct TCP_Server_Info * server )
306+ static int __cifs_reconnect (struct TCP_Server_Info * server ,
307+ bool mark_smb_session )
296308{
297309 int rc = 0 ;
298310
299311 if (!cifs_tcp_ses_needs_reconnect (server , 1 ))
300312 return 0 ;
301313
302- cifs_mark_tcp_ses_conns_for_reconnect (server );
314+ cifs_mark_tcp_ses_conns_for_reconnect (server , mark_smb_session );
303315
304316 do {
305317 try_to_freeze ();
@@ -322,10 +334,10 @@ static int __cifs_reconnect(struct TCP_Server_Info *server)
322334 } else {
323335 atomic_inc (& tcpSesReconnectCount );
324336 set_credits (server , 1 );
325- spin_lock (& GlobalMid_Lock );
337+ spin_lock (& cifs_tcp_ses_lock );
326338 if (server -> tcpStatus != CifsExiting )
327339 server -> tcpStatus = CifsNeedNegotiate ;
328- spin_unlock (& GlobalMid_Lock );
340+ spin_unlock (& cifs_tcp_ses_lock );
329341 cifs_swn_reset_server_dstaddr (server );
330342 mutex_unlock (& server -> srv_mutex );
331343 }
@@ -394,7 +406,9 @@ static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_
394406 return rc ;
395407}
396408
397- static int reconnect_dfs_server (struct TCP_Server_Info * server )
409+ static int
410+ reconnect_dfs_server (struct TCP_Server_Info * server ,
411+ bool mark_smb_session )
398412{
399413 int rc = 0 ;
400414 const char * refpath = server -> current_fullpath + 1 ;
@@ -418,7 +432,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
418432 if (!cifs_tcp_ses_needs_reconnect (server , num_targets ))
419433 return 0 ;
420434
421- cifs_mark_tcp_ses_conns_for_reconnect (server );
435+ cifs_mark_tcp_ses_conns_for_reconnect (server , mark_smb_session );
422436
423437 do {
424438 try_to_freeze ();
@@ -439,10 +453,10 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
439453 */
440454 atomic_inc (& tcpSesReconnectCount );
441455 set_credits (server , 1 );
442- spin_lock (& GlobalMid_Lock );
456+ spin_lock (& cifs_tcp_ses_lock );
443457 if (server -> tcpStatus != CifsExiting )
444458 server -> tcpStatus = CifsNeedNegotiate ;
445- spin_unlock (& GlobalMid_Lock );
459+ spin_unlock (& cifs_tcp_ses_lock );
446460 cifs_swn_reset_server_dstaddr (server );
447461 mutex_unlock (& server -> srv_mutex );
448462 } while (server -> tcpStatus == CifsNeedReconnect );
@@ -460,22 +474,22 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
460474 return rc ;
461475}
462476
463- int cifs_reconnect (struct TCP_Server_Info * server )
477+ int cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
464478{
465479 /* If tcp session is not an dfs connection, then reconnect to last target server */
466480 spin_lock (& cifs_tcp_ses_lock );
467481 if (!server -> is_dfs_conn || !server -> origin_fullpath || !server -> leaf_fullpath ) {
468482 spin_unlock (& cifs_tcp_ses_lock );
469- return __cifs_reconnect (server );
483+ return __cifs_reconnect (server , mark_smb_session );
470484 }
471485 spin_unlock (& cifs_tcp_ses_lock );
472486
473- return reconnect_dfs_server (server );
487+ return reconnect_dfs_server (server , mark_smb_session );
474488}
475489#else
476- int cifs_reconnect (struct TCP_Server_Info * server )
490+ int cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
477491{
478- return __cifs_reconnect (server );
492+ return __cifs_reconnect (server , mark_smb_session );
479493}
480494#endif
481495
@@ -563,7 +577,7 @@ server_unresponsive(struct TCP_Server_Info *server)
563577 time_after (jiffies , server -> lstrp + 3 * server -> echo_interval )) {
564578 cifs_server_dbg (VFS , "has not responded in %lu seconds. Reconnecting...\n" ,
565579 (3 * server -> echo_interval ) / HZ );
566- cifs_reconnect (server );
580+ cifs_reconnect (server , false );
567581 return true;
568582 }
569583
@@ -599,7 +613,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
599613
600614 /* reconnect if no credits and no requests in flight */
601615 if (zero_credits (server )) {
602- cifs_reconnect (server );
616+ cifs_reconnect (server , false );
603617 return - ECONNABORTED ;
604618 }
605619
@@ -614,7 +628,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
614628 return - ESHUTDOWN ;
615629
616630 if (server -> tcpStatus == CifsNeedReconnect ) {
617- cifs_reconnect (server );
631+ cifs_reconnect (server , false );
618632 return - ECONNABORTED ;
619633 }
620634
@@ -633,7 +647,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
633647
634648 if (length <= 0 ) {
635649 cifs_dbg (FYI , "Received no data or error: %d\n" , length );
636- cifs_reconnect (server );
650+ cifs_reconnect (server , false );
637651 return - ECONNABORTED ;
638652 }
639653 }
@@ -712,11 +726,11 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
712726 * initialize frame).
713727 */
714728 cifs_set_port ((struct sockaddr * )& server -> dstaddr , CIFS_PORT );
715- cifs_reconnect (server );
729+ cifs_reconnect (server , true );
716730 break ;
717731 default :
718732 cifs_server_dbg (VFS , "RFC 1002 unknown response type 0x%x\n" , type );
719- cifs_reconnect (server );
733+ cifs_reconnect (server , true );
720734 }
721735
722736 return false;
@@ -889,7 +903,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
889903 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE (server ) -
890904 server -> vals -> header_preamble_size ) {
891905 cifs_server_dbg (VFS , "SMB response too long (%u bytes)\n" , pdu_length );
892- cifs_reconnect (server );
906+ cifs_reconnect (server , true );
893907 return - ECONNABORTED ;
894908 }
895909
@@ -936,7 +950,7 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
936950
937951 if (server -> ops -> is_session_expired &&
938952 server -> ops -> is_session_expired (buf )) {
939- cifs_reconnect (server );
953+ cifs_reconnect (server , true );
940954 return -1 ;
941955 }
942956
@@ -1040,7 +1054,7 @@ cifs_demultiplex_thread(void *p)
10401054 server -> vals -> header_preamble_size ) {
10411055 cifs_server_dbg (VFS , "SMB response too short (%u bytes)\n" ,
10421056 server -> pdu_size );
1043- cifs_reconnect (server );
1057+ cifs_reconnect (server , true );
10441058 continue ;
10451059 }
10461060
@@ -1092,7 +1106,7 @@ cifs_demultiplex_thread(void *p)
10921106 server -> ops -> is_status_io_timeout (buf )) {
10931107 num_io_timeout ++ ;
10941108 if (num_io_timeout > NUM_STATUS_IO_TIMEOUT ) {
1095- cifs_reconnect (server );
1109+ cifs_reconnect (server , false );
10961110 num_io_timeout = 0 ;
10971111 continue ;
10981112 }
0 commit comments