@@ -83,27 +83,6 @@ static void refresh_cache_worker(struct work_struct *work);
8383
8484static DECLARE_DELAYED_WORK (refresh_task , refresh_cache_worker );
8585
86- static void get_ipc_unc (const char * ref_path , char * ipc , size_t ipclen )
87- {
88- const char * host ;
89- size_t len ;
90-
91- extract_unc_hostname (ref_path , & host , & len );
92- scnprintf (ipc , ipclen , "\\\\%.*s\\IPC$" , (int )len , host );
93- }
94-
95- static struct cifs_ses * find_ipc_from_server_path (struct cifs_ses * * ses , const char * path )
96- {
97- char unc [SERVER_NAME_LENGTH + sizeof ("//x/IPC$" )] = {0 };
98-
99- get_ipc_unc (path , unc , sizeof (unc ));
100- for (; * ses ; ses ++ ) {
101- if (!strcasecmp (unc , (* ses )-> tcon_ipc -> tree_name ))
102- return * ses ;
103- }
104- return ERR_PTR (- ENOENT );
105- }
106-
10786static void __mount_group_release (struct mount_group * mg )
10887{
10988 int i ;
@@ -760,8 +739,6 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
760739 int rc ;
761740 int i ;
762741
763- cifs_dbg (FYI , "%s: get an DFS referral for %s\n" , __func__ , path );
764-
765742 * refs = NULL ;
766743 * numrefs = 0 ;
767744
@@ -770,6 +747,7 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
770747 if (unlikely (!cache_cp ))
771748 return - EINVAL ;
772749
750+ cifs_dbg (FYI , "%s: ipc=%s referral=%s\n" , __func__ , ses -> tcon_ipc -> tree_name , path );
773751 rc = ses -> server -> ops -> get_dfs_refer (xid , ses , path , refs , numrefs , cache_cp ,
774752 NO_MAP_UNI_RSVD );
775753 if (!rc ) {
@@ -1366,10 +1344,9 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
13661344}
13671345
13681346/* Refresh dfs referral of tcon and mark it for reconnect if needed */
1369- static int __refresh_tcon (const char * path , struct cifs_ses * * sessions , struct cifs_tcon * tcon ,
1370- bool force_refresh )
1347+ static int __refresh_tcon (const char * path , struct cifs_tcon * tcon , bool force_refresh )
13711348{
1372- struct cifs_ses * ses ;
1349+ struct cifs_ses * ses = CIFS_DFS_ROOT_SES ( tcon -> ses ) ;
13731350 struct cache_entry * ce ;
13741351 struct dfs_info3_param * refs = NULL ;
13751352 int numrefs = 0 ;
@@ -1378,11 +1355,7 @@ static int __refresh_tcon(const char *path, struct cifs_ses **sessions, struct c
13781355 int rc = 0 ;
13791356 unsigned int xid ;
13801357
1381- ses = find_ipc_from_server_path (sessions , path );
1382- if (IS_ERR (ses )) {
1383- cifs_dbg (FYI , "%s: could not find ipc session\n" , __func__ );
1384- return PTR_ERR (ses );
1385- }
1358+ xid = get_xid ();
13861359
13871360 down_read (& htable_rw_lock );
13881361 ce = lookup_cache_entry (path );
@@ -1399,12 +1372,9 @@ static int __refresh_tcon(const char *path, struct cifs_ses **sessions, struct c
13991372 goto out ;
14001373 }
14011374
1402- xid = get_xid ();
14031375 rc = get_dfs_referral (xid , ses , path , & refs , & numrefs );
1404- free_xid (xid );
1405-
1406- /* Create or update a cache entry with the new referral */
14071376 if (!rc ) {
1377+ /* Create or update a cache entry with the new referral */
14081378 dump_refs (refs , numrefs );
14091379
14101380 down_write (& htable_rw_lock );
@@ -1419,24 +1389,20 @@ static int __refresh_tcon(const char *path, struct cifs_ses **sessions, struct c
14191389 }
14201390
14211391out :
1392+ free_xid (xid );
14221393 dfs_cache_free_tgts (& tl );
14231394 free_dfs_info_array (refs , numrefs );
14241395 return rc ;
14251396}
14261397
1427- static int refresh_tcon (struct cifs_ses * * sessions , struct cifs_tcon * tcon , bool force_refresh )
1398+ static int refresh_tcon (struct cifs_tcon * tcon , bool force_refresh )
14281399{
14291400 struct TCP_Server_Info * server = tcon -> ses -> server ;
14301401
14311402 mutex_lock (& server -> refpath_lock );
1432- if (server -> origin_fullpath ) {
1433- if (server -> leaf_fullpath && strcasecmp (server -> leaf_fullpath ,
1434- server -> origin_fullpath ))
1435- __refresh_tcon (server -> leaf_fullpath + 1 , sessions , tcon , force_refresh );
1436- __refresh_tcon (server -> origin_fullpath + 1 , sessions , tcon , force_refresh );
1437- }
1403+ if (server -> leaf_fullpath )
1404+ __refresh_tcon (server -> leaf_fullpath + 1 , tcon , force_refresh );
14381405 mutex_unlock (& server -> refpath_lock );
1439-
14401406 return 0 ;
14411407}
14421408
@@ -1454,9 +1420,6 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
14541420{
14551421 struct cifs_tcon * tcon ;
14561422 struct TCP_Server_Info * server ;
1457- struct mount_group * mg ;
1458- struct cifs_ses * sessions [CACHE_MAX_ENTRIES + 1 ] = {NULL };
1459- int rc ;
14601423
14611424 if (!cifs_sb || !cifs_sb -> master_tlink )
14621425 return - EINVAL ;
@@ -1473,21 +1436,6 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
14731436 cifs_dbg (FYI , "%s: no dfs mount group id\n" , __func__ );
14741437 return - EINVAL ;
14751438 }
1476-
1477- mutex_lock (& mount_group_list_lock );
1478- mg = find_mount_group_locked (& cifs_sb -> dfs_mount_id );
1479- if (IS_ERR (mg )) {
1480- mutex_unlock (& mount_group_list_lock );
1481- cifs_dbg (FYI , "%s: no ipc session for refreshing referral\n" , __func__ );
1482- return PTR_ERR (mg );
1483- }
1484- kref_get (& mg -> refcount );
1485- mutex_unlock (& mount_group_list_lock );
1486-
1487- spin_lock (& mg -> lock );
1488- memcpy (& sessions , mg -> sessions , mg -> num_sessions * sizeof (mg -> sessions [0 ]));
1489- spin_unlock (& mg -> lock );
1490-
14911439 /*
14921440 * After reconnecting to a different server, unique ids won't match anymore, so we disable
14931441 * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE).
@@ -1498,17 +1446,15 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
14981446 * that have different prefix paths.
14991447 */
15001448 cifs_sb -> mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH ;
1501- rc = refresh_tcon (sessions , tcon , true);
15021449
1503- kref_put (& mg -> refcount , mount_group_release );
1504- return rc ;
1450+ return refresh_tcon (tcon , true);
15051451}
15061452
15071453/*
1508- * Refresh all active dfs mounts regardless of whether they are in cache or not.
1509- * (cache can be cleared)
1454+ * Worker that will refresh DFS cache from all active mounts based on lowest TTL value
1455+ * from a DFS referral.
15101456 */
1511- static void refresh_mounts (struct cifs_ses * * sessions )
1457+ static void refresh_cache_worker (struct work_struct * work )
15121458{
15131459 struct TCP_Server_Info * server ;
15141460 struct cifs_ses * ses ;
@@ -1523,9 +1469,19 @@ static void refresh_mounts(struct cifs_ses **sessions)
15231469 continue ;
15241470
15251471 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 ;
1478+ }
1479+ spin_unlock (& root_ses -> ses_lock );
1480+
15261481 list_for_each_entry (tcon , & ses -> tcon_list , tcon_list ) {
15271482 spin_lock (& tcon -> tc_lock );
1528- if (!tcon -> ipc && !tcon -> need_reconnect ) {
1483+ if (!tcon -> ipc && tcon -> status != TID_NEW &&
1484+ tcon -> status != TID_NEED_TCON ) {
15291485 tcon -> tc_count ++ ;
15301486 list_add_tail (& tcon -> ulist , & tcons );
15311487 }
@@ -1542,57 +1498,11 @@ static void refresh_mounts(struct cifs_ses **sessions)
15421498
15431499 mutex_lock (& server -> refpath_lock );
15441500 if (server -> leaf_fullpath )
1545- __refresh_tcon (server -> leaf_fullpath + 1 , sessions , tcon , false);
1501+ __refresh_tcon (server -> leaf_fullpath + 1 , tcon , false);
15461502 mutex_unlock (& server -> refpath_lock );
15471503
15481504 cifs_put_tcon (tcon );
15491505 }
1550- }
1551-
1552- /*
1553- * Worker that will refresh DFS cache and active mounts based on lowest TTL value from a DFS
1554- * referral.
1555- */
1556- static void refresh_cache_worker (struct work_struct * work )
1557- {
1558- struct list_head mglist ;
1559- struct mount_group * mg , * tmp_mg ;
1560- struct cifs_ses * sessions [CACHE_MAX_ENTRIES + 1 ] = {NULL };
1561- int max_sessions = ARRAY_SIZE (sessions ) - 1 ;
1562- int i = 0 , count ;
1563-
1564- INIT_LIST_HEAD (& mglist );
1565-
1566- /* Get refereces of mount groups */
1567- mutex_lock (& mount_group_list_lock );
1568- list_for_each_entry (mg , & mount_group_list , list ) {
1569- kref_get (& mg -> refcount );
1570- list_add (& mg -> refresh_list , & mglist );
1571- }
1572- mutex_unlock (& mount_group_list_lock );
1573-
1574- /* Fill in local array with an NULL-terminated list of all referral server sessions */
1575- list_for_each_entry (mg , & mglist , refresh_list ) {
1576- if (i >= max_sessions )
1577- break ;
1578-
1579- spin_lock (& mg -> lock );
1580- if (i + mg -> num_sessions > max_sessions )
1581- count = max_sessions - i ;
1582- else
1583- count = mg -> num_sessions ;
1584- memcpy (& sessions [i ], mg -> sessions , count * sizeof (mg -> sessions [0 ]));
1585- spin_unlock (& mg -> lock );
1586- i += count ;
1587- }
1588-
1589- if (sessions [0 ])
1590- refresh_mounts (sessions );
1591-
1592- list_for_each_entry_safe (mg , tmp_mg , & mglist , refresh_list ) {
1593- list_del_init (& mg -> refresh_list );
1594- kref_put (& mg -> refcount , mount_group_release );
1595- }
15961506
15971507 spin_lock (& cache_ttl_lock );
15981508 queue_delayed_work (dfscache_wq , & refresh_task , cache_ttl * HZ );
0 commit comments