@@ -374,6 +374,54 @@ static int target_share_matches_server(struct TCP_Server_Info *server, char *sha
374
374
return rc ;
375
375
}
376
376
377
+ static void __tree_connect_ipc (const unsigned int xid , char * tree ,
378
+ struct cifs_sb_info * cifs_sb ,
379
+ struct cifs_ses * ses )
380
+ {
381
+ struct TCP_Server_Info * server = ses -> server ;
382
+ struct cifs_tcon * tcon = ses -> tcon_ipc ;
383
+ int rc ;
384
+
385
+ spin_lock (& ses -> ses_lock );
386
+ spin_lock (& ses -> chan_lock );
387
+ if (cifs_chan_needs_reconnect (ses , server ) ||
388
+ ses -> ses_status != SES_GOOD ) {
389
+ spin_unlock (& ses -> chan_lock );
390
+ spin_unlock (& ses -> ses_lock );
391
+ cifs_server_dbg (FYI , "%s: skipping ipc reconnect due to disconnected ses\n" ,
392
+ __func__ );
393
+ return ;
394
+ }
395
+ spin_unlock (& ses -> chan_lock );
396
+ spin_unlock (& ses -> ses_lock );
397
+
398
+ cifs_server_lock (server );
399
+ scnprintf (tree , MAX_TREE_SIZE , "\\\\%s\\IPC$" , server -> hostname );
400
+ cifs_server_unlock (server );
401
+
402
+ rc = server -> ops -> tree_connect (xid , ses , tree , tcon ,
403
+ cifs_sb -> local_nls );
404
+ cifs_server_dbg (FYI , "%s: tree_reconnect %s: %d\n" , __func__ , tree , rc );
405
+ spin_lock (& tcon -> tc_lock );
406
+ if (rc ) {
407
+ tcon -> status = TID_NEED_TCON ;
408
+ } else {
409
+ tcon -> status = TID_GOOD ;
410
+ tcon -> need_reconnect = false;
411
+ }
412
+ spin_unlock (& tcon -> tc_lock );
413
+ }
414
+
415
+ static void tree_connect_ipc (const unsigned int xid , char * tree ,
416
+ struct cifs_sb_info * cifs_sb ,
417
+ struct cifs_tcon * tcon )
418
+ {
419
+ struct cifs_ses * ses = tcon -> ses ;
420
+
421
+ __tree_connect_ipc (xid , tree , cifs_sb , ses );
422
+ __tree_connect_ipc (xid , tree , cifs_sb , CIFS_DFS_ROOT_SES (ses ));
423
+ }
424
+
377
425
static int __tree_connect_dfs_target (const unsigned int xid , struct cifs_tcon * tcon ,
378
426
struct cifs_sb_info * cifs_sb , char * tree , bool islink ,
379
427
struct dfs_cache_tgt_list * tl )
@@ -382,7 +430,6 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
382
430
struct TCP_Server_Info * server = tcon -> ses -> server ;
383
431
const struct smb_version_operations * ops = server -> ops ;
384
432
struct cifs_ses * root_ses = CIFS_DFS_ROOT_SES (tcon -> ses );
385
- struct cifs_tcon * ipc = root_ses -> tcon_ipc ;
386
433
char * share = NULL , * prefix = NULL ;
387
434
struct dfs_cache_tgt_iterator * tit ;
388
435
bool target_match ;
@@ -418,18 +465,14 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
418
465
}
419
466
420
467
dfs_cache_noreq_update_tgthint (server -> current_fullpath + 1 , tit );
421
-
422
- if (ipc -> need_reconnect ) {
423
- scnprintf (tree , MAX_TREE_SIZE , "\\\\%s\\IPC$" , server -> hostname );
424
- rc = ops -> tree_connect (xid , ipc -> ses , tree , ipc , cifs_sb -> local_nls );
425
- cifs_dbg (FYI , "%s: reconnect ipc: %d\n" , __func__ , rc );
426
- }
468
+ tree_connect_ipc (xid , tree , cifs_sb , tcon );
427
469
428
470
scnprintf (tree , MAX_TREE_SIZE , "\\%s" , share );
429
471
if (!islink ) {
430
472
rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , cifs_sb -> local_nls );
431
473
break ;
432
474
}
475
+
433
476
/*
434
477
* If no dfs referrals were returned from link target, then just do a TREE_CONNECT
435
478
* to it. Otherwise, cache the dfs referral and then mark current tcp ses for
0 commit comments