Skip to content

Commit a71c716

Browse files
committed
cifs: cifs_chan_is_iface_active should be called with chan_lock held
jira LE-4669 Rebuild_History Non-Buildable kernel-4.18.0-553.82.1.el8_10 commit-author Shyam Prasad N <sprasad@microsoft.com> commit 7257bcf Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-4.18.0-553.82.1.el8_10/7257bcf3.failed cifs_chan_is_iface_active checks the channels of a session to see if the associated iface is active. This should always happen with chan_lock held. However, these two callers of this function were missing this locking. This change makes sure the function calls are protected with proper locking. Fixes: b54034a ("cifs: during reconnect, update interface if necessary") Fixes: fa1d050 ("cifs: account for primary channel in the interface list") Cc: stable@vger.kernel.org Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit 7257bcf) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # fs/cifs/connect.c # fs/cifs/smb2ops.c
1 parent d8532d7 commit a71c716

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
cifs: cifs_chan_is_iface_active should be called with chan_lock held
2+
3+
jira LE-4669
4+
Rebuild_History Non-Buildable kernel-4.18.0-553.82.1.el8_10
5+
commit-author Shyam Prasad N <sprasad@microsoft.com>
6+
commit 7257bcf3bdc785eabc4eef1f329a59815b032508
7+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
8+
Will be included in final tarball splat. Ref for failed cherry-pick at:
9+
ciq/ciq_backports/kernel-4.18.0-553.82.1.el8_10/7257bcf3.failed
10+
11+
cifs_chan_is_iface_active checks the channels of a session to see
12+
if the associated iface is active. This should always happen
13+
with chan_lock held. However, these two callers of this function
14+
were missing this locking.
15+
16+
This change makes sure the function calls are protected with
17+
proper locking.
18+
19+
Fixes: b54034a73baf ("cifs: during reconnect, update interface if necessary")
20+
Fixes: fa1d0508bdd4 ("cifs: account for primary channel in the interface list")
21+
Cc: stable@vger.kernel.org
22+
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
23+
Signed-off-by: Steve French <stfrench@microsoft.com>
24+
(cherry picked from commit 7257bcf3bdc785eabc4eef1f329a59815b032508)
25+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
26+
27+
# Conflicts:
28+
# fs/cifs/connect.c
29+
# fs/cifs/smb2ops.c
30+
diff --cc fs/cifs/connect.c
31+
index ca2926c7b59e,dc9b95ca71e6..000000000000
32+
--- a/fs/cifs/connect.c
33+
+++ b/fs/cifs/connect.c
34+
@@@ -207,50 -211,88 +207,60 @@@ static void cifs_mark_tcp_ses_conns_for
35+
* before reconnecting the tcp session, mark the smb session (uid) and the tid bad so they
36+
* are not used until reconnected.
37+
*/
38+
- cifs_dbg(FYI, "%s: marking necessary sessions and tcons for reconnect\n", __func__);
39+
+ cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n", __func__);
40+
41+
/* If server is a channel, select the primary channel */
42+
- pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
43+
-
44+
- /*
45+
- * if the server has been marked for termination, there is a
46+
- * chance that the remaining channels all need reconnect. To be
47+
- * on the safer side, mark the session and trees for reconnect
48+
- * for this scenario. This might cause a few redundant session
49+
- * setup and tree connect requests, but it is better than not doing
50+
- * a tree connect when needed, and all following requests failing
51+
- */
52+
- if (server->terminate) {
53+
- mark_smb_session = true;
54+
- server = pserver;
55+
- }
56+
+ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
57+
58+
spin_lock(&cifs_tcp_ses_lock);
59+
- list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) {
60+
+ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
61+
/* check if iface is still active */
62+
- if (!cifs_chan_is_iface_active(ses, server))
63+
- cifs_chan_update_iface(ses, server);
64+
-
65+
spin_lock(&ses->chan_lock);
66+
++<<<<<<< HEAD:fs/cifs/connect.c
67+
+ if (cifs_chan_needs_reconnect(ses, server))
68+
+ goto next_session;
69+
++=======
70+
+ if (!cifs_chan_is_iface_active(ses, server)) {
71+
+ spin_unlock(&ses->chan_lock);
72+
+ cifs_chan_update_iface(ses, server);
73+
+ spin_lock(&ses->chan_lock);
74+
+ }
75+
+
76+
+ if (!mark_smb_session && cifs_chan_needs_reconnect(ses, server)) {
77+
+ spin_unlock(&ses->chan_lock);
78+
+ continue;
79+
+ }
80+
++>>>>>>> 7257bcf3bdc7 (cifs: cifs_chan_is_iface_active should be called with chan_lock held):fs/smb/client/connect.c
81+
82+
- if (mark_smb_session)
83+
- CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses);
84+
- else
85+
- cifs_chan_set_need_reconnect(ses, server);
86+
-
87+
- cifs_dbg(FYI, "%s: channel connect bitmap: 0x%lx\n",
88+
- __func__, ses->chans_need_reconnect);
89+
+ cifs_chan_set_need_reconnect(ses, server);
90+
91+
/* If all channels need reconnect, then tcon needs reconnect */
92+
- if (!mark_smb_session && !CIFS_ALL_CHANS_NEED_RECONNECT(ses)) {
93+
- spin_unlock(&ses->chan_lock);
94+
- continue;
95+
- }
96+
- spin_unlock(&ses->chan_lock);
97+
+ if (!CIFS_ALL_CHANS_NEED_RECONNECT(ses))
98+
+ goto next_session;
99+
100+
- spin_lock(&ses->ses_lock);
101+
- ses->ses_status = SES_NEED_RECON;
102+
- spin_unlock(&ses->ses_lock);
103+
+ num_sessions++;
104+
105+
- list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
106+
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list)
107+
tcon->need_reconnect = true;
108+
- spin_lock(&tcon->tc_lock);
109+
- tcon->status = TID_NEED_RECON;
110+
- spin_unlock(&tcon->tc_lock);
111+
-
112+
- cancel_delayed_work(&tcon->query_interfaces);
113+
- }
114+
- if (ses->tcon_ipc) {
115+
+ if (ses->tcon_ipc)
116+
ses->tcon_ipc->need_reconnect = true;
117+
- spin_lock(&ses->tcon_ipc->tc_lock);
118+
- ses->tcon_ipc->status = TID_NEED_RECON;
119+
- spin_unlock(&ses->tcon_ipc->tc_lock);
120+
- }
121+
+
122+
+next_session:
123+
+ spin_unlock(&ses->chan_lock);
124+
}
125+
spin_unlock(&cifs_tcp_ses_lock);
126+
-}
127+
-
128+
-static void
129+
-cifs_abort_connection(struct TCP_Server_Info *server)
130+
-{
131+
- struct mid_q_entry *mid, *nmid;
132+
- struct list_head retry_list;
133+
-
134+
- server->maxBuf = 0;
135+
- server->max_read = 0;
136+
137+
+ if (num_sessions == 0)
138+
+ return;
139+
+ /*
140+
+ * before reconnecting the tcp session, mark the smb session (uid)
141+
+ * and the tid bad so they are not used until reconnected
142+
+ */
143+
+ cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
144+
+ __func__);
145+
/* do not want to be sending data on a socket we are freeing */
146+
cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
147+
- cifs_server_lock(server);
148+
+ mutex_lock(&server->srv_mutex);
149+
if (server->ssocket) {
150+
cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", server->ssocket->state,
151+
server->ssocket->flags);
152+
diff --cc fs/cifs/smb2ops.c
153+
index 06fe88efbf89,c8722e82274f..000000000000
154+
--- a/fs/cifs/smb2ops.c
155+
+++ b/fs/cifs/smb2ops.c
156+
@@@ -727,6 -783,16 +727,19 @@@ SMB3_request_interfaces(const unsigned
157+
if (rc)
158+
goto out;
159+
160+
++<<<<<<< HEAD:fs/cifs/smb2ops.c
161+
++=======
162+
+ /* check if iface is still active */
163+
+ spin_lock(&ses->chan_lock);
164+
+ pserver = ses->chans[0].server;
165+
+ if (pserver && !cifs_chan_is_iface_active(ses, pserver)) {
166+
+ spin_unlock(&ses->chan_lock);
167+
+ cifs_chan_update_iface(ses, pserver);
168+
+ spin_lock(&ses->chan_lock);
169+
+ }
170+
+ spin_unlock(&ses->chan_lock);
171+
+
172+
++>>>>>>> 7257bcf3bdc7 (cifs: cifs_chan_is_iface_active should be called with chan_lock held):fs/smb/client/smb2ops.c
173+
out:
174+
kfree(out_buf);
175+
return rc;
176+
* Unmerged path fs/cifs/connect.c
177+
* Unmerged path fs/cifs/smb2ops.c

0 commit comments

Comments
 (0)