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

Changed files
+26 -10
fs
+4 -1
fs/cifs/cifsfs.h
··· 124 124 #ifdef CONFIG_CIFS_DFS_UPCALL 125 125 extern struct vfsmount *cifs_dfs_d_automount(struct path *path); 126 126 #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 + } 128 131 #endif 129 132 130 133 /* Functions related to symlinks */
+22 -8
fs/cifs/cifssmb.c
··· 71 71 int rc; 72 72 struct cifs_ses *ses; 73 73 struct TCP_Server_Info *server; 74 - struct nls_table *nls_codepage; 74 + struct nls_table *nls_codepage = NULL; 75 75 76 76 /* 77 77 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for ··· 99 99 } 100 100 spin_unlock(&tcon->tc_lock); 101 101 102 + again: 102 103 rc = cifs_wait_for_server_reconnect(server, tcon->retry); 103 104 if (rc) 104 105 return rc; ··· 111 110 } 112 111 spin_unlock(&ses->chan_lock); 113 112 114 - nls_codepage = load_nls_default(); 115 - 113 + mutex_lock(&ses->session_mutex); 116 114 /* 117 115 * Recheck after acquire mutex. If another thread is negotiating 118 116 * and the server never sends an answer the socket will be closed ··· 120 120 spin_lock(&server->srv_lock); 121 121 if (server->tcpStatus == CifsNeedReconnect) { 122 122 spin_unlock(&server->srv_lock); 123 + mutex_lock(&ses->session_mutex); 124 + 125 + if (tcon->retry) 126 + goto again; 123 127 rc = -EHOSTDOWN; 124 128 goto out; 125 129 } 126 130 spin_unlock(&server->srv_lock); 127 131 132 + nls_codepage = load_nls_default(); 133 + 128 134 /* 129 135 * need to prevent multiple threads trying to simultaneously 130 136 * reconnect the same SMB session 131 137 */ 138 + spin_lock(&ses->ses_lock); 132 139 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) { 134 142 spin_unlock(&ses->chan_lock); 143 + spin_unlock(&ses->ses_lock); 135 144 136 145 /* this means that we only need to tree connect */ 137 146 if (tcon->need_reconnect) 138 147 goto skip_sess_setup; 139 148 140 - rc = -EHOSTDOWN; 149 + mutex_unlock(&ses->session_mutex); 141 150 goto out; 142 151 } 143 152 spin_unlock(&ses->chan_lock); 153 + spin_unlock(&ses->ses_lock); 144 154 145 - mutex_lock(&ses->session_mutex); 146 155 rc = cifs_negotiate_protocol(0, ses, server); 147 156 if (!rc) 148 157 rc = cifs_setup_session(0, ses, server, nls_codepage); ··· 4382 4373 return -ENODEV; 4383 4374 4384 4375 getDFSRetry: 4385 - rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB, 4386 - (void **) &pSMBr); 4376 + /* 4377 + * Use smb_init_no_reconnect() instead of smb_init() as 4378 + * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus 4379 + * causing an infinite recursion. 4380 + */ 4381 + rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, 4382 + (void **)&pSMB, (void **)&pSMBr); 4387 4383 if (rc) 4388 4384 return rc; 4389 4385
-1
fs/cifs/smb2pdu.c
··· 310 310 case SMB2_READ: 311 311 case SMB2_WRITE: 312 312 case SMB2_LOCK: 313 - case SMB2_IOCTL: 314 313 case SMB2_QUERY_DIRECTORY: 315 314 case SMB2_CHANGE_NOTIFY: 316 315 case SMB2_QUERY_INFO: