summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;