@@ -140,6 +140,14 @@ static void smb2_query_server_interfaces(struct work_struct *work)
140140 (SMB_INTERFACE_POLL_INTERVAL * HZ ));
141141}
142142
143+ #define set_need_reco (server ) \
144+ do { \
145+ spin_lock(&server->srv_lock); \
146+ if (server->tcpStatus != CifsExiting) \
147+ server->tcpStatus = CifsNeedReconnect; \
148+ spin_unlock(&server->srv_lock); \
149+ } while (0)
150+
143151/*
144152 * Update the tcpStatus for the server.
145153 * This is used to signal the cifsd thread to call cifs_reconnect
@@ -153,39 +161,45 @@ void
153161cifs_signal_cifsd_for_reconnect (struct TCP_Server_Info * server ,
154162 bool all_channels )
155163{
156- struct TCP_Server_Info * pserver ;
164+ struct TCP_Server_Info * nserver ;
157165 struct cifs_ses * ses ;
166+ LIST_HEAD (reco );
158167 int i ;
159168
160- /* If server is a channel, select the primary channel */
161- pserver = SERVER_IS_CHAN (server ) ? server -> primary_server : server ;
162-
163169 /* if we need to signal just this channel */
164170 if (!all_channels ) {
165- spin_lock (& server -> srv_lock );
166- if (server -> tcpStatus != CifsExiting )
167- server -> tcpStatus = CifsNeedReconnect ;
168- spin_unlock (& server -> srv_lock );
171+ set_need_reco (server );
169172 return ;
170173 }
171174
172- spin_lock (& cifs_tcp_ses_lock );
173- list_for_each_entry (ses , & pserver -> smb_ses_list , smb_ses_list ) {
174- if (cifs_ses_exiting (ses ))
175- continue ;
176- spin_lock (& ses -> chan_lock );
177- for (i = 0 ; i < ses -> chan_count ; i ++ ) {
178- if (!ses -> chans [i ].server )
175+ if (SERVER_IS_CHAN (server ))
176+ server = server -> primary_server ;
177+ scoped_guard (spinlock , & cifs_tcp_ses_lock ) {
178+ set_need_reco (server );
179+ list_for_each_entry (ses , & server -> smb_ses_list , smb_ses_list ) {
180+ spin_lock (& ses -> ses_lock );
181+ if (ses -> ses_status == SES_EXITING ) {
182+ spin_unlock (& ses -> ses_lock );
179183 continue ;
180-
181- spin_lock (& ses -> chans [i ].server -> srv_lock );
182- if (ses -> chans [i ].server -> tcpStatus != CifsExiting )
183- ses -> chans [i ].server -> tcpStatus = CifsNeedReconnect ;
184- spin_unlock (& ses -> chans [i ].server -> srv_lock );
184+ }
185+ spin_lock (& ses -> chan_lock );
186+ for (i = 1 ; i < ses -> chan_count ; i ++ ) {
187+ nserver = ses -> chans [i ].server ;
188+ if (!nserver )
189+ continue ;
190+ nserver -> srv_count ++ ;
191+ list_add (& nserver -> rlist , & reco );
192+ }
193+ spin_unlock (& ses -> chan_lock );
194+ spin_unlock (& ses -> ses_lock );
185195 }
186- spin_unlock (& ses -> chan_lock );
187196 }
188- spin_unlock (& cifs_tcp_ses_lock );
197+
198+ list_for_each_entry_safe (server , nserver , & reco , rlist ) {
199+ list_del_init (& server -> rlist );
200+ set_need_reco (server );
201+ cifs_put_tcp_session (server , 0 );
202+ }
189203}
190204
191205/*
0 commit comments