@@ -776,7 +776,8 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
776776 */
777777static struct cache_entry * cache_refresh_path (const unsigned int xid ,
778778 struct cifs_ses * ses ,
779- const char * path )
779+ const char * path ,
780+ bool force_refresh )
780781{
781782 struct dfs_info3_param * refs = NULL ;
782783 struct cache_entry * ce ;
@@ -788,7 +789,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid,
788789 down_read (& htable_rw_lock );
789790
790791 ce = lookup_cache_entry (path );
791- if (!IS_ERR (ce ) && !cache_entry_expired (ce ))
792+ if (!IS_ERR (ce ) && !force_refresh && ! cache_entry_expired (ce ))
792793 return ce ;
793794
794795 /*
@@ -800,7 +801,8 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid,
800801 up_read (& htable_rw_lock );
801802
802803 /*
803- * Either the entry was not found, or it is expired.
804+ * Either the entry was not found, or it is expired, or it is a forced
805+ * refresh.
804806 * Request a new DFS referral in order to create or update a cache entry.
805807 */
806808 rc = get_dfs_referral (xid , ses , path , & refs , & numrefs );
@@ -815,7 +817,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid,
815817 /* Re-check as another task might have it added or refreshed already */
816818 ce = lookup_cache_entry (path );
817819 if (!IS_ERR (ce )) {
818- if (cache_entry_expired (ce )) {
820+ if (force_refresh || cache_entry_expired (ce )) {
819821 rc = update_cache_entry_locked (ce , refs , numrefs );
820822 if (rc )
821823 ce = ERR_PTR (rc );
@@ -952,7 +954,7 @@ int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nl
952954 if (IS_ERR (npath ))
953955 return PTR_ERR (npath );
954956
955- ce = cache_refresh_path (xid , ses , npath );
957+ ce = cache_refresh_path (xid , ses , npath , false );
956958 if (IS_ERR (ce )) {
957959 rc = PTR_ERR (ce );
958960 goto out_free_path ;
@@ -1049,7 +1051,7 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses,
10491051
10501052 cifs_dbg (FYI , "%s: update target hint - path: %s\n" , __func__ , npath );
10511053
1052- ce = cache_refresh_path (xid , ses , npath );
1054+ ce = cache_refresh_path (xid , ses , npath , false );
10531055 if (IS_ERR (ce )) {
10541056 rc = PTR_ERR (ce );
10551057 goto out_free_path ;
@@ -1327,35 +1329,37 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
13271329 * Mark dfs tcon for reconnecting when the currently connected tcon does not match any of the new
13281330 * target shares in @refs.
13291331 */
1330- static void mark_for_reconnect_if_needed (struct cifs_tcon * tcon , struct dfs_cache_tgt_list * tl ,
1331- const struct dfs_info3_param * refs , int numrefs )
1332+ static void mark_for_reconnect_if_needed (struct TCP_Server_Info * server ,
1333+ struct dfs_cache_tgt_list * old_tl ,
1334+ struct dfs_cache_tgt_list * new_tl )
13321335{
1333- struct dfs_cache_tgt_iterator * it ;
1334- int i ;
1335-
1336- for (it = dfs_cache_get_tgt_iterator (tl ); it ; it = dfs_cache_get_next_tgt (tl , it )) {
1337- for (i = 0 ; i < numrefs ; i ++ ) {
1338- if (target_share_equal (tcon -> ses -> server , dfs_cache_get_tgt_name (it ),
1339- refs [i ].node_name ))
1336+ struct dfs_cache_tgt_iterator * oit , * nit ;
1337+
1338+ for (oit = dfs_cache_get_tgt_iterator (old_tl ); oit ;
1339+ oit = dfs_cache_get_next_tgt (old_tl , oit )) {
1340+ for (nit = dfs_cache_get_tgt_iterator (new_tl ); nit ;
1341+ nit = dfs_cache_get_next_tgt (new_tl , nit )) {
1342+ if (target_share_equal (server ,
1343+ dfs_cache_get_tgt_name (oit ),
1344+ dfs_cache_get_tgt_name (nit )))
13401345 return ;
13411346 }
13421347 }
13431348
13441349 cifs_dbg (FYI , "%s: no cached or matched targets. mark dfs share for reconnect.\n" , __func__ );
1345- cifs_signal_cifsd_for_reconnect (tcon -> ses -> server , true);
1350+ cifs_signal_cifsd_for_reconnect (server , true);
13461351}
13471352
13481353/* Refresh dfs referral of tcon and mark it for reconnect if needed */
13491354static int __refresh_tcon (const char * path , struct cifs_tcon * tcon , bool force_refresh )
13501355{
1351- struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT (tl );
1356+ struct dfs_cache_tgt_list old_tl = DFS_CACHE_TGT_LIST_INIT (old_tl );
1357+ struct dfs_cache_tgt_list new_tl = DFS_CACHE_TGT_LIST_INIT (new_tl );
13521358 struct cifs_ses * ses = CIFS_DFS_ROOT_SES (tcon -> ses );
13531359 struct cifs_tcon * ipc = ses -> tcon_ipc ;
1354- struct dfs_info3_param * refs = NULL ;
13551360 bool needs_refresh = false;
13561361 struct cache_entry * ce ;
13571362 unsigned int xid ;
1358- int numrefs = 0 ;
13591363 int rc = 0 ;
13601364
13611365 xid = get_xid ();
@@ -1364,9 +1368,8 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
13641368 ce = lookup_cache_entry (path );
13651369 needs_refresh = force_refresh || IS_ERR (ce ) || cache_entry_expired (ce );
13661370 if (!IS_ERR (ce )) {
1367- rc = get_targets (ce , & tl );
1368- if (rc )
1369- cifs_dbg (FYI , "%s: could not get dfs targets: %d\n" , __func__ , rc );
1371+ rc = get_targets (ce , & old_tl );
1372+ cifs_dbg (FYI , "%s: get_targets: %d\n" , __func__ , rc );
13701373 }
13711374 up_read (& htable_rw_lock );
13721375
@@ -1383,26 +1386,18 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
13831386 }
13841387 spin_unlock (& ipc -> tc_lock );
13851388
1386- rc = get_dfs_referral (xid , ses , path , & refs , & numrefs );
1387- if (!rc ) {
1388- /* Create or update a cache entry with the new referral */
1389- dump_refs (refs , numrefs );
1390-
1391- down_write (& htable_rw_lock );
1392- ce = lookup_cache_entry (path );
1393- if (IS_ERR (ce ))
1394- add_cache_entry_locked (refs , numrefs );
1395- else if (force_refresh || cache_entry_expired (ce ))
1396- update_cache_entry_locked (ce , refs , numrefs );
1397- up_write (& htable_rw_lock );
1398-
1399- mark_for_reconnect_if_needed (tcon , & tl , refs , numrefs );
1389+ ce = cache_refresh_path (xid , ses , path , true);
1390+ if (!IS_ERR (ce )) {
1391+ rc = get_targets (ce , & new_tl );
1392+ up_read (& htable_rw_lock );
1393+ cifs_dbg (FYI , "%s: get_targets: %d\n" , __func__ , rc );
1394+ mark_for_reconnect_if_needed (tcon -> ses -> server , & old_tl , & new_tl );
14001395 }
14011396
14021397out :
14031398 free_xid (xid );
1404- dfs_cache_free_tgts (& tl );
1405- free_dfs_info_array ( refs , numrefs );
1399+ dfs_cache_free_tgts (& old_tl );
1400+ dfs_cache_free_tgts ( & new_tl );
14061401 return rc ;
14071402}
14081403
0 commit comments