summaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index fa80a23f9fcf..9ee5856d63cc 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -169,6 +169,7 @@ static void cifs_resolve_server(struct work_struct *work)
*/
static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server)
{
+ unsigned int num_sessions = 0;
struct cifs_ses *ses;
struct cifs_tcon *tcon;
struct mid_q_entry *mid, *nmid;
@@ -201,6 +202,8 @@ static void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server
if (!CIFS_ALL_CHANS_NEED_RECONNECT(ses))
goto next_session;
+ num_sessions++;
+
list_for_each_entry(tcon, &ses->tcon_list, tcon_list)
tcon->need_reconnect = true;
if (ses->tcon_ipc)
@@ -211,6 +214,14 @@ next_session:
}
spin_unlock(&cifs_tcp_ses_lock);
+ if (num_sessions == 0)
+ return;
+ /*
+ * before reconnecting the tcp session, mark the smb session (uid)
+ * and the tid bad so they are not used until reconnected
+ */
+ cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
+ __func__);
/* do not want to be sending data on a socket we are freeing */
cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
mutex_lock(&server->srv_mutex);
@@ -2005,7 +2016,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
spin_unlock(&ses->chan_lock);
cifs_dbg(FYI, "Session needs reconnect\n");
- rc = cifs_negotiate_protocol(xid, ses);
+ rc = cifs_negotiate_protocol(xid, ses, server);
if (rc) {
mutex_unlock(&ses->session_mutex);
/* problem -- put our ses reference */
@@ -2014,7 +2025,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
return ERR_PTR(rc);
}
- rc = cifs_setup_session(xid, ses,
+ rc = cifs_setup_session(xid, ses, server,
ctx->local_nls);
if (rc) {
mutex_unlock(&ses->session_mutex);
@@ -2086,9 +2097,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
ses->chans_need_reconnect = 1;
spin_unlock(&ses->chan_lock);
- rc = cifs_negotiate_protocol(xid, ses);
+ rc = cifs_negotiate_protocol(xid, ses, server);
if (!rc)
- rc = cifs_setup_session(xid, ses, ctx->local_nls);
+ rc = cifs_setup_session(xid, ses, server, ctx->local_nls);
/* each channel uses a different signing key */
memcpy(ses->chans[0].signkey, ses->smb3signingkey,
@@ -3820,10 +3831,10 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
}
int
-cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
+cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
+ struct TCP_Server_Info *server)
{
int rc = 0;
- struct TCP_Server_Info *server = cifs_ses_server(ses);
if (!server->ops->need_neg || !server->ops->negotiate)
return -ENOSYS;
@@ -3832,7 +3843,7 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
if (!server->ops->need_neg(server))
return 0;
- rc = server->ops->negotiate(xid, ses);
+ rc = server->ops->negotiate(xid, ses, server);
if (rc == 0) {
spin_lock(&GlobalMid_Lock);
if (server->tcpStatus == CifsNeedNegotiate)
@@ -3847,12 +3858,17 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
int
cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
+ struct TCP_Server_Info *server,
struct nls_table *nls_info)
{
int rc = -ENOSYS;
- struct TCP_Server_Info *server = cifs_ses_server(ses);
+ bool is_binding = false;
+
+ spin_lock(&ses->chan_lock);
+ is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
+ spin_unlock(&ses->chan_lock);
- if (!ses->binding) {
+ if (!is_binding) {
ses->capabilities = server->capabilities;
if (!linuxExtEnabled)
ses->capabilities &= (~server->vals->cap_unix);
@@ -3870,7 +3886,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
server->sec_mode, server->capabilities, server->timeAdj);
if (server->ops->sess_setup)
- rc = server->ops->sess_setup(xid, ses, nls_info);
+ rc = server->ops->sess_setup(xid, ses, server, nls_info);
if (rc)
cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc);