Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec2e4523 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Pavel Shilovsky
Browse files

CIFS: Add capability to send SMB2 negotiate message



and add negotiate request type to let set_credits know that
we are only on negotiate stage and no need to make a decision
about disabling echos and oplocks.

Signed-off-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 3792c173
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -16,4 +16,5 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o


cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o


cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o smb2misc.o
cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \
			    smb2misc.o smb2pdu.o
+12 −1
Original line number Original line Diff line number Diff line
@@ -313,6 +313,12 @@ get_rfc1002_length(void *buf)
	return be32_to_cpu(*((__be32 *)buf));
	return be32_to_cpu(*((__be32 *)buf));
}
}


static inline void
inc_rfc1001_len(void *buf, int count)
{
	be32_add_cpu((__be32 *)buf, count);
}

struct TCP_Server_Info {
struct TCP_Server_Info {
	struct list_head tcp_ses_list;
	struct list_head tcp_ses_list;
	struct list_head smb_ses_list;
	struct list_head smb_ses_list;
@@ -393,6 +399,10 @@ struct TCP_Server_Info {
	atomic_t in_send; /* requests trying to send */
	atomic_t in_send; /* requests trying to send */
	atomic_t num_waiters;   /* blocked waiting to get in sendrecv */
	atomic_t num_waiters;   /* blocked waiting to get in sendrecv */
#endif
#endif
#ifdef CONFIG_CIFS_SMB2
	unsigned int	max_read;
	unsigned int	max_write;
#endif /* CONFIG_CIFS_SMB2 */
};
};


static inline unsigned int
static inline unsigned int
@@ -986,7 +996,8 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
/* Type of request operation */
/* Type of request operation */
#define   CIFS_ECHO_OP      0x080    /* echo request */
#define   CIFS_ECHO_OP      0x080    /* echo request */
#define   CIFS_OBREAK_OP   0x0100    /* oplock break request */
#define   CIFS_OBREAK_OP   0x0100    /* oplock break request */
#define   CIFS_OP_MASK     0x0180    /* mask request type */
#define   CIFS_NEG_OP      0x0200    /* negotiate request */
#define   CIFS_OP_MASK     0x0380    /* mask request type */


/* Security Flags: indicate type of session setup needed */
/* Security Flags: indicate type of session setup needed */
#define   CIFSSEC_MAY_SIGN	0x00001
#define   CIFSSEC_MAY_SIGN	0x00001
+0 −7
Original line number Original line Diff line number Diff line
@@ -388,13 +388,6 @@ vt2_err:
	return -EINVAL;
	return -EINVAL;
}
}


static inline void inc_rfc1001_len(void *pSMB, int count)
{
	struct smb_hdr *hdr = (struct smb_hdr *)pSMB;

	be32_add_cpu(&hdr->smb_buf_length, count);
}

int
int
CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
{
{
+6 −1
Original line number Original line Diff line number Diff line
@@ -199,7 +199,7 @@ static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
 * Returns the pointer to the beginning of the data area. Length of the data
 * Returns the pointer to the beginning of the data area. Length of the data
 * area and the offset to it (from the beginning of the smb are also returned.
 * area and the offset to it (from the beginning of the smb are also returned.
 */
 */
static char *
char *
smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
{
{
	*off = 0;
	*off = 0;
@@ -218,6 +218,11 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
	 */
	 */
	switch (hdr->Command) {
	switch (hdr->Command) {
	case SMB2_NEGOTIATE:
	case SMB2_NEGOTIATE:
		*off = le16_to_cpu(
		    ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferOffset);
		*len = le16_to_cpu(
		    ((struct smb2_negotiate_rsp *)hdr)->SecurityBufferLength);
		break;
	case SMB2_SESSION_SETUP:
	case SMB2_SESSION_SETUP:
	case SMB2_CREATE:
	case SMB2_CREATE:
	case SMB2_READ:
	case SMB2_READ:
+21 −1
Original line number Original line Diff line number Diff line
@@ -61,7 +61,7 @@ smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
	val = server->ops->get_credits_field(server, optype);
	val = server->ops->get_credits_field(server, optype);
	*val += add;
	*val += add;
	server->in_flight--;
	server->in_flight--;
	if (server->in_flight == 0)
	if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
		rc = change_conf(server);
		rc = change_conf(server);
	spin_unlock(&server->req_lock);
	spin_unlock(&server->req_lock);
	wake_up(&server->request_q);
	wake_up(&server->request_q);
@@ -139,6 +139,24 @@ smb2_dump_detail(void *buf)
#endif
#endif
}
}


static bool
smb2_need_neg(struct TCP_Server_Info *server)
{
	return server->max_read == 0;
}

static int
smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
{
	int rc;
	ses->server->CurrentMid = 0;
	rc = SMB2_negotiate(xid, ses);
	/* BB we probably don't need to retry with modern servers */
	if (rc == -EAGAIN)
		rc = -EHOSTDOWN;
	return rc;
}

struct smb_version_operations smb21_operations = {
struct smb_version_operations smb21_operations = {
	.setup_request = smb2_setup_request,
	.setup_request = smb2_setup_request,
	.check_receive = smb2_check_receive,
	.check_receive = smb2_check_receive,
@@ -150,6 +168,8 @@ struct smb_version_operations smb21_operations = {
	.find_mid = smb2_find_mid,
	.find_mid = smb2_find_mid,
	.check_message = smb2_check_message,
	.check_message = smb2_check_message,
	.dump_detail = smb2_dump_detail,
	.dump_detail = smb2_dump_detail,
	.need_neg = smb2_need_neg,
	.negotiate = smb2_negotiate,
};
};


struct smb_version_values smb21_values = {
struct smb_version_values smb21_values = {
Loading