@@ -776,7 +776,8 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
776
776
*/
777
777
static struct cache_entry * cache_refresh_path (const unsigned int xid ,
778
778
struct cifs_ses * ses ,
779
- const char * path )
779
+ const char * path ,
780
+ bool force_refresh )
780
781
{
781
782
struct dfs_info3_param * refs = NULL ;
782
783
struct cache_entry * ce ;
@@ -788,7 +789,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid,
788
789
down_read (& htable_rw_lock );
789
790
790
791
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 ))
792
793
return ce ;
793
794
794
795
/*
@@ -800,7 +801,8 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid,
800
801
up_read (& htable_rw_lock );
801
802
802
803
/*
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.
804
806
* Request a new DFS referral in order to create or update a cache entry.
805
807
*/
806
808
rc = get_dfs_referral (xid , ses , path , & refs , & numrefs );
@@ -815,7 +817,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid,
815
817
/* Re-check as another task might have it added or refreshed already */
816
818
ce = lookup_cache_entry (path );
817
819
if (!IS_ERR (ce )) {
818
- if (cache_entry_expired (ce )) {
820
+ if (force_refresh || cache_entry_expired (ce )) {
819
821
rc = update_cache_entry_locked (ce , refs , numrefs );
820
822
if (rc )
821
823
ce = ERR_PTR (rc );
@@ -952,7 +954,7 @@ int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nl
952
954
if (IS_ERR (npath ))
953
955
return PTR_ERR (npath );
954
956
955
- ce = cache_refresh_path (xid , ses , npath );
957
+ ce = cache_refresh_path (xid , ses , npath , false );
956
958
if (IS_ERR (ce )) {
957
959
rc = PTR_ERR (ce );
958
960
goto out_free_path ;
@@ -1049,7 +1051,7 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses,
1049
1051
1050
1052
cifs_dbg (FYI , "%s: update target hint - path: %s\n" , __func__ , npath );
1051
1053
1052
- ce = cache_refresh_path (xid , ses , npath );
1054
+ ce = cache_refresh_path (xid , ses , npath , false );
1053
1055
if (IS_ERR (ce )) {
1054
1056
rc = PTR_ERR (ce );
1055
1057
goto out_free_path ;
@@ -1327,35 +1329,37 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c
1327
1329
* Mark dfs tcon for reconnecting when the currently connected tcon does not match any of the new
1328
1330
* target shares in @refs.
1329
1331
*/
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 )
1332
1335
{
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 )))
1340
1345
return ;
1341
1346
}
1342
1347
}
1343
1348
1344
1349
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);
1346
1351
}
1347
1352
1348
1353
/* Refresh dfs referral of tcon and mark it for reconnect if needed */
1349
1354
static int __refresh_tcon (const char * path , struct cifs_tcon * tcon , bool force_refresh )
1350
1355
{
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 );
1352
1358
struct cifs_ses * ses = CIFS_DFS_ROOT_SES (tcon -> ses );
1353
1359
struct cifs_tcon * ipc = ses -> tcon_ipc ;
1354
- struct dfs_info3_param * refs = NULL ;
1355
1360
bool needs_refresh = false;
1356
1361
struct cache_entry * ce ;
1357
1362
unsigned int xid ;
1358
- int numrefs = 0 ;
1359
1363
int rc = 0 ;
1360
1364
1361
1365
xid = get_xid ();
@@ -1364,9 +1368,8 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
1364
1368
ce = lookup_cache_entry (path );
1365
1369
needs_refresh = force_refresh || IS_ERR (ce ) || cache_entry_expired (ce );
1366
1370
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 );
1370
1373
}
1371
1374
up_read (& htable_rw_lock );
1372
1375
@@ -1383,26 +1386,18 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
1383
1386
}
1384
1387
spin_unlock (& ipc -> tc_lock );
1385
1388
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 );
1400
1395
}
1401
1396
1402
1397
out :
1403
1398
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 );
1406
1401
return rc ;
1407
1402
}
1408
1403
0 commit comments