Skip to content

Commit

Permalink
CIFS: Add capability to send SMB2 negotiate message
Browse files Browse the repository at this point in the history
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: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
  • Loading branch information
Pavel Shilovsky authored and Pavel Shilovsky committed Jul 24, 2012
1 parent 3792c17 commit ec2e452
Show file tree
Hide file tree
Showing 8 changed files with 417 additions and 11 deletions.
3 changes: 2 additions & 1 deletion fs/cifs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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_SMB2) += smb2ops.o smb2maperror.o smb2transport.o smb2misc.o
cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o
13 changes: 12 additions & 1 deletion fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ get_rfc1002_length(void *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 list_head tcp_ses_list;
struct list_head smb_ses_list;
Expand Down Expand Up @@ -393,6 +399,10 @@ struct TCP_Server_Info {
atomic_t in_send; /* requests trying to send */
atomic_t num_waiters; /* blocked waiting to get in sendrecv */
#endif
#ifdef CONFIG_CIFS_SMB2
unsigned int max_read;
unsigned int max_write;
#endif /* CONFIG_CIFS_SMB2 */
};

static inline unsigned int
Expand Down Expand Up @@ -986,7 +996,8 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
/* Type of request operation */
#define CIFS_ECHO_OP 0x080 /* echo 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 */
#define CIFSSEC_MAY_SIGN 0x00001
Expand Down
7 changes: 0 additions & 7 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,13 +388,6 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
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
CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
{
Expand Down
7 changes: 6 additions & 1 deletion fs/cifs/smb2misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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)
{
*off = 0;
Expand All @@ -218,6 +218,11 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
*/
switch (hdr->Command) {
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_CREATE:
case SMB2_READ:
Expand Down
22 changes: 21 additions & 1 deletion fs/cifs/smb2ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 += add;
server->in_flight--;
if (server->in_flight == 0)
if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
rc = change_conf(server);
spin_unlock(&server->req_lock);
wake_up(&server->request_q);
Expand Down Expand Up @@ -139,6 +139,24 @@ smb2_dump_detail(void *buf)
#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 = {
.setup_request = smb2_setup_request,
.check_receive = smb2_check_receive,
Expand All @@ -150,6 +168,8 @@ struct smb_version_operations smb21_operations = {
.find_mid = smb2_find_mid,
.check_message = smb2_check_message,
.dump_detail = smb2_dump_detail,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
};

struct smb_version_values smb21_values = {
Expand Down
Loading

0 comments on commit ec2e452

Please sign in to comment.