aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-05-25 02:43:58 -0400
committerSteve French <smfrench@gmail.com>2012-07-24 01:33:26 -0400
commit286170aa241819f39d9d1d5d9f2434cfb8519506 (patch)
treef7f4a8fd6eb653ac0f40cab9e8468462316fe41e
parenta891f0f895f4a760fdb99636fab05e60597b8224 (diff)
CIFS: Move protocol specific negotiate code to ops struct
Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r--fs/cifs/cifsglob.h8
-rw-r--r--fs/cifs/cifsproto.h6
-rw-r--r--fs/cifs/cifssmb.c4
-rw-r--r--fs/cifs/connect.c24
-rw-r--r--fs/cifs/sess.c2
-rw-r--r--fs/cifs/smb1ops.c23
6 files changed, 46 insertions, 21 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 844b77c2bc9c..8a4150573cf8 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -192,6 +192,10 @@ struct smb_version_operations {
192 /* process transaction2 response */ 192 /* process transaction2 response */
193 bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, 193 bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
194 char *, int); 194 char *, int);
195 /* check if we need to negotiate */
196 bool (*need_neg)(struct TCP_Server_Info *);
197 /* negotiate to the server */
198 int (*negotiate)(const unsigned int, struct cifs_ses *);
195}; 199};
196 200
197struct smb_version_values { 201struct smb_version_values {
@@ -324,7 +328,7 @@ struct TCP_Server_Info {
324 struct mutex srv_mutex; 328 struct mutex srv_mutex;
325 struct task_struct *tsk; 329 struct task_struct *tsk;
326 char server_GUID[16]; 330 char server_GUID[16];
327 char sec_mode; 331 __u16 sec_mode;
328 bool session_estab; /* mark when very first sess is established */ 332 bool session_estab; /* mark when very first sess is established */
329 u16 dialect; /* dialect index that server chose */ 333 u16 dialect; /* dialect index that server chose */
330 enum securityEnum secType; 334 enum securityEnum secType;
@@ -459,7 +463,7 @@ struct cifs_ses {
459 char *serverOS; /* name of operating system underlying server */ 463 char *serverOS; /* name of operating system underlying server */
460 char *serverNOS; /* name of network operating system of server */ 464 char *serverNOS; /* name of network operating system of server */
461 char *serverDomain; /* security realm of server */ 465 char *serverDomain; /* security realm of server */
462 int Suid; /* remote smb uid */ 466 __u64 Suid; /* remote smb uid */
463 uid_t linux_uid; /* overriding owner of files on the mount */ 467 uid_t linux_uid; /* overriding owner of files on the mount */
464 uid_t cred_uid; /* owner of credentials */ 468 uid_t cred_uid; /* owner of credentials */
465 int capabilities; 469 int capabilities;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index b37399491fa3..723a3273c6bb 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -178,11 +178,11 @@ extern void cifs_dfs_release_automount_timer(void);
178void cifs_proc_init(void); 178void cifs_proc_init(void);
179void cifs_proc_clean(void); 179void cifs_proc_clean(void);
180 180
181extern int cifs_negotiate_protocol(unsigned int xid, 181extern int cifs_negotiate_protocol(const unsigned int xid,
182 struct cifs_ses *ses); 182 struct cifs_ses *ses);
183extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses, 183extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
184 struct nls_table *nls_info); 184 struct nls_table *nls_info);
185extern int CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses); 185extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses);
186 186
187extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses, 187extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
188 const char *tree, struct cifs_tcon *tcon, 188 const char *tree, struct cifs_tcon *tcon,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 92bbd8487ead..ae59d6e4e4f5 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -396,7 +396,7 @@ static inline void inc_rfc1001_len(void *pSMB, int count)
396} 396}
397 397
398int 398int
399CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses) 399CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
400{ 400{
401 NEGOTIATE_REQ *pSMB; 401 NEGOTIATE_REQ *pSMB;
402 NEGOTIATE_RSP *pSMBr; 402 NEGOTIATE_RSP *pSMBr;
@@ -480,7 +480,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
480 rc = -EOPNOTSUPP; 480 rc = -EOPNOTSUPP;
481 goto neg_err_exit; 481 goto neg_err_exit;
482 } 482 }
483 server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode); 483 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
484 server->maxReq = min_t(unsigned int, 484 server->maxReq = min_t(unsigned int,
485 le16_to_cpu(rsp->MaxMpxCount), 485 le16_to_cpu(rsp->MaxMpxCount),
486 cifs_max_pending); 486 cifs_max_pending);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 6d846e7624d0..03389f59390f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -407,7 +407,7 @@ cifs_echo_request(struct work_struct *work)
407 * done, which is indicated by maxBuf != 0. Also, no need to ping if 407 * done, which is indicated by maxBuf != 0. Also, no need to ping if
408 * we got a response recently 408 * we got a response recently
409 */ 409 */
410 if (server->maxBuf == 0 || 410 if (!server->ops->need_neg || server->ops->need_neg(server) ||
411 time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) 411 time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
412 goto requeue_echo; 412 goto requeue_echo;
413 413
@@ -2406,7 +2406,8 @@ static bool warned_on_ntlm; /* globals init to false automatically */
2406static struct cifs_ses * 2406static struct cifs_ses *
2407cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) 2407cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2408{ 2408{
2409 int rc = -ENOMEM, xid; 2409 int rc = -ENOMEM;
2410 unsigned int xid;
2410 struct cifs_ses *ses; 2411 struct cifs_ses *ses;
2411 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; 2412 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2412 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; 2413 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
@@ -3960,24 +3961,22 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
3960 kfree(cifs_sb); 3961 kfree(cifs_sb);
3961} 3962}
3962 3963
3963int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) 3964int
3965cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
3964{ 3966{
3965 int rc = 0; 3967 int rc = 0;
3966 struct TCP_Server_Info *server = ses->server; 3968 struct TCP_Server_Info *server = ses->server;
3967 3969
3970 if (!server->ops->need_neg || !server->ops->negotiate)
3971 return -ENOSYS;
3972
3968 /* only send once per connect */ 3973 /* only send once per connect */
3969 if (server->maxBuf != 0) 3974 if (!server->ops->need_neg(server))
3970 return 0; 3975 return 0;
3971 3976
3972 set_credits(server, 1); 3977 set_credits(server, 1);
3973 rc = CIFSSMBNegotiate(xid, ses); 3978
3974 if (rc == -EAGAIN) { 3979 rc = server->ops->negotiate(xid, ses);
3975 /* retry only once on 1st time connection */
3976 set_credits(server, 1);
3977 rc = CIFSSMBNegotiate(xid, ses);
3978 if (rc == -EAGAIN)
3979 rc = -EHOSTDOWN;
3980 }
3981 if (rc == 0) { 3980 if (rc == 0) {
3982 spin_lock(&GlobalMid_Lock); 3981 spin_lock(&GlobalMid_Lock);
3983 if (server->tcpStatus == CifsNeedNegotiate) 3982 if (server->tcpStatus == CifsNeedNegotiate)
@@ -3985,7 +3984,6 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
3985 else 3984 else
3986 rc = -EHOSTDOWN; 3985 rc = -EHOSTDOWN;
3987 spin_unlock(&GlobalMid_Lock); 3986 spin_unlock(&GlobalMid_Lock);
3988
3989 } 3987 }
3990 3988
3991 return rc; 3989 return rc;
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index b4219789049a..3ba3f3cd2397 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -898,7 +898,7 @@ ssetup_ntlmssp_authenticate:
898 if (action & GUEST_LOGIN) 898 if (action & GUEST_LOGIN)
899 cFYI(1, "Guest login"); /* BB mark SesInfo struct? */ 899 cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
900 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */ 900 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
901 cFYI(1, "UID = %d ", ses->Suid); 901 cFYI(1, "UID = %llu ", ses->Suid);
902 /* response can have either 3 or 4 word count - Samba sends 3 */ 902 /* response can have either 3 or 4 word count - Samba sends 3 */
903 /* and lanman response is 3 */ 903 /* and lanman response is 3 */
904 bytes_remaining = get_bcc(smb_buf); 904 bytes_remaining = get_bcc(smb_buf);
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index f4f839459e90..ea4fb8aaaafb 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -389,6 +389,27 @@ cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
389 return true; 389 return true;
390} 390}
391 391
392static bool
393cifs_need_neg(struct TCP_Server_Info *server)
394{
395 return server->maxBuf == 0;
396}
397
398static int
399cifs_negotiate(const unsigned int xid, struct cifs_ses *ses)
400{
401 int rc;
402 rc = CIFSSMBNegotiate(xid, ses);
403 if (rc == -EAGAIN) {
404 /* retry only once on 1st time connection */
405 set_credits(ses->server, 1);
406 rc = CIFSSMBNegotiate(xid, ses);
407 if (rc == -EAGAIN)
408 rc = -EHOSTDOWN;
409 }
410 return rc;
411}
412
392struct smb_version_operations smb1_operations = { 413struct smb_version_operations smb1_operations = {
393 .send_cancel = send_nt_cancel, 414 .send_cancel = send_nt_cancel,
394 .compare_fids = cifs_compare_fids, 415 .compare_fids = cifs_compare_fids,
@@ -407,6 +428,8 @@ struct smb_version_operations smb1_operations = {
407 .dump_detail = cifs_dump_detail, 428 .dump_detail = cifs_dump_detail,
408 .is_oplock_break = is_valid_oplock_break, 429 .is_oplock_break = is_valid_oplock_break,
409 .check_trans2 = cifs_check_trans2, 430 .check_trans2 = cifs_check_trans2,
431 .need_neg = cifs_need_neg,
432 .negotiate = cifs_negotiate,
410}; 433};
411 434
412struct smb_version_values smb1_values = { 435struct smb_version_values smb1_values = {