Skip to content

Commit d8532d7

Browse files
committed
cifs: account for primary channel in the interface list
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 fa1d050 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/fa1d0508.failed The refcounting of server interfaces should account for the primary channel too. Although this is not strictly necessary, doing so will account for the primary channel in DebugData. Cc: stable@vger.kernel.org Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com> Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit fa1d050) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # fs/cifs/sess.c
1 parent a7504d4 commit d8532d7

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
cifs: account for primary channel in the interface list
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 fa1d0508bdd4a68c5e40f85f635712af8c12f180
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/fa1d0508.failed
10+
11+
The refcounting of server interfaces should account
12+
for the primary channel too. Although this is not
13+
strictly necessary, doing so will account for the primary
14+
channel in DebugData.
15+
16+
Cc: stable@vger.kernel.org
17+
Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
18+
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
19+
Signed-off-by: Steve French <stfrench@microsoft.com>
20+
(cherry picked from commit fa1d0508bdd4a68c5e40f85f635712af8c12f180)
21+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
22+
23+
# Conflicts:
24+
# fs/cifs/sess.c
25+
diff --cc fs/cifs/sess.c
26+
index b9c9236e1312,e716d046fb5f..000000000000
27+
--- a/fs/cifs/sess.c
28+
+++ b/fs/cifs/sess.c
29+
@@@ -231,25 -298,61 +231,51 @@@ int cifs_try_adding_channels(struct cif
30+
int
31+
cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
32+
{
33+
- unsigned int chan_index;
34+
- size_t iface_weight = 0, iface_min_speed = 0;
35+
+ unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
36+
struct cifs_server_iface *iface = NULL;
37+
struct cifs_server_iface *old_iface = NULL;
38+
++<<<<<<< HEAD:fs/cifs/sess.c
39+
++=======
40+
+ struct cifs_server_iface *last_iface = NULL;
41+
+ struct sockaddr_storage ss;
42+
++>>>>>>> fa1d0508bdd4 (cifs: account for primary channel in the interface list):fs/smb/client/sess.c
43+
int rc = 0;
44+
45+
- spin_lock(&ses->chan_lock);
46+
- chan_index = cifs_ses_get_chan_index(ses, server);
47+
- if (chan_index == CIFS_INVAL_CHAN_INDEX) {
48+
- spin_unlock(&ses->chan_lock);
49+
+ /* primary channel. This can never go away */
50+
+ if (!chan_index)
51+
return 0;
52+
- }
53+
54+
if (ses->chans[chan_index].iface) {
55+
old_iface = ses->chans[chan_index].iface;
56+
- if (old_iface->is_active) {
57+
- spin_unlock(&ses->chan_lock);
58+
+ if (old_iface->is_active)
59+
return 1;
60+
- }
61+
}
62+
- spin_unlock(&ses->chan_lock);
63+
64+
+ spin_lock(&server->srv_lock);
65+
+ ss = server->dstaddr;
66+
+ spin_unlock(&server->srv_lock);
67+
+
68+
spin_lock(&ses->iface_lock);
69+
- if (!ses->iface_count) {
70+
- spin_unlock(&ses->iface_lock);
71+
- cifs_dbg(VFS, "server %s does not advertise interfaces\n", ses->server->hostname);
72+
- return 0;
73+
- }
74+
-
75+
- last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface,
76+
- iface_head);
77+
- iface_min_speed = last_iface->speed;
78+
79+
/* then look for a new one */
80+
list_for_each_entry(iface, &ses->iface_list, iface_head) {
81+
++<<<<<<< HEAD:fs/cifs/sess.c
82+
++=======
83+
+ if (!chan_index) {
84+
+ /* if we're trying to get the updated iface for primary channel */
85+
+ if (!cifs_match_ipaddr((struct sockaddr *) &ss,
86+
+ (struct sockaddr *) &iface->sockaddr))
87+
+ continue;
88+
+
89+
+ kref_get(&iface->refcount);
90+
+ break;
91+
+ }
92+
+
93+
+ /* do not mix rdma and non-rdma interfaces */
94+
+ if (iface->rdma_capable != server->rdma)
95+
+ continue;
96+
+
97+
++>>>>>>> fa1d0508bdd4 (cifs: account for primary channel in the interface list):fs/smb/client/sess.c
98+
if (!iface->is_active ||
99+
(is_ses_using_iface(ses, iface) &&
100+
!iface->rss_capable)) {
101+
@@@ -265,7 -375,12 +291,16 @@@
102+
cifs_dbg(FYI, "unable to find a suitable iface\n");
103+
}
104+
105+
++<<<<<<< HEAD:fs/cifs/sess.c
106+
+ ses->chans[chan_index].iface = iface;
107+
++=======
108+
+ if (!chan_index && !iface) {
109+
+ cifs_dbg(FYI, "unable to get the interface matching: %pIS\n",
110+
+ &ss);
111+
+ spin_unlock(&ses->iface_lock);
112+
+ return 0;
113+
+ }
114+
++>>>>>>> fa1d0508bdd4 (cifs: account for primary channel in the interface list):fs/smb/client/sess.c
115+
116+
/* now drop the ref to the current iface */
117+
if (old_iface && iface) {
118+
@@@ -276,7 -398,18 +311,13 @@@
119+
} else if (old_iface) {
120+
cifs_dbg(FYI, "releasing ref to iface: %pIS\n",
121+
&old_iface->sockaddr);
122+
-
123+
- old_iface->num_channels--;
124+
- if (old_iface->weight_fulfilled)
125+
- old_iface->weight_fulfilled--;
126+
-
127+
kref_put(&old_iface->refcount, release_iface);
128+
+ } else if (!chan_index) {
129+
+ /* special case: update interface for primary channel */
130+
+ cifs_dbg(FYI, "referencing primary channel iface: %pIS\n",
131+
+ &iface->sockaddr);
132+
+ iface->num_channels++;
133+
+ iface->weight_fulfilled++;
134+
} else {
135+
WARN_ON(!iface);
136+
cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr);
137+
* Unmerged path fs/cifs/sess.c
138+
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
139+
index 06fe88efbf89..ca9630b8bae7 100644
140+
--- a/fs/cifs/smb2ops.c
141+
+++ b/fs/cifs/smb2ops.c
142+
@@ -703,6 +703,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
143+
unsigned int ret_data_len = 0;
144+
struct network_interface_info_ioctl_rsp *out_buf = NULL;
145+
struct cifs_ses *ses = tcon->ses;
146+
+ struct TCP_Server_Info *pserver;
147+
148+
/* do not query too frequently */
149+
if (ses->iface_last_update &&
150+
@@ -727,6 +728,11 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
151+
if (rc)
152+
goto out;
153+
154+
+ /* check if iface is still active */
155+
+ pserver = ses->chans[0].server;
156+
+ if (pserver && !cifs_chan_is_iface_active(ses, pserver))
157+
+ cifs_chan_update_iface(ses, pserver);
158+
+
159+
out:
160+
kfree(out_buf);
161+
return rc;

0 commit comments

Comments
 (0)