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: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
8eec79540d
commit
2f58967979
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue