@@ -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