@@ -185,6 +185,14 @@ static void cifs_resolve_server(struct work_struct *work)
185185 cifs_server_unlock (server );
186186}
187187
188+ #define set_need_reco (server ) \
189+ do { \
190+ spin_lock(&server->srv_lock); \
191+ if (server->tcpStatus != CifsExiting) \
192+ server->tcpStatus = CifsNeedReconnect; \
193+ spin_unlock(&server->srv_lock); \
194+ } while (0)
195+
188196/*
189197 * Update the tcpStatus for the server.
190198 * This is used to signal the cifsd thread to call cifs_reconnect
@@ -198,35 +206,45 @@ void
198206cifs_signal_cifsd_for_reconnect (struct TCP_Server_Info * server ,
199207 bool all_channels )
200208{
201- struct TCP_Server_Info * pserver ;
209+ struct TCP_Server_Info * nserver ;
202210 struct cifs_ses * ses ;
211+ LIST_HEAD (reco );
203212 int i ;
204213
205- /* If server is a channel, select the primary channel */
206- pserver = CIFS_SERVER_IS_CHAN (server ) ? server -> primary_server : server ;
207-
208214 /* if we need to signal just this channel */
209215 if (!all_channels ) {
210- spin_lock (& server -> srv_lock );
211- if (server -> tcpStatus != CifsExiting )
212- server -> tcpStatus = CifsNeedReconnect ;
213- spin_unlock (& server -> srv_lock );
216+ set_need_reco (server );
214217 return ;
215218 }
216219
217- spin_lock (& cifs_tcp_ses_lock );
218- list_for_each_entry (ses , & pserver -> smb_ses_list , smb_ses_list ) {
219- if (cifs_ses_exiting (ses ))
220- continue ;
221- spin_lock (& ses -> chan_lock );
222- for (i = 0 ; i < ses -> chan_count ; i ++ ) {
223- spin_lock (& ses -> chans [i ].server -> srv_lock );
224- ses -> chans [i ].server -> tcpStatus = CifsNeedReconnect ;
225- spin_unlock (& ses -> chans [i ].server -> srv_lock );
220+ if (CIFS_SERVER_IS_CHAN (server ))
221+ server = server -> primary_server ;
222+ scoped_guard (spinlock , & cifs_tcp_ses_lock ) {
223+ set_need_reco (server );
224+ list_for_each_entry (ses , & server -> smb_ses_list , smb_ses_list ) {
225+ spin_lock (& ses -> ses_lock );
226+ if (ses -> ses_status == SES_EXITING ) {
227+ spin_unlock (& ses -> ses_lock );
228+ continue ;
229+ }
230+ spin_lock (& ses -> chan_lock );
231+ for (i = 1 ; i < ses -> chan_count ; i ++ ) {
232+ nserver = ses -> chans [i ].server ;
233+ if (!nserver )
234+ continue ;
235+ nserver -> srv_count ++ ;
236+ list_add (& nserver -> rlist , & reco );
237+ }
238+ spin_unlock (& ses -> chan_lock );
239+ spin_unlock (& ses -> ses_lock );
226240 }
227- spin_unlock (& ses -> chan_lock );
228241 }
229- spin_unlock (& cifs_tcp_ses_lock );
242+
243+ list_for_each_entry_safe (server , nserver , & reco , rlist ) {
244+ list_del_init (& server -> rlist );
245+ set_need_reco (server );
246+ cifs_put_tcp_session (server , 0 );
247+ }
230248}
231249
232250/*
0 commit comments