aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/cifssmb.c3
-rw-r--r--fs/cifs/connect.c78
3 files changed, 52 insertions, 33 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 8e9214275e42..6fa808ec7e36 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -138,7 +138,9 @@ extern void cifs_dfs_release_automount_timer(void);
138void cifs_proc_init(void); 138void cifs_proc_init(void);
139void cifs_proc_clean(void); 139void cifs_proc_clean(void);
140 140
141extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 141extern int cifs_negotiate_protocol(unsigned int xid,
142 struct cifsSesInfo *ses);
143extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
142 struct nls_table *nls_info); 144 struct nls_table *nls_info);
143extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); 145extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
144 146
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 1372253a0606..30742d8eef14 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -172,7 +172,8 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
172 * reconnect the same SMB session 172 * reconnect the same SMB session
173 */ 173 */
174 mutex_lock(&ses->session_mutex); 174 mutex_lock(&ses->session_mutex);
175 if (ses->need_reconnect) 175 rc = cifs_negotiate_protocol(0, ses);
176 if (rc == 0 && ses->need_reconnect)
176 rc = cifs_setup_session(0, ses, nls_codepage); 177 rc = cifs_setup_session(0, ses, nls_codepage);
177 178
178 /* do we need to reconnect tcon? */ 179 /* do we need to reconnect tcon? */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9123c23bd1d9..2208f06e4c45 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1651,6 +1651,14 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1651 cifs_put_tcp_session(server); 1651 cifs_put_tcp_session(server);
1652 1652
1653 mutex_lock(&ses->session_mutex); 1653 mutex_lock(&ses->session_mutex);
1654 rc = cifs_negotiate_protocol(xid, ses);
1655 if (rc) {
1656 mutex_unlock(&ses->session_mutex);
1657 /* problem -- put our ses reference */
1658 cifs_put_smb_ses(ses);
1659 FreeXid(xid);
1660 return ERR_PTR(rc);
1661 }
1654 if (ses->need_reconnect) { 1662 if (ses->need_reconnect) {
1655 cFYI(1, "Session needs reconnect"); 1663 cFYI(1, "Session needs reconnect");
1656 rc = cifs_setup_session(xid, ses, 1664 rc = cifs_setup_session(xid, ses,
@@ -1702,7 +1710,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1702 ses->overrideSecFlg = volume_info->secFlg; 1710 ses->overrideSecFlg = volume_info->secFlg;
1703 1711
1704 mutex_lock(&ses->session_mutex); 1712 mutex_lock(&ses->session_mutex);
1705 rc = cifs_setup_session(xid, ses, volume_info->local_nls); 1713 rc = cifs_negotiate_protocol(xid, ses);
1714 if (!rc)
1715 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1706 mutex_unlock(&ses->session_mutex); 1716 mutex_unlock(&ses->session_mutex);
1707 if (rc) 1717 if (rc)
1708 goto get_ses_fail; 1718 goto get_ses_fail;
@@ -2874,55 +2884,61 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
2874 return rc; 2884 return rc;
2875} 2885}
2876 2886
2877int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 2887int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
2878 struct nls_table *nls_info)
2879{ 2888{
2880 int rc = 0; 2889 int rc = 0;
2881 struct TCP_Server_Info *server = pSesInfo->server; 2890 struct TCP_Server_Info *server = ses->server;
2882
2883 /* what if server changes its buffer size after dropping the session? */
2884 if (server->maxBuf == 0) /* no need to send on reconnect */ {
2885 rc = CIFSSMBNegotiate(xid, pSesInfo);
2886 if (rc == -EAGAIN) {
2887 /* retry only once on 1st time connection */
2888 rc = CIFSSMBNegotiate(xid, pSesInfo);
2889 if (rc == -EAGAIN)
2890 rc = -EHOSTDOWN;
2891 }
2892 if (rc == 0) {
2893 spin_lock(&GlobalMid_Lock);
2894 if (server->tcpStatus != CifsExiting)
2895 server->tcpStatus = CifsGood;
2896 else
2897 rc = -EHOSTDOWN;
2898 spin_unlock(&GlobalMid_Lock);
2899 2891
2900 } 2892 /* only send once per connect */
2893 if (server->maxBuf != 0)
2894 return 0;
2895
2896 rc = CIFSSMBNegotiate(xid, ses);
2897 if (rc == -EAGAIN) {
2898 /* retry only once on 1st time connection */
2899 rc = CIFSSMBNegotiate(xid, ses);
2900 if (rc == -EAGAIN)
2901 rc = -EHOSTDOWN;
2901 } 2902 }
2903 if (rc == 0) {
2904 spin_lock(&GlobalMid_Lock);
2905 if (server->tcpStatus != CifsExiting)
2906 server->tcpStatus = CifsGood;
2907 else
2908 rc = -EHOSTDOWN;
2909 spin_unlock(&GlobalMid_Lock);
2902 2910
2903 if (rc) 2911 }
2904 goto ss_err_exit; 2912
2913 return rc;
2914}
2915
2916
2917int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
2918 struct nls_table *nls_info)
2919{
2920 int rc = 0;
2921 struct TCP_Server_Info *server = ses->server;
2905 2922
2906 pSesInfo->flags = 0; 2923 ses->flags = 0;
2907 pSesInfo->capabilities = server->capabilities; 2924 ses->capabilities = server->capabilities;
2908 if (linuxExtEnabled == 0) 2925 if (linuxExtEnabled == 0)
2909 pSesInfo->capabilities &= (~CAP_UNIX); 2926 ses->capabilities &= (~CAP_UNIX);
2910 2927
2911 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 2928 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
2912 server->secMode, server->capabilities, server->timeAdj); 2929 server->secMode, server->capabilities, server->timeAdj);
2913 2930
2914 rc = CIFS_SessSetup(xid, pSesInfo, nls_info); 2931 rc = CIFS_SessSetup(xid, ses, nls_info);
2915 if (rc) { 2932 if (rc) {
2916 cERROR(1, "Send error in SessSetup = %d", rc); 2933 cERROR(1, "Send error in SessSetup = %d", rc);
2917 } else { 2934 } else {
2918 cFYI(1, "CIFS Session Established successfully"); 2935 cFYI(1, "CIFS Session Established successfully");
2919 spin_lock(&GlobalMid_Lock); 2936 spin_lock(&GlobalMid_Lock);
2920 pSesInfo->status = CifsGood; 2937 ses->status = CifsGood;
2921 pSesInfo->need_reconnect = false; 2938 ses->need_reconnect = false;
2922 spin_unlock(&GlobalMid_Lock); 2939 spin_unlock(&GlobalMid_Lock);
2923 } 2940 }
2924 2941
2925ss_err_exit:
2926 return rc; 2942 return rc;
2927} 2943}
2928 2944