@@ -185,6 +185,14 @@ static void cifs_resolve_server(struct work_struct *work)
185
185
cifs_server_unlock (server );
186
186
}
187
187
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
+
188
196
/*
189
197
* Update the tcpStatus for the server.
190
198
* This is used to signal the cifsd thread to call cifs_reconnect
@@ -198,35 +206,45 @@ void
198
206
cifs_signal_cifsd_for_reconnect (struct TCP_Server_Info * server ,
199
207
bool all_channels )
200
208
{
201
- struct TCP_Server_Info * pserver ;
209
+ struct TCP_Server_Info * nserver ;
202
210
struct cifs_ses * ses ;
211
+ LIST_HEAD (reco );
203
212
int i ;
204
213
205
- /* If server is a channel, select the primary channel */
206
- pserver = CIFS_SERVER_IS_CHAN (server ) ? server -> primary_server : server ;
207
-
208
214
/* if we need to signal just this channel */
209
215
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 );
214
217
return ;
215
218
}
216
219
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 );
226
240
}
227
- spin_unlock (& ses -> chan_lock );
228
241
}
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
+ }
230
248
}
231
249
232
250
/*
0 commit comments