aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@manguebit.com>2025-01-13 19:00:29 -0300
committerSteve French <stfrench@microsoft.com>2025-01-19 19:34:00 -0600
commit48aa99523e88e5792edc007e0c7f89faffacc5f7 (patch)
tree8275841719664a1cbb974a3313b75ce8eeae1f73
parentsmb: client: fix return value of parse_dfs_referrals() (diff)
downloadwireguard-linux-48aa99523e88e5792edc007e0c7f89faffacc5f7.tar.xz
wireguard-linux-48aa99523e88e5792edc007e0c7f89faffacc5f7.zip
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) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to '')
-rw-r--r--fs/smb/client/connect.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 004fec33efab..73d07d95d435 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -422,7 +422,8 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,
}
#ifdef CONFIG_CIFS_DFS_UPCALL
-static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const char *target)
+static int __reconnect_target_locked(struct TCP_Server_Info *server,
+ const char *target)
{
int rc;
char *hostname;
@@ -455,27 +456,36 @@ static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const cha
return rc;
}
-static int reconnect_target_unlocked(struct TCP_Server_Info *server, struct dfs_cache_tgt_list *tl,
- struct dfs_cache_tgt_iterator **target_hint)
+static int reconnect_target_locked(struct TCP_Server_Info *server,
+ struct dfs_cache_tgt_list *tl,
+ struct dfs_cache_tgt_iterator **target_hint)
{
- int rc;
struct dfs_cache_tgt_iterator *tit;
+ int rc;
*target_hint = NULL;
/* If dfs target list is empty, then reconnect to last server */
tit = dfs_cache_get_tgt_iterator(tl);
if (!tit)
- return __reconnect_target_unlocked(server, server->hostname);
+ return __reconnect_target_locked(server, server->hostname);
/* Otherwise, try every dfs target in @tl */
- for (; tit; tit = dfs_cache_get_next_tgt(tl, tit)) {
- rc = __reconnect_target_unlocked(server, dfs_cache_get_tgt_name(tit));
+ do {
+ const char *target = dfs_cache_get_tgt_name(tit);
+
+ spin_lock(&server->srv_lock);
+ if (server->tcpStatus != CifsNeedReconnect) {
+ spin_unlock(&server->srv_lock);
+ return -ECONNRESET;
+ }
+ spin_unlock(&server->srv_lock);
+ rc = __reconnect_target_locked(server, target);
if (!rc) {
*target_hint = tit;
break;
}
- }
+ } while ((tit = dfs_cache_get_next_tgt(tl, tit)));
return rc;
}
@@ -518,7 +528,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
try_to_freeze();
cifs_server_lock(server);
- rc = reconnect_target_unlocked(server, &tl, &target_hint);
+ rc = reconnect_target_locked(server, &tl, &target_hint);
if (rc) {
/* Failed to reconnect socket */
cifs_server_unlock(server);