summaryrefslogtreecommitdiff
path: root/fs/smb/client/connect.c
diff options
context:
space:
mode:
authorShyam Prasad N <sprasad@microsoft.com>2023-12-06 19:37:38 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-02-01 03:18:48 +0300
commit07e864089a0e4f521f4232b7f35d4723049c568b (patch)
tree98c4f7cc738d5f23b73947258a842b446ef895b3 /fs/smb/client/connect.c
parent3a0ef868fb8aa0f5f9d05e1e4140903bfc1d1204 (diff)
downloadlinux-07e864089a0e4f521f4232b7f35d4723049c568b.tar.xz
cifs: reconnect worker should take reference on server struct unconditionally
[ Upstream commit 04909192ada3285070f8ced0af7f07735478b364 ] Reconnect worker currently assumes that the server struct is alive and only takes reference on the server if it needs to call smb2_reconnect. With the new ability to disable channels based on whether the server has multichannel disabled, this becomes a problem when we need to disable established channels. While disabling the channels and deallocating the server, there could be reconnect work that could not be cancelled (because it started). This change forces the reconnect worker to unconditionally take a reference on the server when it runs. Also, this change now allows smb2_reconnect to know if it was called by the reconnect worker. Based on this, the cifs_put_tcp_session can decide whether it can cancel the reconnect work synchronously or not. Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> Stable-dep-of: 78e727e58e54 ("cifs: update iface_last_update on each query-and-update") Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/smb/client/connect.c')
-rw-r--r--fs/smb/client/connect.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 2a30245287d5..432248e955ed 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1612,10 +1612,6 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
list_del_init(&server->tcp_ses_list);
spin_unlock(&cifs_tcp_ses_lock);
- /* For secondary channels, we pick up ref-count on the primary server */
- if (SERVER_IS_CHAN(server))
- cifs_put_tcp_session(server->primary_server, from_reconnect);
-
cancel_delayed_work_sync(&server->echo);
if (from_reconnect)
@@ -1629,6 +1625,10 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
else
cancel_delayed_work_sync(&server->reconnect);
+ /* For secondary channels, we pick up ref-count on the primary server */
+ if (SERVER_IS_CHAN(server))
+ cifs_put_tcp_session(server->primary_server, from_reconnect);
+
spin_lock(&server->srv_lock);
server->tcpStatus = CifsExiting;
spin_unlock(&server->srv_lock);