@@ -140,6 +140,14 @@ static void smb2_query_server_interfaces(struct work_struct *work)
140
140
(SMB_INTERFACE_POLL_INTERVAL * HZ ));
141
141
}
142
142
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
+
143
151
/*
144
152
* Update the tcpStatus for the server.
145
153
* This is used to signal the cifsd thread to call cifs_reconnect
@@ -153,39 +161,45 @@ void
153
161
cifs_signal_cifsd_for_reconnect (struct TCP_Server_Info * server ,
154
162
bool all_channels )
155
163
{
156
- struct TCP_Server_Info * pserver ;
164
+ struct TCP_Server_Info * nserver ;
157
165
struct cifs_ses * ses ;
166
+ LIST_HEAD (reco );
158
167
int i ;
159
168
160
- /* If server is a channel, select the primary channel */
161
- pserver = SERVER_IS_CHAN (server ) ? server -> primary_server : server ;
162
-
163
169
/* if we need to signal just this channel */
164
170
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 );
169
172
return ;
170
173
}
171
174
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 );
179
183
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 );
185
195
}
186
- spin_unlock (& ses -> chan_lock );
187
196
}
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
+ }
189
203
}
190
204
191
205
/*
0 commit comments