@@ -374,6 +374,54 @@ static int target_share_matches_server(struct TCP_Server_Info *server, char *sha
374374 return rc ;
375375}
376376
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+
377425static int __tree_connect_dfs_target (const unsigned int xid , struct cifs_tcon * tcon ,
378426 struct cifs_sb_info * cifs_sb , char * tree , bool islink ,
379427 struct dfs_cache_tgt_list * tl )
@@ -382,7 +430,6 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
382430 struct TCP_Server_Info * server = tcon -> ses -> server ;
383431 const struct smb_version_operations * ops = server -> ops ;
384432 struct cifs_ses * root_ses = CIFS_DFS_ROOT_SES (tcon -> ses );
385- struct cifs_tcon * ipc = root_ses -> tcon_ipc ;
386433 char * share = NULL , * prefix = NULL ;
387434 struct dfs_cache_tgt_iterator * tit ;
388435 bool target_match ;
@@ -418,18 +465,14 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
418465 }
419466
420467 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 );
427469
428470 scnprintf (tree , MAX_TREE_SIZE , "\\%s" , share );
429471 if (!islink ) {
430472 rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , cifs_sb -> local_nls );
431473 break ;
432474 }
475+
433476 /*
434477 * If no dfs referrals were returned from link target, then just do a TREE_CONNECT
435478 * to it. Otherwise, cache the dfs referral and then mark current tcp ses for
0 commit comments