@@ -124,6 +124,14 @@ static void smb2_query_server_interfaces(struct work_struct *work)
124124 (SMB_INTERFACE_POLL_INTERVAL * HZ ));
125125}
126126
127+ #define set_need_reco (server ) \
128+ do { \
129+ spin_lock(&server->srv_lock); \
130+ if (server->tcpStatus != CifsExiting) \
131+ server->tcpStatus = CifsNeedReconnect; \
132+ spin_unlock(&server->srv_lock); \
133+ } while (0)
134+
127135/*
128136 * Update the tcpStatus for the server.
129137 * This is used to signal the cifsd thread to call cifs_reconnect
@@ -137,39 +145,45 @@ void
137145cifs_signal_cifsd_for_reconnect (struct TCP_Server_Info * server ,
138146 bool all_channels )
139147{
140- struct TCP_Server_Info * pserver ;
148+ struct TCP_Server_Info * nserver ;
141149 struct cifs_ses * ses ;
150+ LIST_HEAD (reco );
142151 int i ;
143152
144- /* If server is a channel, select the primary channel */
145- pserver = SERVER_IS_CHAN (server ) ? server -> primary_server : server ;
146-
147153 /* if we need to signal just this channel */
148154 if (!all_channels ) {
149- spin_lock (& server -> srv_lock );
150- if (server -> tcpStatus != CifsExiting )
151- server -> tcpStatus = CifsNeedReconnect ;
152- spin_unlock (& server -> srv_lock );
155+ set_need_reco (server );
153156 return ;
154157 }
155158
156- spin_lock (& cifs_tcp_ses_lock );
157- list_for_each_entry (ses , & pserver -> smb_ses_list , smb_ses_list ) {
158- if (cifs_ses_exiting (ses ))
159- continue ;
160- spin_lock (& ses -> chan_lock );
161- for (i = 0 ; i < ses -> chan_count ; i ++ ) {
162- if (!ses -> chans [i ].server )
159+ if (SERVER_IS_CHAN (server ))
160+ server = server -> primary_server ;
161+ scoped_guard (spinlock , & cifs_tcp_ses_lock ) {
162+ set_need_reco (server );
163+ list_for_each_entry (ses , & server -> smb_ses_list , smb_ses_list ) {
164+ spin_lock (& ses -> ses_lock );
165+ if (ses -> ses_status == SES_EXITING ) {
166+ spin_unlock (& ses -> ses_lock );
163167 continue ;
164-
165- spin_lock (& ses -> chans [i ].server -> srv_lock );
166- if (ses -> chans [i ].server -> tcpStatus != CifsExiting )
167- ses -> chans [i ].server -> tcpStatus = CifsNeedReconnect ;
168- spin_unlock (& ses -> chans [i ].server -> srv_lock );
168+ }
169+ spin_lock (& ses -> chan_lock );
170+ for (i = 1 ; i < ses -> chan_count ; i ++ ) {
171+ nserver = ses -> chans [i ].server ;
172+ if (!nserver )
173+ continue ;
174+ nserver -> srv_count ++ ;
175+ list_add (& nserver -> rlist , & reco );
176+ }
177+ spin_unlock (& ses -> chan_lock );
178+ spin_unlock (& ses -> ses_lock );
169179 }
170- spin_unlock (& ses -> chan_lock );
171180 }
172- spin_unlock (& cifs_tcp_ses_lock );
181+
182+ list_for_each_entry_safe (server , nserver , & reco , rlist ) {
183+ list_del_init (& server -> rlist );
184+ set_need_reco (server );
185+ cifs_put_tcp_session (server , 0 );
186+ }
173187}
174188
175189/*
0 commit comments