summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorAurelien Aptel <aaptel@suse.com>2020-04-22 15:58:57 +0200
committerSteve French <stfrench@microsoft.com>2020-06-02 09:58:41 -0500
commit5f68ea4aa98bcddb5ec5229d2a0933d84ed17732 (patch)
tree7baa63a0ea83697cc0b45181a155140e1068825f /fs/cifs
parentbbbf9eafbfdaa2af75fb5ed6d5ddb01be89e6d30 (diff)
downloadlinux-5f68ea4aa98bcddb5ec5229d2a0933d84ed17732.tar.bz2
cifs: multichannel: move channel selection in function
This commit moves channel picking code in separate function. Signed-off-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/transport.c38
2 files changed, 28 insertions, 11 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 8036216ce434..9767f9b5d315 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -96,6 +96,7 @@ extern int cifs_call_async(struct TCP_Server_Info *server,
mid_receive_t *receive, mid_callback_t *callback,
mid_handle_t *handle, void *cbdata, const int flags,
const struct cifs_credits *exist_credits);
+extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
struct smb_rqst *rqst, int *resp_buf_type,
const int flags, struct kvec *resp_iov);
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index c359221d6848..4d4cb26d2ae1 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -992,6 +992,32 @@ cifs_cancelled_callback(struct mid_q_entry *mid)
DeleteMidQEntry(mid);
}
+/*
+ * Return a channel (master if none) of @ses that can be used to send
+ * regular requests.
+ *
+ * If we are currently binding a new channel (negprot/sess.setup),
+ * return the new incomplete channel.
+ */
+struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
+{
+ uint index = 0;
+
+ if (!ses)
+ return NULL;
+
+ if (!ses->binding) {
+ /* round robin */
+ if (ses->chan_count > 1) {
+ index = (uint)atomic_inc_return(&ses->chan_seq);
+ index %= ses->chan_count;
+ }
+ return ses->chans[index].server;
+ } else {
+ return cifs_ses_server(ses);
+ }
+}
+
int
compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
const int flags, const int num_rqst, struct smb_rqst *rqst,
@@ -1017,17 +1043,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
return -EIO;
}
- if (!ses->binding) {
- uint index = 0;
-
- if (ses->chan_count > 1) {
- index = (uint)atomic_inc_return(&ses->chan_seq);
- index %= ses->chan_count;
- }
- server = ses->chans[index].server;
- } else {
- server = cifs_ses_server(ses);
- }
+ server = cifs_pick_channel(ses);
if (server->tcpStatus == CifsExiting)
return -ENOENT;