diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsproto.h | 4 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 3 | ||||
-rw-r--r-- | fs/cifs/connect.c | 78 |
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); | |||
138 | void cifs_proc_init(void); | 138 | void cifs_proc_init(void); |
139 | void cifs_proc_clean(void); | 139 | void cifs_proc_clean(void); |
140 | 140 | ||
141 | extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | 141 | extern int cifs_negotiate_protocol(unsigned int xid, |
142 | struct cifsSesInfo *ses); | ||
143 | extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, | ||
142 | struct nls_table *nls_info); | 144 | struct nls_table *nls_info); |
143 | extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); | 145 | extern 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 | ||
2877 | int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | 2887 | int 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 | |||
2917 | int 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 | ||
2925 | ss_err_exit: | ||
2926 | return rc; | 2942 | return rc; |
2927 | } | 2943 | } |
2928 | 2944 | ||