@@ -83,27 +83,6 @@ static void refresh_cache_worker(struct work_struct *work);
83
83
84
84
static DECLARE_DELAYED_WORK (refresh_task , refresh_cache_worker );
85
85
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
-
107
86
static void __mount_group_release (struct mount_group * mg )
108
87
{
109
88
int i ;
@@ -760,8 +739,6 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
760
739
int rc ;
761
740
int i ;
762
741
763
- cifs_dbg (FYI , "%s: get an DFS referral for %s\n" , __func__ , path );
764
-
765
742
* refs = NULL ;
766
743
* numrefs = 0 ;
767
744
@@ -770,6 +747,7 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const
770
747
if (unlikely (!cache_cp ))
771
748
return - EINVAL ;
772
749
750
+ cifs_dbg (FYI , "%s: ipc=%s referral=%s\n" , __func__ , ses -> tcon_ipc -> tree_name , path );
773
751
rc = ses -> server -> ops -> get_dfs_refer (xid , ses , path , refs , numrefs , cache_cp ,
774
752
NO_MAP_UNI_RSVD );
775
753
if (!rc ) {
@@ -1366,10 +1344,9 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
1366
1344
}
1367
1345
1368
1346
/* 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 )
1371
1348
{
1372
- struct cifs_ses * ses ;
1349
+ struct cifs_ses * ses = CIFS_DFS_ROOT_SES ( tcon -> ses ) ;
1373
1350
struct cache_entry * ce ;
1374
1351
struct dfs_info3_param * refs = NULL ;
1375
1352
int numrefs = 0 ;
@@ -1378,11 +1355,7 @@ static int __refresh_tcon(const char *path, struct cifs_ses **sessions, struct c
1378
1355
int rc = 0 ;
1379
1356
unsigned int xid ;
1380
1357
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 ();
1386
1359
1387
1360
down_read (& htable_rw_lock );
1388
1361
ce = lookup_cache_entry (path );
@@ -1399,12 +1372,9 @@ static int __refresh_tcon(const char *path, struct cifs_ses **sessions, struct c
1399
1372
goto out ;
1400
1373
}
1401
1374
1402
- xid = get_xid ();
1403
1375
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 */
1407
1376
if (!rc ) {
1377
+ /* Create or update a cache entry with the new referral */
1408
1378
dump_refs (refs , numrefs );
1409
1379
1410
1380
down_write (& htable_rw_lock );
@@ -1419,24 +1389,20 @@ static int __refresh_tcon(const char *path, struct cifs_ses **sessions, struct c
1419
1389
}
1420
1390
1421
1391
out :
1392
+ free_xid (xid );
1422
1393
dfs_cache_free_tgts (& tl );
1423
1394
free_dfs_info_array (refs , numrefs );
1424
1395
return rc ;
1425
1396
}
1426
1397
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 )
1428
1399
{
1429
1400
struct TCP_Server_Info * server = tcon -> ses -> server ;
1430
1401
1431
1402
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 );
1438
1405
mutex_unlock (& server -> refpath_lock );
1439
-
1440
1406
return 0 ;
1441
1407
}
1442
1408
@@ -1454,9 +1420,6 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
1454
1420
{
1455
1421
struct cifs_tcon * tcon ;
1456
1422
struct TCP_Server_Info * server ;
1457
- struct mount_group * mg ;
1458
- struct cifs_ses * sessions [CACHE_MAX_ENTRIES + 1 ] = {NULL };
1459
- int rc ;
1460
1423
1461
1424
if (!cifs_sb || !cifs_sb -> master_tlink )
1462
1425
return - EINVAL ;
@@ -1473,21 +1436,6 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
1473
1436
cifs_dbg (FYI , "%s: no dfs mount group id\n" , __func__ );
1474
1437
return - EINVAL ;
1475
1438
}
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
-
1491
1439
/*
1492
1440
* After reconnecting to a different server, unique ids won't match anymore, so we disable
1493
1441
* 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)
1498
1446
* that have different prefix paths.
1499
1447
*/
1500
1448
cifs_sb -> mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH ;
1501
- rc = refresh_tcon (sessions , tcon , true);
1502
1449
1503
- kref_put (& mg -> refcount , mount_group_release );
1504
- return rc ;
1450
+ return refresh_tcon (tcon , true);
1505
1451
}
1506
1452
1507
1453
/*
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.
1510
1456
*/
1511
- static void refresh_mounts (struct cifs_ses * * sessions )
1457
+ static void refresh_cache_worker (struct work_struct * work )
1512
1458
{
1513
1459
struct TCP_Server_Info * server ;
1514
1460
struct cifs_ses * ses ;
@@ -1523,9 +1469,19 @@ static void refresh_mounts(struct cifs_ses **sessions)
1523
1469
continue ;
1524
1470
1525
1471
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
+
1526
1481
list_for_each_entry (tcon , & ses -> tcon_list , tcon_list ) {
1527
1482
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 ) {
1529
1485
tcon -> tc_count ++ ;
1530
1486
list_add_tail (& tcon -> ulist , & tcons );
1531
1487
}
@@ -1542,57 +1498,11 @@ static void refresh_mounts(struct cifs_ses **sessions)
1542
1498
1543
1499
mutex_lock (& server -> refpath_lock );
1544
1500
if (server -> leaf_fullpath )
1545
- __refresh_tcon (server -> leaf_fullpath + 1 , sessions , tcon , false);
1501
+ __refresh_tcon (server -> leaf_fullpath + 1 , tcon , false);
1546
1502
mutex_unlock (& server -> refpath_lock );
1547
1503
1548
1504
cifs_put_tcon (tcon );
1549
1505
}
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
- }
1596
1506
1597
1507
spin_lock (& cache_ttl_lock );
1598
1508
queue_delayed_work (dfscache_wq , & refresh_task , cache_ttl * HZ );
0 commit comments