@@ -124,6 +124,14 @@ static void smb2_query_server_interfaces(struct work_struct *work)
124
124
(SMB_INTERFACE_POLL_INTERVAL * HZ ));
125
125
}
126
126
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
+
127
135
/*
128
136
* Update the tcpStatus for the server.
129
137
* This is used to signal the cifsd thread to call cifs_reconnect
@@ -137,39 +145,45 @@ void
137
145
cifs_signal_cifsd_for_reconnect (struct TCP_Server_Info * server ,
138
146
bool all_channels )
139
147
{
140
- struct TCP_Server_Info * pserver ;
148
+ struct TCP_Server_Info * nserver ;
141
149
struct cifs_ses * ses ;
150
+ LIST_HEAD (reco );
142
151
int i ;
143
152
144
- /* If server is a channel, select the primary channel */
145
- pserver = SERVER_IS_CHAN (server ) ? server -> primary_server : server ;
146
-
147
153
/* if we need to signal just this channel */
148
154
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 );
153
156
return ;
154
157
}
155
158
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 );
163
167
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 );
169
179
}
170
- spin_unlock (& ses -> chan_lock );
171
180
}
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
+ }
173
187
}
174
188
175
189
/*
0 commit comments