@@ -1346,14 +1346,15 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
1346
1346
/* Refresh dfs referral of tcon and mark it for reconnect if needed */
1347
1347
static int __refresh_tcon (const char * path , struct cifs_tcon * tcon , bool force_refresh )
1348
1348
{
1349
+ struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT (tl );
1349
1350
struct cifs_ses * ses = CIFS_DFS_ROOT_SES (tcon -> ses );
1350
- struct cache_entry * ce ;
1351
+ struct cifs_tcon * ipc = ses -> tcon_ipc ;
1351
1352
struct dfs_info3_param * refs = NULL ;
1352
- int numrefs = 0 ;
1353
1353
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 ;
1356
1355
unsigned int xid ;
1356
+ int numrefs = 0 ;
1357
+ int rc = 0 ;
1357
1358
1358
1359
xid = get_xid ();
1359
1360
@@ -1372,6 +1373,14 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r
1372
1373
goto out ;
1373
1374
}
1374
1375
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
+
1375
1384
rc = get_dfs_referral (xid , ses , path , & refs , & numrefs );
1376
1385
if (!rc ) {
1377
1386
/* 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)
1457
1466
static void refresh_cache_worker (struct work_struct * work )
1458
1467
{
1459
1468
struct TCP_Server_Info * server ;
1460
- struct cifs_ses * ses ;
1461
1469
struct cifs_tcon * tcon , * ntcon ;
1462
1470
struct list_head tcons ;
1471
+ struct cifs_ses * ses ;
1463
1472
1464
1473
INIT_LIST_HEAD (& tcons );
1465
1474
@@ -1469,23 +1478,15 @@ static void refresh_cache_worker(struct work_struct *work)
1469
1478
continue ;
1470
1479
1471
1480
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 );
1478
1484
}
1479
- spin_unlock (& root_ses -> ses_lock );
1480
-
1481
1485
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 ) {
1485
1487
tcon -> tc_count ++ ;
1486
1488
list_add_tail (& tcon -> ulist , & tcons );
1487
1489
}
1488
- spin_unlock (& tcon -> tc_lock );
1489
1490
}
1490
1491
}
1491
1492
}
@@ -1501,7 +1502,10 @@ static void refresh_cache_worker(struct work_struct *work)
1501
1502
__refresh_tcon (server -> leaf_fullpath + 1 , tcon , false);
1502
1503
mutex_unlock (& server -> refpath_lock );
1503
1504
1504
- cifs_put_tcon (tcon );
1505
+ if (tcon -> ipc )
1506
+ cifs_put_smb_ses (tcon -> ses );
1507
+ else
1508
+ cifs_put_tcon (tcon );
1505
1509
}
1506
1510
1507
1511
spin_lock (& cache_ttl_lock );
0 commit comments