@@ -166,8 +166,11 @@ static void cifs_resolve_server(struct work_struct *work)
166
166
* Mark all sessions and tcons for reconnect.
167
167
*
168
168
* @server needs to be previously set to CifsNeedReconnect.
169
+ *
169
170
*/
170
- static void cifs_mark_tcp_ses_conns_for_reconnect (struct TCP_Server_Info * server )
171
+ static void
172
+ cifs_mark_tcp_ses_conns_for_reconnect (struct TCP_Server_Info * server ,
173
+ bool mark_smb_session )
171
174
{
172
175
unsigned int num_sessions = 0 ;
173
176
struct cifs_ses * ses ;
@@ -193,13 +196,16 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
193
196
spin_lock (& cifs_tcp_ses_lock );
194
197
list_for_each_entry (ses , & pserver -> smb_ses_list , smb_ses_list ) {
195
198
spin_lock (& ses -> chan_lock );
196
- if (cifs_chan_needs_reconnect (ses , server ))
199
+ if (! mark_smb_session && cifs_chan_needs_reconnect (ses , server ))
197
200
goto next_session ;
198
201
199
- cifs_chan_set_need_reconnect (ses , server );
202
+ if (mark_smb_session )
203
+ CIFS_SET_ALL_CHANS_NEED_RECONNECT (ses );
204
+ else
205
+ cifs_chan_set_need_reconnect (ses , server );
200
206
201
207
/* If all channels need reconnect, then tcon needs reconnect */
202
- if (!CIFS_ALL_CHANS_NEED_RECONNECT (ses ))
208
+ if (!mark_smb_session && ! CIFS_ALL_CHANS_NEED_RECONNECT (ses ))
203
209
goto next_session ;
204
210
205
211
num_sessions ++ ;
@@ -271,16 +277,16 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
271
277
272
278
static bool cifs_tcp_ses_needs_reconnect (struct TCP_Server_Info * server , int num_targets )
273
279
{
274
- spin_lock (& GlobalMid_Lock );
280
+ spin_lock (& cifs_tcp_ses_lock );
275
281
server -> nr_targets = num_targets ;
276
282
if (server -> tcpStatus == CifsExiting ) {
277
283
/* the demux thread will exit normally next time through the loop */
278
- spin_unlock (& GlobalMid_Lock );
284
+ spin_unlock (& cifs_tcp_ses_lock );
279
285
wake_up (& server -> response_q );
280
286
return false;
281
287
}
282
288
server -> tcpStatus = CifsNeedReconnect ;
283
- spin_unlock (& GlobalMid_Lock );
289
+ spin_unlock (& cifs_tcp_ses_lock );
284
290
return true;
285
291
}
286
292
@@ -291,15 +297,21 @@ static bool cifs_tcp_ses_needs_reconnect(struct TCP_Server_Info *server, int num
291
297
* mark all smb sessions as reconnecting for tcp session
292
298
* reconnect tcp session
293
299
* wake up waiters on reconnection? - (not needed currently)
300
+ *
301
+ * if mark_smb_session is passed as true, unconditionally mark
302
+ * the smb session (and tcon) for reconnect as well. This value
303
+ * doesn't really matter for non-multichannel scenario.
304
+ *
294
305
*/
295
- static int __cifs_reconnect (struct TCP_Server_Info * server )
306
+ static int __cifs_reconnect (struct TCP_Server_Info * server ,
307
+ bool mark_smb_session )
296
308
{
297
309
int rc = 0 ;
298
310
299
311
if (!cifs_tcp_ses_needs_reconnect (server , 1 ))
300
312
return 0 ;
301
313
302
- cifs_mark_tcp_ses_conns_for_reconnect (server );
314
+ cifs_mark_tcp_ses_conns_for_reconnect (server , mark_smb_session );
303
315
304
316
do {
305
317
try_to_freeze ();
@@ -322,10 +334,10 @@ static int __cifs_reconnect(struct TCP_Server_Info *server)
322
334
} else {
323
335
atomic_inc (& tcpSesReconnectCount );
324
336
set_credits (server , 1 );
325
- spin_lock (& GlobalMid_Lock );
337
+ spin_lock (& cifs_tcp_ses_lock );
326
338
if (server -> tcpStatus != CifsExiting )
327
339
server -> tcpStatus = CifsNeedNegotiate ;
328
- spin_unlock (& GlobalMid_Lock );
340
+ spin_unlock (& cifs_tcp_ses_lock );
329
341
cifs_swn_reset_server_dstaddr (server );
330
342
mutex_unlock (& server -> srv_mutex );
331
343
}
@@ -394,7 +406,9 @@ static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_
394
406
return rc ;
395
407
}
396
408
397
- static int reconnect_dfs_server (struct TCP_Server_Info * server )
409
+ static int
410
+ reconnect_dfs_server (struct TCP_Server_Info * server ,
411
+ bool mark_smb_session )
398
412
{
399
413
int rc = 0 ;
400
414
const char * refpath = server -> current_fullpath + 1 ;
@@ -418,7 +432,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
418
432
if (!cifs_tcp_ses_needs_reconnect (server , num_targets ))
419
433
return 0 ;
420
434
421
- cifs_mark_tcp_ses_conns_for_reconnect (server );
435
+ cifs_mark_tcp_ses_conns_for_reconnect (server , mark_smb_session );
422
436
423
437
do {
424
438
try_to_freeze ();
@@ -439,10 +453,10 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
439
453
*/
440
454
atomic_inc (& tcpSesReconnectCount );
441
455
set_credits (server , 1 );
442
- spin_lock (& GlobalMid_Lock );
456
+ spin_lock (& cifs_tcp_ses_lock );
443
457
if (server -> tcpStatus != CifsExiting )
444
458
server -> tcpStatus = CifsNeedNegotiate ;
445
- spin_unlock (& GlobalMid_Lock );
459
+ spin_unlock (& cifs_tcp_ses_lock );
446
460
cifs_swn_reset_server_dstaddr (server );
447
461
mutex_unlock (& server -> srv_mutex );
448
462
} while (server -> tcpStatus == CifsNeedReconnect );
@@ -460,22 +474,22 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
460
474
return rc ;
461
475
}
462
476
463
- int cifs_reconnect (struct TCP_Server_Info * server )
477
+ int cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
464
478
{
465
479
/* If tcp session is not an dfs connection, then reconnect to last target server */
466
480
spin_lock (& cifs_tcp_ses_lock );
467
481
if (!server -> is_dfs_conn || !server -> origin_fullpath || !server -> leaf_fullpath ) {
468
482
spin_unlock (& cifs_tcp_ses_lock );
469
- return __cifs_reconnect (server );
483
+ return __cifs_reconnect (server , mark_smb_session );
470
484
}
471
485
spin_unlock (& cifs_tcp_ses_lock );
472
486
473
- return reconnect_dfs_server (server );
487
+ return reconnect_dfs_server (server , mark_smb_session );
474
488
}
475
489
#else
476
- int cifs_reconnect (struct TCP_Server_Info * server )
490
+ int cifs_reconnect (struct TCP_Server_Info * server , bool mark_smb_session )
477
491
{
478
- return __cifs_reconnect (server );
492
+ return __cifs_reconnect (server , mark_smb_session );
479
493
}
480
494
#endif
481
495
@@ -563,7 +577,7 @@ server_unresponsive(struct TCP_Server_Info *server)
563
577
time_after (jiffies , server -> lstrp + 3 * server -> echo_interval )) {
564
578
cifs_server_dbg (VFS , "has not responded in %lu seconds. Reconnecting...\n" ,
565
579
(3 * server -> echo_interval ) / HZ );
566
- cifs_reconnect (server );
580
+ cifs_reconnect (server , false );
567
581
return true;
568
582
}
569
583
@@ -599,7 +613,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
599
613
600
614
/* reconnect if no credits and no requests in flight */
601
615
if (zero_credits (server )) {
602
- cifs_reconnect (server );
616
+ cifs_reconnect (server , false );
603
617
return - ECONNABORTED ;
604
618
}
605
619
@@ -614,7 +628,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
614
628
return - ESHUTDOWN ;
615
629
616
630
if (server -> tcpStatus == CifsNeedReconnect ) {
617
- cifs_reconnect (server );
631
+ cifs_reconnect (server , false );
618
632
return - ECONNABORTED ;
619
633
}
620
634
@@ -633,7 +647,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
633
647
634
648
if (length <= 0 ) {
635
649
cifs_dbg (FYI , "Received no data or error: %d\n" , length );
636
- cifs_reconnect (server );
650
+ cifs_reconnect (server , false );
637
651
return - ECONNABORTED ;
638
652
}
639
653
}
@@ -712,11 +726,11 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
712
726
* initialize frame).
713
727
*/
714
728
cifs_set_port ((struct sockaddr * )& server -> dstaddr , CIFS_PORT );
715
- cifs_reconnect (server );
729
+ cifs_reconnect (server , true );
716
730
break ;
717
731
default :
718
732
cifs_server_dbg (VFS , "RFC 1002 unknown response type 0x%x\n" , type );
719
- cifs_reconnect (server );
733
+ cifs_reconnect (server , true );
720
734
}
721
735
722
736
return false;
@@ -889,7 +903,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
889
903
if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE (server ) -
890
904
server -> vals -> header_preamble_size ) {
891
905
cifs_server_dbg (VFS , "SMB response too long (%u bytes)\n" , pdu_length );
892
- cifs_reconnect (server );
906
+ cifs_reconnect (server , true );
893
907
return - ECONNABORTED ;
894
908
}
895
909
@@ -936,7 +950,7 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
936
950
937
951
if (server -> ops -> is_session_expired &&
938
952
server -> ops -> is_session_expired (buf )) {
939
- cifs_reconnect (server );
953
+ cifs_reconnect (server , true );
940
954
return -1 ;
941
955
}
942
956
@@ -1040,7 +1054,7 @@ cifs_demultiplex_thread(void *p)
1040
1054
server -> vals -> header_preamble_size ) {
1041
1055
cifs_server_dbg (VFS , "SMB response too short (%u bytes)\n" ,
1042
1056
server -> pdu_size );
1043
- cifs_reconnect (server );
1057
+ cifs_reconnect (server , true );
1044
1058
continue ;
1045
1059
}
1046
1060
@@ -1092,7 +1106,7 @@ cifs_demultiplex_thread(void *p)
1092
1106
server -> ops -> is_status_io_timeout (buf )) {
1093
1107
num_io_timeout ++ ;
1094
1108
if (num_io_timeout > NUM_STATUS_IO_TIMEOUT ) {
1095
- cifs_reconnect (server );
1109
+ cifs_reconnect (server , false );
1096
1110
num_io_timeout = 0 ;
1097
1111
continue ;
1098
1112
}
0 commit comments