Skip to content

Commit f7772da

Browse files
committed
Merge tag '6.3-rc4-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs client fixes from Steve French: "Four cifs/smb3 client (reconnect and DFS related) fixes, including two for stable: - DFS oops fix - DFS reconnect recursion fix - An SMB1 parallel reconnect fix - Trivial dead code removal in smb2_reconnect" * tag '6.3-rc4-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: get rid of dead check in smb2_reconnect() cifs: prevent infinite recursion in CIFSGetDFSRefer() cifs: avoid races in parallel reconnects in smb1 cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL
2 parents 00c7b5f + e036771 commit f7772da

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

fs/cifs/cifsfs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ extern const struct dentry_operations cifs_ci_dentry_ops;
124124
#ifdef CONFIG_CIFS_DFS_UPCALL
125125
extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
126126
#else
127-
#define cifs_dfs_d_automount NULL
127+
static inline struct vfsmount *cifs_dfs_d_automount(struct path *path)
128+
{
129+
return ERR_PTR(-EREMOTE);
130+
}
128131
#endif
129132

130133
/* Functions related to symlinks */

fs/cifs/cifssmb.c

Lines changed: 22 additions & 8 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);
@@ -4373,8 +4382,13 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
43734382
return -ENODEV;
43744383

43754384
getDFSRetry:
4376-
rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB,
4377-
(void **) &pSMBr);
4385+
/*
4386+
* Use smb_init_no_reconnect() instead of smb_init() as
4387+
* CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus
4388+
* causing an infinite recursion.
4389+
*/
4390+
rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
4391+
(void **)&pSMB, (void **)&pSMBr);
43784392
if (rc)
43794393
return rc;
43804394

fs/cifs/smb2pdu.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
310310
case SMB2_READ:
311311
case SMB2_WRITE:
312312
case SMB2_LOCK:
313-
case SMB2_IOCTL:
314313
case SMB2_QUERY_DIRECTORY:
315314
case SMB2_CHANGE_NOTIFY:
316315
case SMB2_QUERY_INFO:

0 commit comments

Comments
 (0)