summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2012-05-25 10:43:58 +0400
committerSteve French <smfrench@gmail.com>2012-07-24 00:33:26 -0500
commit286170aa241819f39d9d1d5d9f2434cfb8519506 (patch)
treef7f4a8fd6eb653ac0f40cab9e8468462316fe41e /fs/cifs
parenta891f0f895f4a760fdb99636fab05e60597b8224 (diff)
downloadlinux-stable-286170aa241819f39d9d1d5d9f2434cfb8519506.tar.gz
linux-stable-286170aa241819f39d9d1d5d9f2434cfb8519506.tar.bz2
linux-stable-286170aa241819f39d9d1d5d9f2434cfb8519506.zip
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>
Diffstat (limited to 'fs/cifs')
-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 {
/* process transaction2 response */
bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
char *, int);
+ /* check if we need to negotiate */
+ bool (*need_neg)(struct TCP_Server_Info *);
+ /* negotiate to the server */
+ int (*negotiate)(const unsigned int, struct cifs_ses *);
};
struct smb_version_values {
@@ -324,7 +328,7 @@ struct TCP_Server_Info {
struct mutex srv_mutex;
struct task_struct *tsk;
char server_GUID[16];
- char sec_mode;
+ __u16 sec_mode;
bool session_estab; /* mark when very first sess is established */
u16 dialect; /* dialect index that server chose */
enum securityEnum secType;
@@ -459,7 +463,7 @@ struct cifs_ses {
char *serverOS; /* name of operating system underlying server */
char *serverNOS; /* name of network operating system of server */
char *serverDomain; /* security realm of server */
- int Suid; /* remote smb uid */
+ __u64 Suid; /* remote smb uid */
uid_t linux_uid; /* overriding owner of files on the mount */
uid_t cred_uid; /* owner of credentials */
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);
void cifs_proc_init(void);
void cifs_proc_clean(void);
-extern int cifs_negotiate_protocol(unsigned int xid,
- struct cifs_ses *ses);
+extern int cifs_negotiate_protocol(const unsigned int xid,
+ struct cifs_ses *ses);
extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
struct nls_table *nls_info);
-extern int CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses);
+extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses);
extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
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)
}
int
-CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
+CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
{
NEGOTIATE_REQ *pSMB;
NEGOTIATE_RSP *pSMBr;
@@ -480,7 +480,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
rc = -EOPNOTSUPP;
goto neg_err_exit;
}
- server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
+ server->sec_mode = le16_to_cpu(rsp->SecurityMode);
server->maxReq = min_t(unsigned int,
le16_to_cpu(rsp->MaxMpxCount),
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)
* done, which is indicated by maxBuf != 0. Also, no need to ping if
* we got a response recently
*/
- if (server->maxBuf == 0 ||
+ if (!server->ops->need_neg || server->ops->need_neg(server) ||
time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
goto requeue_echo;
@@ -2406,7 +2406,8 @@ static bool warned_on_ntlm; /* globals init to false automatically */
static struct cifs_ses *
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
{
- int rc = -ENOMEM, xid;
+ int rc = -ENOMEM;
+ unsigned int xid;
struct cifs_ses *ses;
struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
@@ -3960,24 +3961,22 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
kfree(cifs_sb);
}
-int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
+int
+cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
{
int rc = 0;
struct TCP_Server_Info *server = ses->server;
+ if (!server->ops->need_neg || !server->ops->negotiate)
+ return -ENOSYS;
+
/* only send once per connect */
- if (server->maxBuf != 0)
+ if (!server->ops->need_neg(server))
return 0;
set_credits(server, 1);
- rc = CIFSSMBNegotiate(xid, ses);
- if (rc == -EAGAIN) {
- /* retry only once on 1st time connection */
- set_credits(server, 1);
- rc = CIFSSMBNegotiate(xid, ses);
- if (rc == -EAGAIN)
- rc = -EHOSTDOWN;
- }
+
+ rc = server->ops->negotiate(xid, ses);
if (rc == 0) {
spin_lock(&GlobalMid_Lock);
if (server->tcpStatus == CifsNeedNegotiate)
@@ -3985,7 +3984,6 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
else
rc = -EHOSTDOWN;
spin_unlock(&GlobalMid_Lock);
-
}
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:
if (action & GUEST_LOGIN)
cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
- cFYI(1, "UID = %d ", ses->Suid);
+ cFYI(1, "UID = %llu ", ses->Suid);
/* response can have either 3 or 4 word count - Samba sends 3 */
/* and lanman response is 3 */
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,
return true;
}
+static bool
+cifs_need_neg(struct TCP_Server_Info *server)
+{
+ return server->maxBuf == 0;
+}
+
+static int
+cifs_negotiate(const unsigned int xid, struct cifs_ses *ses)
+{
+ int rc;
+ rc = CIFSSMBNegotiate(xid, ses);
+ if (rc == -EAGAIN) {
+ /* retry only once on 1st time connection */
+ set_credits(ses->server, 1);
+ rc = CIFSSMBNegotiate(xid, ses);
+ if (rc == -EAGAIN)
+ rc = -EHOSTDOWN;
+ }
+ return rc;
+}
+
struct smb_version_operations smb1_operations = {
.send_cancel = send_nt_cancel,
.compare_fids = cifs_compare_fids,
@@ -407,6 +428,8 @@ struct smb_version_operations smb1_operations = {
.dump_detail = cifs_dump_detail,
.is_oplock_break = is_valid_oplock_break,
.check_trans2 = cifs_check_trans2,
+ .need_neg = cifs_need_neg,
+ .negotiate = cifs_negotiate,
};
struct smb_version_values smb1_values = {