Skip to content

Commit 48aa995

Browse files
Paulo Alcantarasmfrench
authored andcommitted
smb: client: don't retry DFS targets on server shutdown
If TCP Server is about to be destroyed (e.g. CifsExiting was set) and it is reconnecting, stop retrying DFS targets from cached DFS referral as this would potentially delay server shutdown in several seconds. Signed-off-by: Paulo Alcantara (Red Hat) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent bfc1155 commit 48aa995

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

fs/smb/client/connect.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,8 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
422422
}
423423

424424
#ifdef CONFIG_CIFS_DFS_UPCALL
425-
static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const char *target)
425+
static int __reconnect_target_locked(struct TCP_Server_Info *server,
426+
const char *target)
426427
{
427428
int rc;
428429
char *hostname;
@@ -455,27 +456,36 @@ static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const cha
455456
return rc;
456457
}
457458

458-
static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_cache_tgt_list *tl,
459-
struct dfs_cache_tgt_iterator **target_hint)
459+
static int reconnect_target_locked(struct TCP_Server_Info *server,
460+
struct dfs_cache_tgt_list *tl,
461+
struct dfs_cache_tgt_iterator **target_hint)
460462
{
461-
int rc;
462463
struct dfs_cache_tgt_iterator *tit;
464+
int rc;
463465

464466
*target_hint = NULL;
465467

466468
/* If dfs target list is empty, then reconnect to last server */
467469
tit = dfs_cache_get_tgt_iterator(tl);
468470
if (!tit)
469-
return __reconnect_target_unlocked(server, server->hostname);
471+
return __reconnect_target_locked(server, server->hostname);
470472

471473
/* Otherwise, try every dfs target in @tl */
472-
for (; tit; tit = dfs_cache_get_next_tgt(tl, tit)) {
473-
rc = __reconnect_target_unlocked(server, dfs_cache_get_tgt_name(tit));
474+
do {
475+
const char *target = dfs_cache_get_tgt_name(tit);
476+
477+
spin_lock(&server->srv_lock);
478+
if (server->tcpStatus != CifsNeedReconnect) {
479+
spin_unlock(&server->srv_lock);
480+
return -ECONNRESET;
481+
}
482+
spin_unlock(&server->srv_lock);
483+
rc = __reconnect_target_locked(server, target);
474484
if (!rc) {
475485
*target_hint = tit;
476486
break;
477487
}
478-
}
488+
} while ((tit = dfs_cache_get_next_tgt(tl, tit)));
479489
return rc;
480490
}
481491

@@ -518,7 +528,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
518528
try_to_freeze();
519529
cifs_server_lock(server);
520530

521-
rc = reconnect_target_unlocked(server, &tl, &target_hint);
531+
rc = reconnect_target_locked(server, &tl, &target_hint);
522532
if (rc) {
523533
/* Failed to reconnect socket */
524534
cifs_server_unlock(server);

0 commit comments

Comments
 (0)