@@ -1346,14 +1346,15 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
13461346/* Refresh dfs referral of tcon and mark it for reconnect if needed */
13471347static int __refresh_tcon (const char * path , struct cifs_tcon * tcon , bool force_refresh )
13481348{
1349+ struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT (tl );
13491350 struct cifs_ses * ses = CIFS_DFS_ROOT_SES (tcon -> ses );
1350- struct cache_entry * ce ;
1351+ struct cifs_tcon * ipc = ses -> tcon_ipc ;
13511352 struct dfs_info3_param * refs = NULL ;
1352- int numrefs = 0 ;
13531353 bool needs_refresh = false;
1354- struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT (tl );
1355- int rc = 0 ;
1354+ struct cache_entry * ce ;
13561355 unsigned int xid ;
1356+ int numrefs = 0 ;
1357+ int rc = 0 ;
13571358
13581359 xid = get_xid ();
13591360
@@ -1372,6 +1373,14 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
13721373 goto out ;
13731374 }
13741375
1376+ spin_lock (& ipc -> tc_lock );
1377+ if (ses -> ses_status != SES_GOOD || ipc -> status != TID_GOOD ) {
1378+ spin_unlock (& ipc -> tc_lock );
1379+ cifs_dbg (FYI , "%s: skip cache refresh due to disconnected ipc\n" , __func__ );
1380+ goto out ;
1381+ }
1382+ spin_unlock (& ipc -> tc_lock );
1383+
13751384 rc = get_dfs_referral (xid , ses , path , & refs , & numrefs );
13761385 if (!rc ) {
13771386 /* Create or update a cache entry with the new referral */
@@ -1457,9 +1466,9 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
14571466static void refresh_cache_worker (struct work_struct * work )
14581467{
14591468 struct TCP_Server_Info * server ;
1460- struct cifs_ses * ses ;
14611469 struct cifs_tcon * tcon , * ntcon ;
14621470 struct list_head tcons ;
1471+ struct cifs_ses * ses ;
14631472
14641473 INIT_LIST_HEAD (& tcons );
14651474
@@ -1469,23 +1478,15 @@ static void refresh_cache_worker(struct work_struct *work)
14691478 continue ;
14701479
14711480 list_for_each_entry (ses , & server -> smb_ses_list , smb_ses_list ) {
1472- struct cifs_ses * root_ses = CIFS_DFS_ROOT_SES (ses );
1473-
1474- spin_lock (& root_ses -> ses_lock );
1475- if (root_ses -> ses_status != SES_GOOD ) {
1476- spin_unlock (& root_ses -> ses_lock );
1477- continue ;
1481+ if (ses -> tcon_ipc ) {
1482+ ses -> ses_count ++ ;
1483+ list_add_tail (& ses -> tcon_ipc -> ulist , & tcons );
14781484 }
1479- spin_unlock (& root_ses -> ses_lock );
1480-
14811485 list_for_each_entry (tcon , & ses -> tcon_list , tcon_list ) {
1482- spin_lock (& tcon -> tc_lock );
1483- if (!tcon -> ipc && tcon -> status != TID_NEW &&
1484- tcon -> status != TID_NEED_TCON ) {
1486+ if (!tcon -> ipc ) {
14851487 tcon -> tc_count ++ ;
14861488 list_add_tail (& tcon -> ulist , & tcons );
14871489 }
1488- spin_unlock (& tcon -> tc_lock );
14891490 }
14901491 }
14911492 }
@@ -1501,7 +1502,10 @@ static void refresh_cache_worker(struct work_struct *work)
15011502 __refresh_tcon (server -> leaf_fullpath + 1 , tcon , false);
15021503 mutex_unlock (& server -> refpath_lock );
15031504
1504- cifs_put_tcon (tcon );
1505+ if (tcon -> ipc )
1506+ cifs_put_smb_ses (tcon -> ses );
1507+ else
1508+ cifs_put_tcon (tcon );
15051509 }
15061510
15071511 spin_lock (& cache_ttl_lock );
0 commit comments