Commit 2f589679 authored by Aurelien Aptel's avatar Aurelien Aptel Committed by Steve French
Browse files

cifs: multichannel: try to rebind when reconnecting a channel



first steps in trying to make channels properly reconnect.

* add cifs_ses_find_chan() function to find the enclosing cifs_chan
  struct it belongs to
* while we have the session lock and are redoing negprot and
  sess.setup in smb2_reconnect() redo the binding of channels.

Signed-off-by: default avatarAurelien Aptel <aaptel@suse.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 8eec7954
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -593,6 +593,8 @@ void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);

extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
				unsigned int *len, unsigned int *offset);
struct cifs_chan *
cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
int cifs_try_adding_channels(struct cifs_ses *ses);
int cifs_ses_add_channel(struct cifs_ses *ses,
				struct cifs_server_iface *iface);
+16 −0
Original line number Diff line number Diff line
@@ -150,6 +150,22 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
	return ses->chan_count - old_chan_count;
}

/*
 * If server is a channel of ses, return the corresponding enclosing
 * cifs_chan otherwise return NULL.
 */
struct cifs_chan *
cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
{
	int i;

	for (i = 0; i < ses->chan_count; i++) {
		if (ses->chans[i].server == server)
			return &ses->chans[i];
	}
	return NULL;
}

int
cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
{
+16 −0
Original line number Diff line number Diff line
@@ -375,15 +375,31 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
		goto out;
	}

	/*
	 * If we are reconnecting an extra channel, bind
	 */
	if (server->is_channel) {
		ses->binding = true;
		ses->binding_chan = cifs_ses_find_chan(ses, server);
	}

	rc = cifs_negotiate_protocol(0, tcon->ses);
	if (!rc && tcon->ses->need_reconnect) {
		rc = cifs_setup_session(0, tcon->ses, nls_codepage);
		if ((rc == -EACCES) && !tcon->retry) {
			rc = -EHOSTDOWN;
			ses->binding = false;
			ses->binding_chan = NULL;
			mutex_unlock(&tcon->ses->session_mutex);
			goto failed;
		}
	}
	/*
	 * End of channel binding
	 */
	ses->binding = false;
	ses->binding_chan = NULL;

	if (rc || !tcon->need_reconnect) {
		mutex_unlock(&tcon->ses->session_mutex);
		goto out;