Skip to content

Commit 6cc041e

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: avoid races in parallel reconnects in smb1
Prevent multiple threads of doing negotiate, session setup and tree connect by holding @ses->session_mutex in cifs_reconnect_tcon() while reconnecting session and tcon. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Reviewed-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 179a88a commit 6cc041e

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

fs/cifs/cifssmb.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
7171
int rc;
7272
struct cifs_ses *ses;
7373
struct TCP_Server_Info *server;
74-
struct nls_table *nls_codepage;
74+
struct nls_table *nls_codepage = NULL;
7575

7676
/*
7777
* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
@@ -99,6 +99,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
9999
}
100100
spin_unlock(&tcon->tc_lock);
101101

102+
again:
102103
rc = cifs_wait_for_server_reconnect(server, tcon->retry);
103104
if (rc)
104105
return rc;
@@ -110,8 +111,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
110111
}
111112
spin_unlock(&ses->chan_lock);
112113

113-
nls_codepage = load_nls_default();
114-
114+
mutex_lock(&ses->session_mutex);
115115
/*
116116
* Recheck after acquire mutex. If another thread is negotiating
117117
* and the server never sends an answer the socket will be closed
@@ -120,29 +120,38 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
120120
spin_lock(&server->srv_lock);
121121
if (server->tcpStatus == CifsNeedReconnect) {
122122
spin_unlock(&server->srv_lock);
123+
mutex_lock(&ses->session_mutex);
124+
125+
if (tcon->retry)
126+
goto again;
123127
rc = -EHOSTDOWN;
124128
goto out;
125129
}
126130
spin_unlock(&server->srv_lock);
127131

132+
nls_codepage = load_nls_default();
133+
128134
/*
129135
* need to prevent multiple threads trying to simultaneously
130136
* reconnect the same SMB session
131137
*/
138+
spin_lock(&ses->ses_lock);
132139
spin_lock(&ses->chan_lock);
133-
if (!cifs_chan_needs_reconnect(ses, server)) {
140+
if (!cifs_chan_needs_reconnect(ses, server) &&
141+
ses->ses_status == SES_GOOD) {
134142
spin_unlock(&ses->chan_lock);
143+
spin_unlock(&ses->ses_lock);
135144

136145
/* this means that we only need to tree connect */
137146
if (tcon->need_reconnect)
138147
goto skip_sess_setup;
139148

140-
rc = -EHOSTDOWN;
149+
mutex_unlock(&ses->session_mutex);
141150
goto out;
142151
}
143152
spin_unlock(&ses->chan_lock);
153+
spin_unlock(&ses->ses_lock);
144154

145-
mutex_lock(&ses->session_mutex);
146155
rc = cifs_negotiate_protocol(0, ses, server);
147156
if (!rc)
148157
rc = cifs_setup_session(0, ses, server, nls_codepage);

0 commit comments

Comments
 (0)