summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurelien Aptel <aaptel@suse.com>2020-04-24 15:24:05 +0200
committerSteve French <stfrench@microsoft.com>2020-06-04 13:50:55 -0500
commit8eec79540d2b9cec385707be45f6e9388b34020f (patch)
treee3544323d087c547495019aa4f6d92b95aa04797
parentedb161353680e6d488d94cbcaf967745bee98d17 (diff)
downloadlinux-8eec79540d2b9cec385707be45f6e9388b34020f.tar.gz
linux-8eec79540d2b9cec385707be45f6e9388b34020f.tar.bz2
linux-8eec79540d2b9cec385707be45f6e9388b34020f.zip
cifs: multichannel: use pointer for binding channel
Add a cifs_chan pointer in struct cifs_ses that points to the channel currently being bound if ses->binding is true. Previously it was always the channel past the established count. This will make reconnecting (and rebinding) a channel easier later on. Signed-off-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/cifs/cifsglob.h15
-rw-r--r--fs/cifs/sess.c3
2 files changed, 14 insertions, 4 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index c0cbbd0bbb1d..e133bb3e172f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1030,6 +1030,7 @@ struct cifs_ses {
#define CIFS_MAX_CHANNELS 16
struct cifs_chan chans[CIFS_MAX_CHANNELS];
+ struct cifs_chan *binding_chan;
size_t chan_count;
size_t chan_max;
atomic_t chan_seq; /* round robin state */
@@ -1037,23 +1038,31 @@ struct cifs_ses {
/*
* When binding a new channel, we need to access the channel which isn't fully
- * established yet (one past the established count)
+ * established yet.
*/
static inline
struct cifs_chan *cifs_ses_binding_channel(struct cifs_ses *ses)
{
if (ses->binding)
- return &ses->chans[ses->chan_count];
+ return ses->binding_chan;
else
return NULL;
}
+/*
+ * Returns the server pointer of the session. When binding a new
+ * channel this returns the last channel which isn't fully established
+ * yet.
+ *
+ * This function should be use for negprot/sess.setup codepaths. For
+ * the other requests see cifs_pick_channel().
+ */
static inline
struct TCP_Server_Info *cifs_ses_server(struct cifs_ses *ses)
{
if (ses->binding)
- return ses->chans[ses->chan_count].server;
+ return ses->binding_chan->server;
else
return ses->server;
}
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 0ae25cc77fc0..1ffdd7dadc55 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -231,7 +231,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
mutex_lock(&ses->session_mutex);
- chan = &ses->chans[ses->chan_count];
+ chan = ses->binding_chan = &ses->chans[ses->chan_count];
chan->server = cifs_get_tcp_session(&vol);
if (IS_ERR(chan->server)) {
rc = PTR_ERR(chan->server);
@@ -276,6 +276,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
atomic_set(&ses->chan_seq, 0);
out:
ses->binding = false;
+ ses->binding_chan = NULL;
mutex_unlock(&ses->session_mutex);
if (rc && chan->server)