[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fe428483-6564-4f18-bd1a-cc1150941da5@talpey.com>
Date: Mon, 24 Nov 2025 12:27:15 -0500
From: Tom Talpey <tom@...pey.com>
To: David Howells <dhowells@...hat.com>, Steve French <sfrench@...ba.org>
Cc: Paulo Alcantara <pc@...guebit.org>, Shyam Prasad N
<sprasad@...rosoft.com>, Stefan Metzmacher <metze@...ba.org>,
linux-cifs@...r.kernel.org, netfs@...ts.linux.dev,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr
On 11/24/2025 7:42 AM, David Howells wrote:
> Remove the RFC1002 header from struct smb_hdr as used for SMB-1.0. This
> simplifies the SMB-1.0 code by simplifying a lot of places that have to add
> or subtract 4 to work around the fact that the RFC1002 header isn't really
> part of the message and the base for various offsets within the message is
> from the base of the smb_hdr, not the RFC1002 header.
This is truly great, RFC1002 is a framing layer and separating it from
the upper SMB code is long overdue.
But... isn't this applicable to SMB2/3? The commit log implies it's SMB1
only (nit there's no such thing as "SMB-1.0"), which is weird given the
commit applies to many smb2<foo> files.
And, are similar changes envisioned in the ksmbd code?
Re the code, feel free to add:
Reviewed-by: Tom Talpey <tom@...pey.com>
Tom.
>
> Further, clean up a bunch of places that require an extra kvec struct
> specifically pointing to the RFC1002 header, such that kvec[0].iov_base
> must be exactly 4 bytes before kvec[1].iov_base.
>
> This allows the header preamble size stuff to be removed too.
>
> The size of the request and response message are then handed around either
> directly or by summing the size of all the iov_len members in the kvec
> array for which we have a count.
>
> Also, this simplifies and cleans up the common transmission and receive
> paths for SMB1 and SMB2/3 as there no longer needs to be special handling
> casing for SMB1 messages as the RFC1002 header is now generated on the fly
> for SMB1 as it is for SMB2/3.
>
> Signed-off-by: David Howells <dhowells@...hat.com>
> cc: Steve French <sfrench@...ba.org>
> cc: Paulo Alcantara <pc@...guebit.org>
> cc: Shyam Prasad N <sprasad@...rosoft.com>
> cc: Tom Talpey <tom@...pey.com>
> cc: linux-cifs@...r.kernel.org
> cc: netfs@...ts.linux.dev
> cc: linux-fsdevel@...r.kernel.org
> ---
> fs/smb/client/cifs_debug.c | 6 +-
> fs/smb/client/cifs_debug.h | 2 +-
> fs/smb/client/cifsencrypt.c | 36 +-
> fs/smb/client/cifsglob.h | 21 +-
> fs/smb/client/cifspdu.h | 2 +-
> fs/smb/client/cifsproto.h | 12 +-
> fs/smb/client/cifssmb.c | 695 +++++++++++++++++++---------------
> fs/smb/client/cifstransport.c | 128 +++----
> fs/smb/client/connect.c | 36 +-
> fs/smb/client/misc.c | 32 +-
> fs/smb/client/sess.c | 8 +-
> fs/smb/client/smb1ops.c | 21 +-
> fs/smb/client/smb1proto.h | 10 +-
> fs/smb/client/smb2misc.c | 3 +-
> fs/smb/client/smb2ops.c | 11 +-
> fs/smb/client/smb2proto.h | 3 +-
> fs/smb/client/transport.c | 22 +-
> fs/smb/common/smb2pdu.h | 3 -
> fs/smb/common/smbglob.h | 1 -
> 19 files changed, 538 insertions(+), 514 deletions(-)
>
> diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
> index 6d24d9cd6e09..ceca2ef0ff8d 100644
> --- a/fs/smb/client/cifs_debug.c
> +++ b/fs/smb/client/cifs_debug.c
> @@ -37,7 +37,7 @@ cifs_dump_mem(char *label, void *data, int length)
> data, length, true);
> }
>
> -void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
> +void cifs_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *server)
> {
> #ifdef CONFIG_CIFS_DEBUG2
> struct smb_hdr *smb = buf;
> @@ -45,7 +45,7 @@ void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
> cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d Wct: %d\n",
> smb->Command, smb->Status.CifsError, smb->Flags,
> smb->Flags2, smb->Mid, smb->Pid, smb->WordCount);
> - if (!server->ops->check_message(buf, server->total_read, server)) {
> + if (!server->ops->check_message(buf, buf_len, server->total_read, server)) {
> cifs_dbg(VFS, "smb buf %p len %u\n", smb,
> server->ops->calc_smb_size(smb));
> }
> @@ -79,7 +79,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
> cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n",
> smb->multiRsp, smb->multiEnd);
> if (smb->resp_buf) {
> - cifs_dump_detail(smb->resp_buf, server);
> + cifs_dump_detail(smb->resp_buf, smb->response_pdu_len, server);
> cifs_dump_mem("existing buf: ", smb->resp_buf, 62);
> }
> }
> diff --git a/fs/smb/client/cifs_debug.h b/fs/smb/client/cifs_debug.h
> index fd264c39cfbf..3f69d3a4dca4 100644
> --- a/fs/smb/client/cifs_debug.h
> +++ b/fs/smb/client/cifs_debug.h
> @@ -19,7 +19,7 @@
> * cifs_debug.c
> */
> void cifs_dump_mem(char *label, void *data, int length);
> -void cifs_dump_detail(void *buf, struct TCP_Server_Info *server);
> +void cifs_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *server);
> void cifs_dump_mids(struct TCP_Server_Info *server);
> void cifs_proc_init(void);
> void cifs_proc_clean(void);
> diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
> index 801824825ecf..1e0ac87c6686 100644
> --- a/fs/smb/client/cifsencrypt.c
> +++ b/fs/smb/client/cifsencrypt.c
> @@ -91,18 +91,7 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
> struct kvec *iov = rqst->rq_iov;
> int n_vec = rqst->rq_nvec;
>
> - /* iov[0] is actual data and not the rfc1002 length for SMB2+ */
> - if (!is_smb1(server)) {
> - if (iov[0].iov_len <= 4)
> - return -EIO;
> - i = 0;
> - } else {
> - if (n_vec < 2 || iov[0].iov_len != 4)
> - return -EIO;
> - i = 1; /* skip rfc1002 length */
> - }
> -
> - for (; i < n_vec; i++) {
> + for (i = 0; i < n_vec; i++) {
> if (iov[i].iov_len == 0)
> continue;
> if (iov[i].iov_base == NULL) {
> @@ -165,10 +154,6 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
> char smb_signature[20];
> struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
>
> - if (rqst->rq_iov[0].iov_len != 4 ||
> - rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
> - return -EIO;
> -
> if ((cifs_pdu == NULL) || (server == NULL))
> return -EINVAL;
>
> @@ -211,17 +196,16 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
> }
>
> /* must be called with server->srv_mutex held */
> -int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
> +int cifs_sign_smb(struct smb_hdr *cifs_pdu, unsigned int pdu_len,
> + struct TCP_Server_Info *server,
> __u32 *pexpected_response_sequence_number)
> {
> - struct kvec iov[2];
> + struct kvec iov[1] = {
> + [0].iov_base = (char *)cifs_pdu,
> + [0].iov_len = pdu_len,
> + };
>
> - iov[0].iov_base = cifs_pdu;
> - iov[0].iov_len = 4;
> - iov[1].iov_base = (char *)cifs_pdu + 4;
> - iov[1].iov_len = be32_to_cpu(cifs_pdu->smb_buf_length);
> -
> - return cifs_sign_smbv(iov, 2, server,
> + return cifs_sign_smbv(iov, ARRAY_SIZE(iov), server,
> pexpected_response_sequence_number);
> }
>
> @@ -234,10 +218,6 @@ int cifs_verify_signature(struct smb_rqst *rqst,
> char what_we_think_sig_should_be[20];
> struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
>
> - if (rqst->rq_iov[0].iov_len != 4 ||
> - rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
> - return -EIO;
> -
> if (cifs_pdu == NULL || server == NULL)
> return -EINVAL;
>
> diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
> index a4f396115e92..1e9770910e2b 100644
> --- a/fs/smb/client/cifsglob.h
> +++ b/fs/smb/client/cifsglob.h
> @@ -347,12 +347,13 @@ struct smb_version_operations {
> int (*map_error)(char *, bool);
> /* find mid corresponding to the response message */
> struct smb_message * (*find_mid)(struct TCP_Server_Info *server, char *buf);
> - void (*dump_detail)(void *buf, struct TCP_Server_Info *ptcp_info);
> + void (*dump_detail)(void *buf, size_t buf_len, struct TCP_Server_Info *ptcp_info);
> void (*clear_stats)(struct cifs_tcon *);
> void (*print_stats)(struct seq_file *m, struct cifs_tcon *);
> void (*dump_share_caps)(struct seq_file *, struct cifs_tcon *);
> /* verify the message */
> - int (*check_message)(char *, unsigned int, struct TCP_Server_Info *);
> + int (*check_message)(char *buf, unsigned int pdu_len, unsigned int len,
> + struct TCP_Server_Info *server);
> bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
> int (*handle_cancelled_mid)(struct smb_message *smb, struct TCP_Server_Info *server);
> void (*downgrade_oplock)(struct TCP_Server_Info *server,
> @@ -636,8 +637,7 @@ struct smb_version_operations {
>
> #define HEADER_SIZE(server) (server->vals->header_size)
> #define MAX_HEADER_SIZE(server) (server->vals->max_header_size)
> -#define HEADER_PREAMBLE_SIZE(server) (server->vals->header_preamble_size)
> -#define MID_HEADER_SIZE(server) (HEADER_SIZE(server) - 1 - HEADER_PREAMBLE_SIZE(server))
> +#define MID_HEADER_SIZE(server) (HEADER_SIZE(server) - 1)
>
> /**
> * CIFS superblock mount flags (mnt_cifs_flags) to consider when
> @@ -832,9 +832,9 @@ struct TCP_Server_Info {
> char dns_dom[CIFS_MAX_DOMAINNAME_LEN + 1];
> };
>
> -static inline bool is_smb1(struct TCP_Server_Info *server)
> +static inline bool is_smb1(const struct TCP_Server_Info *server)
> {
> - return HEADER_PREAMBLE_SIZE(server) != 0;
> + return server->vals->protocol_id == SMB10_PROT_ID;
> }
>
> static inline void cifs_server_lock(struct TCP_Server_Info *server)
> @@ -973,16 +973,16 @@ compare_mid(__u16 mid, const struct smb_hdr *smb)
> * of kvecs to handle the receive, though that should only need to be done
> * once.
> */
> -#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4)
> -#define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP) + 4)
> +#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ))
> +#define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP))
>
> /*
> * When the server doesn't allow large posix writes, only allow a rsize/wsize
> * of 2^17-1 minus the size of the call header. That allows for a read or
> * write up to the maximum size described by RFC1002.
> */
> -#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
> -#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
> +#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ))
> +#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP))
>
> /*
> * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
> @@ -1684,6 +1684,7 @@ struct smb_message {
> struct task_struct *creator;
> void *resp_buf; /* pointer to received SMB header */
> unsigned int resp_buf_size;
> + u32 response_pdu_len;
> int mid_state; /* wish this were enum but can not pass to wait_event */
> int mid_rc; /* rc for MID_RC */
> __le16 command; /* smb command code */
> diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
> index 19a463d55fbf..fccb0c20732b 100644
> --- a/fs/smb/client/cifspdu.h
> +++ b/fs/smb/client/cifspdu.h
> @@ -90,7 +90,7 @@
>
> /* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */
> /* among the requests (NTCreateX response is bigger with wct of 34) */
> -#define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */
> +#define MAX_CIFS_HDR_SIZE 0x54 /* 32 hdr + (2*24 wct) + 2 bct + 2 pad */
> #define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */
>
> /* internal cifs vfs structures */
> diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
> index 8d95efbad712..4af6ea8150c3 100644
> --- a/fs/smb/client/cifsproto.h
> +++ b/fs/smb/client/cifsproto.h
> @@ -70,7 +70,8 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
> __u32 *pexpected_response_sequence_number);
> int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
> __u32 *pexpected_response_sequence);
> -int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
> +int cifs_sign_smb(struct smb_hdr *cifs_pdu, unsigned int pdu_len,
> + struct TCP_Server_Info *server,
> __u32 *pexpected_response_sequence_number);
> int cifs_verify_signature(struct smb_rqst *rqst,
> struct TCP_Server_Info *server,
> @@ -374,10 +375,11 @@ void cifs_buf_release(void *buf_to_free);
> struct smb_hdr *cifs_small_buf_get(void);
> void cifs_small_buf_release(void *buf_to_free);
> void free_rsp_buf(int resp_buftype, void *rsp);
> -void header_assemble(struct smb_hdr *buffer, char smb_command,
> - const struct cifs_tcon *treeCon, int word_count
> - /* length of fixed section word count in two byte units */);
> -int checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server);
> +unsigned int header_assemble(struct smb_hdr *buffer, char smb_command,
> + const struct cifs_tcon *treeCon, int word_count
> + /* length of fixed section word count in two byte units */);
> +int checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
> + struct TCP_Server_Info *server);
> bool is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv);
> void dump_smb(void *buf, int smb_buf_length);
> void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
> diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
> index 884eb53618e6..65e517aaa40f 100644
> --- a/fs/smb/client/cifssmb.c
> +++ b/fs/smb/client/cifssmb.c
> @@ -227,6 +227,7 @@ static int
> small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
> void **request_buf)
> {
> + unsigned int in_len;
> int rc;
>
> rc = cifs_reconnect_tcon(tcon, smb_command);
> @@ -239,13 +240,13 @@ small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
> return -ENOMEM;
> }
>
> - header_assemble((struct smb_hdr *) *request_buf, smb_command,
> - tcon, wct);
> + in_len = header_assemble((struct smb_hdr *) *request_buf, smb_command,
> + tcon, wct);
>
> if (tcon != NULL)
> cifs_stats_inc(&tcon->num_smbs_sent);
>
> - return 0;
> + return in_len;
> }
>
> int
> @@ -256,7 +257,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
> struct smb_hdr *buffer;
>
> rc = small_smb_init(smb_command, wct, NULL, request_buf);
> - if (rc)
> + if (rc < 0)
> return rc;
>
> buffer = (struct smb_hdr *)*request_buf;
> @@ -279,6 +280,8 @@ static int
> __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
> void **request_buf, void **response_buf)
> {
> + unsigned int in_len;
> +
> *request_buf = cifs_buf_get();
> if (*request_buf == NULL) {
> /* BB should we add a retry in here if not a writepage? */
> @@ -291,13 +294,13 @@ __smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
> if (response_buf)
> *response_buf = *request_buf;
>
> - header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
> - wct);
> + in_len = header_assemble((struct smb_hdr *)*request_buf, smb_command, tcon,
> + wct);
>
> if (tcon != NULL)
> cifs_stats_inc(&tcon->num_smbs_sent);
>
> - return 0;
> + return in_len;
> }
>
> /* If the return code is zero, this function must fill in request_buf pointer */
> @@ -422,6 +425,7 @@ CIFSSMBNegotiate(const unsigned int xid,
> {
> SMB_NEGOTIATE_REQ *pSMB;
> SMB_NEGOTIATE_RSP *pSMBr;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int i;
> @@ -434,8 +438,9 @@ CIFSSMBNegotiate(const unsigned int xid,
>
> rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
> (void **) &pSMB, (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Mid = get_next_mid(server);
> pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
> @@ -459,10 +464,10 @@ CIFSSMBNegotiate(const unsigned int xid,
> memcpy(&pSMB->DialectsArray[count], protocols[i].name, len);
> count += len;
> }
> - inc_rfc1001_len(pSMB, count);
> + in_len += count;
> pSMB->ByteCount = cpu_to_le16(count);
>
> - rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc != 0)
> goto neg_err_exit;
> @@ -531,6 +536,7 @@ int
> CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
> {
> struct smb_hdr *smb_buffer;
> + unsigned int in_len;
> int rc = 0;
>
> cifs_dbg(FYI, "In tree disconnect\n");
> @@ -554,10 +560,11 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
>
> rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
> (void **)&smb_buffer);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, in_len, 0);
> cifs_small_buf_release(smb_buffer);
> if (rc)
> cifs_dbg(FYI, "Tree disconnect failed %d\n", rc);
> @@ -592,15 +599,19 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
> {
> ECHO_REQ *smb;
> int rc = 0;
> - struct kvec iov[2];
> - struct smb_rqst rqst = { .rq_iov = iov,
> - .rq_nvec = 2 };
> + struct kvec iov[1];
> + struct smb_rqst rqst = {
> + .rq_iov = iov,
> + .rq_nvec = ARRAY_SIZE(iov),
> + };
> + unsigned int in_len;
>
> cifs_dbg(FYI, "In echo request\n");
>
> rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (server->capabilities & CAP_UNICODE)
> smb->hdr.Flags2 |= SMBFLG2_UNICODE;
> @@ -611,12 +622,10 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
> put_unaligned_le16(1, &smb->EchoCount);
> put_bcc(1, &smb->hdr);
> smb->Data[0] = 'a';
> - inc_rfc1001_len(smb, 3);
> + in_len += 3;
>
> - iov[0].iov_len = 4;
> + iov[0].iov_len = in_len;
> iov[0].iov_base = smb;
> - iov[1].iov_len = get_rfc1002_len(smb);
> - iov[1].iov_base = (char *)smb + 4;
>
> rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL,
> server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL);
> @@ -632,6 +641,7 @@ int
> CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
> {
> LOGOFF_ANDX_REQ *pSMB;
> + unsigned int in_len;
> int rc = 0;
>
> cifs_dbg(FYI, "In SMBLogoff for session disconnect\n");
> @@ -654,10 +664,11 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
> spin_unlock(&ses->chan_lock);
>
> rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
> - if (rc) {
> + if (rc < 0) {
> mutex_unlock(&ses->session_mutex);
> return rc;
> }
> + in_len = rc;
>
> pSMB->hdr.Mid = get_next_mid(ses->server);
>
> @@ -667,7 +678,7 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
> pSMB->hdr.Uid = ses->Suid;
>
> pSMB->AndXCommand = 0xFF;
> - rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> session_already_dead:
> mutex_unlock(&ses->session_mutex);
> @@ -688,6 +699,7 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_SPI_REQ *pSMB = NULL;
> TRANSACTION2_SPI_RSP *pSMBr = NULL;
> struct unlink_psx_rq *pRqD;
> + unsigned int in_len;
> int name_len;
> int rc = 0;
> int bytes_returned = 0;
> @@ -697,8 +709,9 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
> PsxDelete:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -719,14 +732,11 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
>
> - /* Setup pointer to Request Data (inode type).
> - * Note that SMB offsets are from the beginning of SMB which is 4 bytes
> - * in, after RFC1001 field
> - */
> - pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4);
> + /* Setup pointer to Request Data (inode type). */
> + pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset);
> pRqD->type = cpu_to_le16(type);
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
> pSMB->DataOffset = cpu_to_le16(offset);
> @@ -741,9 +751,9 @@ CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "Posix delete returned %d\n", rc);
> @@ -763,6 +773,7 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> {
> DELETE_FILE_REQ *pSMB = NULL;
> DELETE_FILE_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -771,8 +782,9 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> DelFileRetry:
> rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name,
> @@ -786,9 +798,9 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> pSMB->SearchAttributes =
> cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
> pSMB->BufferFormat = 0x04;
> - inc_rfc1001_len(pSMB, name_len + 1);
> + in_len += name_len + 1;
> pSMB->ByteCount = cpu_to_le16(name_len + 1);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
> if (rc)
> @@ -807,6 +819,7 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> {
> DELETE_DIRECTORY_REQ *pSMB = NULL;
> DELETE_DIRECTORY_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -816,8 +829,9 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> RmDirRetry:
> rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
> @@ -830,9 +844,9 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
> }
>
> pSMB->BufferFormat = 0x04;
> - inc_rfc1001_len(pSMB, name_len + 1);
> + in_len += name_len + 1;
> pSMB->ByteCount = cpu_to_le16(name_len + 1);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
> if (rc)
> @@ -852,6 +866,7 @@ CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
> int rc = 0;
> CREATE_DIRECTORY_REQ *pSMB = NULL;
> CREATE_DIRECTORY_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int bytes_returned;
> int name_len;
> int remap = cifs_remap(cifs_sb);
> @@ -860,8 +875,9 @@ CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
> MkDirRetry:
> rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
> @@ -874,9 +890,9 @@ CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
> }
>
> pSMB->BufferFormat = 0x04;
> - inc_rfc1001_len(pSMB, name_len + 1);
> + in_len += name_len + 1;
> pSMB->ByteCount = cpu_to_le16(name_len + 1);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
> if (rc)
> @@ -897,6 +913,7 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
> {
> TRANSACTION2_SPI_REQ *pSMB = NULL;
> TRANSACTION2_SPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int name_len;
> int rc = 0;
> int bytes_returned = 0;
> @@ -908,8 +925,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
> PsxCreat:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -931,10 +949,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4);
> + pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset);
> pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
> pdata->Permissions = cpu_to_le64(mode);
> pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
> @@ -952,9 +969,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Posix create returned %d\n", rc);
> @@ -970,8 +987,8 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
> }
>
> /* copy return information to pRetData */
> - psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
> - + le16_to_cpu(pSMBr->t2.DataOffset));
> + psx_rsp = (OPEN_PSX_RSP *)
> + ((char *)pSMBr + le16_to_cpu(pSMBr->t2.DataOffset));
>
> *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
> if (netfid)
> @@ -991,9 +1008,9 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
> pRetData->Type = cpu_to_le32(-1);
> goto psx_create_err;
> }
> - memcpy((char *) pRetData,
> - (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
> - sizeof(FILE_UNIX_BASIC_INFO));
> + memcpy(pRetData,
> + (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
> + sizeof(*pRetData));
> }
>
> psx_create_err:
> @@ -1080,6 +1097,7 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
> int rc;
> OPENX_REQ *pSMB = NULL;
> OPENX_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int bytes_returned;
> int name_len;
> __u16 count;
> @@ -1087,8 +1105,9 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
> OldOpenRetry:
> rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->AndXCommand = 0xFF; /* none */
>
> @@ -1131,10 +1150,10 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
> pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
> count += name_len;
> - inc_rfc1001_len(pSMB, count);
> + in_len += count;
>
> pSMB->ByteCount = cpu_to_le16(count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *)pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
> if (rc) {
> @@ -1192,12 +1211,14 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
> int desired_access = oparms->desired_access;
> int disposition = oparms->disposition;
> const char *path = oparms->path;
> + unsigned int in_len;
>
> openRetry:
> rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req,
> (void **)&rsp);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> /* no commands go after this */
> req->AndXCommand = 0xFF;
> @@ -1255,10 +1276,10 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
> req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY;
>
> count += name_len;
> - inc_rfc1001_len(req, count);
> + in_len += count;
>
> req->ByteCount = cpu_to_le16(count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req, in_len,
> (struct smb_hdr *)rsp, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
> if (rc) {
> @@ -1304,7 +1325,7 @@ cifs_readv_callback(struct smb_message *smb)
> struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
> struct TCP_Server_Info *server = tcon->ses->server;
> struct smb_rqst rqst = { .rq_iov = rdata->iov,
> - .rq_nvec = 2,
> + .rq_nvec = 1,
> .rq_iter = rdata->subreq.io_iter };
> struct cifs_credits credits = {
> .value = 1,
> @@ -1416,7 +1437,8 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
> int wct;
> struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
> struct smb_rqst rqst = { .rq_iov = rdata->iov,
> - .rq_nvec = 2 };
> + .rq_nvec = 1 };
> + unsigned int in_len;
>
> cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
> __func__, rdata->subreq.start, rdata->subreq.len);
> @@ -1432,8 +1454,9 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
> }
>
> rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid);
> smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16));
> @@ -1457,9 +1480,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
>
> /* 4 for RFC1001 length + 1 for BCC */
> rdata->iov[0].iov_base = smb;
> - rdata->iov[0].iov_len = 4;
> - rdata->iov[1].iov_base = (char *)smb + 4;
> - rdata->iov[1].iov_len = get_rfc1002_len(smb);
> + rdata->iov[0].iov_len = in_len;
>
> trace_smb3_read_enter(rdata->rreq->debug_id,
> rdata->subreq.debug_index,
> @@ -1493,6 +1514,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
> __u16 netfid = io_parms->netfid;
> __u64 offset = io_parms->offset;
> struct cifs_tcon *tcon = io_parms->tcon;
> + unsigned int in_len;
> unsigned int count = io_parms->length;
>
> cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid);
> @@ -1508,8 +1530,9 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
>
> *nbytes = 0;
> rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
> @@ -1537,7 +1560,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
> }
>
> iov[0].iov_base = (char *)pSMB;
> - iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
> + iov[0].iov_len = in_len;
> rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type,
> CIFS_LOG_ERROR, &rsp_iov);
> cifs_small_buf_release(pSMB);
> @@ -1601,7 +1624,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
> __u16 netfid = io_parms->netfid;
> __u64 offset = io_parms->offset;
> struct cifs_tcon *tcon = io_parms->tcon;
> - unsigned int count = io_parms->length;
> + unsigned int count = io_parms->length, in_len;
>
> *nbytes = 0;
>
> @@ -1621,8 +1644,9 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
>
> rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
> @@ -1655,7 +1679,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
> if (bytes_sent > count)
> bytes_sent = count;
> pSMB->DataOffset =
> - cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
> + cpu_to_le16(offsetof(struct smb_com_write_req, Data));
> if (buf)
> memcpy(pSMB->Data, buf, bytes_sent);
> else if (count != 0) {
> @@ -1670,7 +1694,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
>
> pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
> pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
>
> if (wct == 14)
> pSMB->ByteCount = cpu_to_le16(byte_count);
> @@ -1681,7 +1705,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
> pSMBW->ByteCount = cpu_to_le16(byte_count);
> }
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
> if (rc) {
> @@ -1795,8 +1819,9 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
> WRITE_REQ *req = NULL;
> int wct;
> struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
> - struct kvec iov[2];
> + struct kvec iov[1];
> struct smb_rqst rqst = { };
> + unsigned int in_len;
>
> if (tcon->ses->capabilities & CAP_LARGE_FILES) {
> wct = 14;
> @@ -1810,8 +1835,9 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
> }
>
> rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&req);
> - if (rc)
> + if (rc < 0)
> goto async_writev_out;
> + in_len = rc;
>
> req->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid);
> req->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16));
> @@ -1826,16 +1852,13 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
> req->Remaining = 0;
>
> req->DataOffset =
> - cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
> + cpu_to_le16(offsetof(struct smb_com_write_req, Data));
>
> - /* 4 for RFC1001 length + 1 for BCC */
> - iov[0].iov_len = 4;
> iov[0].iov_base = req;
> - iov[1].iov_len = get_rfc1002_len(req) + 1;
> - iov[1].iov_base = (char *)req + 4;
> + iov[0].iov_len = in_len + 1; /* +1 for BCC */
>
> rqst.rq_iov = iov;
> - rqst.rq_nvec = 2;
> + rqst.rq_nvec = 1;
> rqst.rq_iter = wdata->subreq.io_iter;
>
> cifs_dbg(FYI, "async write at %llu %zu bytes\n",
> @@ -1845,15 +1868,15 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
> req->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
>
> if (wct == 14) {
> - inc_rfc1001_len(&req->hdr, wdata->subreq.len + 1);
> + in_len += wdata->subreq.len + 1;
> put_bcc(wdata->subreq.len + 1, &req->hdr);
> } else {
> /* wct == 12 */
> struct smb_com_writex_req *reqw =
> (struct smb_com_writex_req *)req;
> - inc_rfc1001_len(&reqw->hdr, wdata->subreq.len + 5);
> + in_len += wdata->subreq.len + 5;
> put_bcc(wdata->subreq.len + 5, &reqw->hdr);
> - iov[1].iov_len += 4; /* pad bigger by four bytes */
> + iov[0].iov_len += 4; /* pad bigger by four bytes */
> }
>
> rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
> @@ -1886,6 +1909,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
> struct cifs_tcon *tcon = io_parms->tcon;
> unsigned int count = io_parms->length;
> struct kvec rsp_iov;
> + unsigned int in_len;
>
> *nbytes = 0;
>
> @@ -1901,8 +1925,9 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
> }
> }
> rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
> @@ -1921,16 +1946,16 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
> pSMB->Remaining = 0;
>
> pSMB->DataOffset =
> - cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
> + cpu_to_le16(offsetof(struct smb_com_write_req, Data));
>
> pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
> pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
> /* header + 1 byte pad */
> - smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
> + smb_hdr_len = in_len + 1;
> if (wct == 14)
> - inc_rfc1001_len(pSMB, count + 1);
> + in_len += count + 1;
> else /* wct == 12 */
> - inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
> + in_len += count + 5; /* smb data starts later */
> if (wct == 14)
> pSMB->ByteCount = cpu_to_le16(count + 1);
> else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
> @@ -1984,6 +2009,7 @@ int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
> LOCK_REQ *pSMB = NULL;
> struct kvec iov[2];
> struct kvec rsp_iov;
> + unsigned int in_len;
> int resp_buf_type;
> __u16 count;
>
> @@ -1991,8 +2017,9 @@ int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
> num_lock, num_unlock);
>
> rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->Timeout = 0;
> pSMB->NumberOfLocks = cpu_to_le16(num_lock);
> @@ -2002,11 +2029,11 @@ int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Fid = netfid; /* netfid stays le */
>
> count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
> - inc_rfc1001_len(pSMB, count);
> + in_len += count;
> pSMB->ByteCount = cpu_to_le16(count);
>
> iov[0].iov_base = (char *)pSMB;
> - iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
> + iov[0].iov_len = in_len -
> (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
> iov[1].iov_base = (char *)buf;
> iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
> @@ -2031,6 +2058,7 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
> int rc = 0;
> LOCK_REQ *pSMB = NULL;
> /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
> + unsigned int in_len;
> int bytes_returned;
> int flags = 0;
> __u16 count;
> @@ -2039,8 +2067,9 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
> (int)waitFlag, numLock);
> rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
>
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
> /* no response expected */
> @@ -2072,14 +2101,14 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
> /* oplock break */
> count = 0;
> }
> - inc_rfc1001_len(pSMB, count);
> + in_len += count;
> pSMB->ByteCount = cpu_to_le16(count);
>
> if (waitFlag)
> - rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
> + rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMB, &bytes_returned);
> else
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, in_len, flags);
> cifs_small_buf_release(pSMB);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
> if (rc)
> @@ -2100,6 +2129,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
> struct smb_com_transaction2_sfi_req *pSMB = NULL;
> struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
> struct cifs_posix_lock *parm_data;
> + unsigned int in_len;
> int rc = 0;
> int timeout = 0;
> int bytes_returned = 0;
> @@ -2111,9 +2141,9 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
> cifs_dbg(FYI, "Posix Lock\n");
>
> rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
> -
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
>
> @@ -2122,7 +2152,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Reserved = 0;
> pSMB->Flags = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
> offset = param_offset + params;
>
> count = sizeof(struct cifs_posix_lock);
> @@ -2140,9 +2170,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalDataCount = pSMB->DataCount;
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - parm_data = (struct cifs_posix_lock *)
> - (((char *)pSMB) + offset + 4);
> + parm_data = (struct cifs_posix_lock *)(((char *)pSMB) + offset);
>
> parm_data->lock_type = cpu_to_le16(lock_type);
> if (waitFlag) {
> @@ -2160,14 +2188,14 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Fid = smb_file_id;
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> if (waitFlag) {
> - rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
> + rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned);
> } else {
> iov[0].iov_base = (char *)pSMB;
> - iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
> + iov[0].iov_len = in_len;
> rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
> &resp_buf_type, timeout, &rsp_iov);
> pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
> @@ -2227,19 +2255,22 @@ CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
> {
> int rc = 0;
> CLOSE_REQ *pSMB = NULL;
> + unsigned int in_len;
> +
> cifs_dbg(FYI, "In CIFSSMBClose\n");
>
> /* do not retry on dead session on close */
> rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
> if (rc == -EAGAIN)
> return 0;
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->FileID = (__u16) smb_file_id;
> pSMB->LastWriteTime = 0xFFFFFFFF;
> pSMB->ByteCount = 0;
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
> if (rc) {
> @@ -2261,15 +2292,18 @@ CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id)
> {
> int rc = 0;
> FLUSH_REQ *pSMB = NULL;
> + unsigned int in_len;
> +
> cifs_dbg(FYI, "In CIFSSMBFlush\n");
>
> rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->FileID = (__u16) smb_file_id;
> pSMB->ByteCount = 0;
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
> if (rc)
> @@ -2286,6 +2320,7 @@ int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
> int rc = 0;
> RENAME_REQ *pSMB = NULL;
> RENAME_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int bytes_returned;
> int name_len, name_len2;
> __u16 count;
> @@ -2295,8 +2330,9 @@ int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
> renameRetry:
> rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->BufferFormat = 0x04;
> pSMB->SearchAttributes =
> @@ -2326,10 +2362,10 @@ int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
> }
>
> count = 1 /* 1st signature byte */ + name_len + name_len2;
> - inc_rfc1001_len(pSMB, count);
> + in_len += count;
> pSMB->ByteCount = cpu_to_le16(count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
> if (rc)
> @@ -2350,6 +2386,7 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
> struct smb_com_transaction2_sfi_req *pSMB = NULL;
> struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
> struct set_file_rename *rename_info;
> + unsigned int in_len;
> char *data_offset;
> char dummy_string[30];
> int rc = 0;
> @@ -2360,8 +2397,9 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
> cifs_dbg(FYI, "Rename to File by handle\n");
> rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 6;
> pSMB->MaxSetupCount = 0;
> @@ -2369,11 +2407,10 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
> pSMB->Flags = 0;
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
> offset = param_offset + params;
>
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - data_offset = (char *)(pSMB) + offset + 4;
> + data_offset = (char *)(pSMB) + offset;
> rename_info = (struct set_file_rename *) data_offset;
> pSMB->MaxParameterCount = cpu_to_le16(2);
> pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
> @@ -2409,9 +2446,9 @@ int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
> pSMB->InformationLevel =
> cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
> if (rc)
> @@ -2433,6 +2470,7 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
> {
> TRANSACTION2_SPI_REQ *pSMB = NULL;
> TRANSACTION2_SPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> char *data_offset;
> int name_len;
> int name_len_target;
> @@ -2444,8 +2482,9 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
> createSymLinkRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -2465,11 +2504,10 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
>
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - data_offset = (char *)pSMB + offset + 4;
> + data_offset = (char *)pSMB + offset;
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len_target =
> cifsConvertToUTF16((__le16 *) data_offset, toName,
> @@ -2496,9 +2534,9 @@ CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->DataOffset = cpu_to_le16(offset);
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
> if (rc)
> @@ -2520,6 +2558,7 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
> {
> TRANSACTION2_SPI_REQ *pSMB = NULL;
> TRANSACTION2_SPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> char *data_offset;
> int name_len;
> int name_len_target;
> @@ -2531,8 +2570,9 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
> createHardLinkRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
> @@ -2550,11 +2590,10 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
>
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - data_offset = (char *)pSMB + offset + 4;
> + data_offset = (char *)pSMB + offset;
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len_target =
> cifsConvertToUTF16((__le16 *) data_offset, fromName,
> @@ -2580,9 +2619,9 @@ CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->DataOffset = cpu_to_le16(offset);
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
> if (rc)
> @@ -2605,6 +2644,7 @@ int CIFSCreateHardLink(const unsigned int xid,
> int rc = 0;
> NT_RENAME_REQ *pSMB = NULL;
> RENAME_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int bytes_returned;
> int name_len, name_len2;
> __u16 count;
> @@ -2615,8 +2655,9 @@ int CIFSCreateHardLink(const unsigned int xid,
>
> rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->SearchAttributes =
> cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
> @@ -2650,10 +2691,10 @@ int CIFSCreateHardLink(const unsigned int xid,
> }
>
> count = 1 /* string type byte */ + name_len + name_len2;
> - inc_rfc1001_len(pSMB, count);
> + in_len += count;
> pSMB->ByteCount = cpu_to_le16(count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
> if (rc)
> @@ -2674,6 +2715,7 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
> /* SMB_QUERY_FILE_UNIX_LINK */
> TRANSACTION2_QPI_REQ *pSMB = NULL;
> TRANSACTION2_QPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -2685,8 +2727,9 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
> querySymLinkRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -2709,7 +2752,7 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qpi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -2720,10 +2763,10 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc);
> @@ -2771,6 +2814,7 @@ int cifs_query_reparse_point(const unsigned int xid,
> TRANSACT_IOCTL_REQ *io_req = NULL;
> TRANSACT_IOCTL_RSP *io_rsp = NULL;
> struct cifs_fid fid;
> + unsigned int in_len;
> __u32 data_offset, data_count, len;
> __u8 *start, *end;
> int io_rsp_len;
> @@ -2802,8 +2846,9 @@ int cifs_query_reparse_point(const unsigned int xid,
>
> rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon,
> (void **)&io_req, (void **)&io_rsp);
> - if (rc)
> + if (rc < 0)
> goto error;
> + in_len = rc;
>
> io_req->TotalParameterCount = 0;
> io_req->TotalDataCount = 0;
> @@ -2824,7 +2869,7 @@ int cifs_query_reparse_point(const unsigned int xid,
> io_req->Fid = fid.netfid;
> io_req->ByteCount = 0;
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, in_len,
> (struct smb_hdr *)io_rsp, &io_rsp_len, 0);
> if (rc)
> goto error;
> @@ -2898,7 +2943,7 @@ struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> struct kvec in_iov[2];
> struct kvec out_iov;
> struct cifs_fid fid;
> - int io_req_len;
> + unsigned int in_len;
> int oplock = 0;
> int buf_type = 0;
> int rc;
> @@ -2954,12 +2999,10 @@ struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> #endif
>
> rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL);
> - if (rc)
> + if (rc < 0)
> goto out_close;
> -
> - inc_rfc1001_len(io_req, sizeof(io_req->Pad));
> -
> - io_req_len = be32_to_cpu(io_req->hdr.smb_buf_length) + sizeof(io_req->hdr.smb_buf_length);
> + in_len = rc;
> + in_len += sizeof(io_req->Pad);
>
> /* NT IOCTL response contains one-word long output setup buffer with size of output data. */
> io_req->MaxSetupCount = 1;
> @@ -2973,8 +3016,7 @@ struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> io_req->ParameterCount = io_req->TotalParameterCount;
> io_req->ParameterOffset = cpu_to_le32(0);
> io_req->DataCount = io_req->TotalDataCount;
> - io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data) -
> - sizeof(io_req->hdr.smb_buf_length));
> + io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data));
> io_req->SetupCount = 4;
> io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
> io_req->FunctionCode = cpu_to_le32(FSCTL_SET_REPARSE_POINT);
> @@ -2983,10 +3025,8 @@ struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
> io_req->IsRootFlag = 0;
> io_req->ByteCount = cpu_to_le16(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad));
>
> - inc_rfc1001_len(io_req, reparse_iov->iov_len);
> -
> in_iov[0].iov_base = (char *)io_req;
> - in_iov[0].iov_len = io_req_len;
> + in_iov[0].iov_len = in_len;
> in_iov[1] = *reparse_iov;
> rc = SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type,
> CIFS_NO_RSP_BUF, &out_iov);
> @@ -3018,12 +3058,14 @@ CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> int bytes_returned;
> struct smb_com_transaction_compr_ioctl_req *pSMB;
> struct smb_com_transaction_ioctl_rsp *pSMBr;
> + unsigned int in_len;
>
> cifs_dbg(FYI, "Set compression for %u\n", fid);
> rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
>
> @@ -3037,7 +3079,7 @@ CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->DataCount = cpu_to_le32(2);
> pSMB->DataOffset =
> cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req,
> - compression_state) - 4); /* 84 */
> + compression_state)); /* 84 */
> pSMB->SetupCount = 4;
> pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
> pSMB->ParameterCount = 0;
> @@ -3047,9 +3089,9 @@ CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Fid = fid; /* file handle always le */
> /* 3 byte pad, followed by 2 byte compress state */
> pSMB->ByteCount = cpu_to_le16(5);
> - inc_rfc1001_len(pSMB, 5);
> + in_len += 5;
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc);
> @@ -3247,6 +3289,7 @@ int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
> /* SMB_QUERY_POSIX_ACL */
> TRANSACTION2_QPI_REQ *pSMB = NULL;
> TRANSACTION2_QPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -3257,8 +3300,9 @@ int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
> queryAclRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -3285,7 +3329,7 @@ int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(
> offsetof(struct smb_com_transaction2_qpi_req,
> - InformationLevel) - 4);
> + InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -3296,10 +3340,10 @@ int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
> if (rc) {
> @@ -3337,6 +3381,7 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
> {
> struct smb_com_transaction2_spi_req *pSMB = NULL;
> struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
> + unsigned int in_len;
> char *parm_data;
> int name_len;
> int rc = 0;
> @@ -3347,8 +3392,9 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
> setAclRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
> @@ -3368,9 +3414,9 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
> - parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset;
> + parm_data = ((char *)pSMB) + offset;
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
>
> /* convert to on the wire format for POSIX ACL */
> @@ -3391,9 +3437,9 @@ int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = cpu_to_le16(params);
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc);
> @@ -3429,6 +3475,7 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
> int rc = 0;
> struct smb_t2_qfi_req *pSMB = NULL;
> struct smb_t2_qfi_rsp *pSMBr = NULL;
> + unsigned int in_len;
> int bytes_returned;
> __u16 params, byte_count;
>
> @@ -3439,8 +3486,9 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
> GetExtAttrRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2 /* level */ + 2 /* fid */;
> pSMB->t2.TotalDataCount = 0;
> @@ -3453,7 +3501,7 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->t2.Timeout = 0;
> pSMB->t2.Reserved2 = 0;
> pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
> - Fid) - 4);
> + Fid));
> pSMB->t2.DataCount = 0;
> pSMB->t2.DataOffset = 0;
> pSMB->t2.SetupCount = 1;
> @@ -3465,10 +3513,10 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
> pSMB->Pad = 0;
> pSMB->Fid = netfid;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->t2.ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "error %d in GetExtAttr\n", rc);
> @@ -3521,11 +3569,13 @@ smb_init_nttransact(const __u16 sub_command, const int setup_count,
> int rc;
> __u32 temp_offset;
> struct smb_com_ntransact_req *pSMB;
> + unsigned int in_len;
>
> rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
> (void **)&pSMB);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
> *ret_buf = (void *)pSMB;
> pSMB->Reserved = 0;
> pSMB->TotalParameterCount = cpu_to_le32(parm_len);
> @@ -3534,12 +3584,12 @@ smb_init_nttransact(const __u16 sub_command, const int setup_count,
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->DataCount = pSMB->TotalDataCount;
> temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
> - (setup_count * 2) - 4 /* for rfc1001 length itself */;
> + (setup_count * 2);
> pSMB->ParameterOffset = cpu_to_le32(temp_offset);
> pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
> pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
> pSMB->SubCommand = cpu_to_le16(sub_command);
> - return 0;
> + return in_len;
> }
>
> static int
> @@ -3605,6 +3655,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
> QUERY_SEC_DESC_REQ *pSMB;
> struct kvec iov[1];
> struct kvec rsp_iov;
> + unsigned int in_len;
>
> cifs_dbg(FYI, "GetCifsACL\n");
>
> @@ -3613,8 +3664,9 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
>
> rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
> 8 /* parm len */, tcon, (void **) &pSMB);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->MaxParameterCount = cpu_to_le32(4);
> /* BB TEST with big acls that might need to be e.g. larger than 16K */
> @@ -3622,9 +3674,9 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
> pSMB->Fid = fid; /* file handle always le */
> pSMB->AclFlags = cpu_to_le32(info);
> pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
> - inc_rfc1001_len(pSMB, 11);
> + in_len += 11;
> iov[0].iov_base = (char *)pSMB;
> - iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
> + iov[0].iov_len = in_len;
>
> rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
> 0, &rsp_iov);
> @@ -3693,18 +3745,20 @@ CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
> int rc = 0;
> int bytes_returned = 0;
> SET_SEC_DESC_REQ *pSMB = NULL;
> + unsigned int in_len;
> void *pSMBr;
>
> setCifsAclRetry:
> rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->MaxSetupCount = 0;
> pSMB->Reserved = 0;
>
> param_count = 8;
> - param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid);
> data_count = acllen;
> data_offset = param_offset + param_count;
> byte_count = 3 /* pad */ + param_count;
> @@ -3726,13 +3780,12 @@ CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
> pSMB->AclFlags = cpu_to_le32(aclflag);
>
> if (pntsd && acllen) {
> - memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
> - data_offset, pntsd, acllen);
> - inc_rfc1001_len(pSMB, byte_count + data_count);
> + memcpy((char *)pSMBr + data_offset, pntsd, acllen);
> + in_len += byte_count + data_count;
> } else
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
>
> cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n",
> @@ -3757,6 +3810,7 @@ SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
> {
> QUERY_INFORMATION_REQ *pSMB;
> QUERY_INFORMATION_RSP *pSMBr;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -3765,8 +3819,9 @@ SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
> QInfRetry:
> rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -3780,10 +3835,10 @@ SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
> }
> pSMB->BufferFormat = 0x04;
> name_len++; /* account for buffer type byte */
> - inc_rfc1001_len(pSMB, (__u16)name_len);
> + in_len += name_len;
> pSMB->ByteCount = cpu_to_le16(name_len);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
> @@ -3822,6 +3877,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> {
> struct smb_t2_qfi_req *pSMB = NULL;
> struct smb_t2_qfi_rsp *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> __u16 params, byte_count;
> @@ -3829,8 +3885,9 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> QFileInfoRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2 /* level */ + 2 /* fid */;
> pSMB->t2.TotalDataCount = 0;
> @@ -3843,7 +3900,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->t2.Timeout = 0;
> pSMB->t2.Reserved2 = 0;
> pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
> - Fid) - 4);
> + Fid));
> pSMB->t2.DataCount = 0;
> pSMB->t2.DataOffset = 0;
> pSMB->t2.SetupCount = 1;
> @@ -3855,10 +3912,10 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
> pSMB->Pad = 0;
> pSMB->Fid = netfid;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->t2.ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
> @@ -3893,6 +3950,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> /* level 263 SMB_QUERY_FILE_ALL_INFO */
> TRANSACTION2_QPI_REQ *pSMB = NULL;
> TRANSACTION2_QPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -3902,8 +3960,9 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> QPathInfoRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -3926,7 +3985,7 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qpi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -3940,10 +3999,10 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> else
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc);
> @@ -3989,6 +4048,7 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> {
> struct smb_t2_qfi_req *pSMB = NULL;
> struct smb_t2_qfi_rsp *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> __u16 params, byte_count;
> @@ -3996,8 +4056,9 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> UnixQFileInfoRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2 /* level */ + 2 /* fid */;
> pSMB->t2.TotalDataCount = 0;
> @@ -4010,7 +4071,7 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->t2.Timeout = 0;
> pSMB->t2.Reserved2 = 0;
> pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
> - Fid) - 4);
> + Fid));
> pSMB->t2.DataCount = 0;
> pSMB->t2.DataOffset = 0;
> pSMB->t2.SetupCount = 1;
> @@ -4022,10 +4083,10 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
> pSMB->Pad = 0;
> pSMB->Fid = netfid;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->t2.ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
> @@ -4060,6 +4121,7 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> /* SMB_QUERY_FILE_UNIX_BASIC */
> TRANSACTION2_QPI_REQ *pSMB = NULL;
> TRANSACTION2_QPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> int name_len;
> @@ -4069,8 +4131,9 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> UnixQPathInfoRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -4093,7 +4156,7 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qpi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -4104,10 +4167,10 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
> @@ -4144,7 +4207,7 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
> T2_FFIRST_RSP_PARMS *parms;
> struct nls_table *nls_codepage;
> - unsigned int lnoff;
> + unsigned int in_len, lnoff;
> __u16 params, byte_count;
> int bytes_returned = 0;
> int name_len, remap;
> @@ -4155,8 +4218,9 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
> findFirstRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> nls_codepage = cifs_sb->local_nls;
> remap = cifs_remap(cifs_sb);
> @@ -4216,8 +4280,7 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalParameterCount = cpu_to_le16(params);
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(
> - offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
> - - 4);
> + offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
> @@ -4232,10 +4295,10 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
>
> /* BB what should we set StorageType to? Does it matter? BB */
> pSMB->SearchStorageType = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
>
> @@ -4294,7 +4357,7 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_FNEXT_REQ *pSMB = NULL;
> TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
> T2_FNEXT_RSP_PARMS *parms;
> - unsigned int name_len;
> + unsigned int name_len, in_len;
> unsigned int lnoff;
> __u16 params, byte_count;
> char *response_data;
> @@ -4308,8 +4371,9 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
>
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 14; /* includes 2 bytes of null string, converted to LE below*/
> byte_count = 0;
> @@ -4322,7 +4386,7 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(
> - offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
> + offsetof(struct smb_com_transaction2_fnext_req, SearchHandle));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -4350,10 +4414,10 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
> byte_count = params + 1 /* pad */ ;
> pSMB->TotalParameterCount = cpu_to_le16(params);
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
>
> @@ -4419,6 +4483,7 @@ CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
> {
> int rc = 0;
> FINDCLOSE_REQ *pSMB = NULL;
> + unsigned int in_len;
>
> cifs_dbg(FYI, "In CIFSSMBFindClose\n");
> rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
> @@ -4427,12 +4492,13 @@ CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
> as file handle has been closed */
> if (rc == -EAGAIN)
> return 0;
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->FileID = searchHandle;
> pSMB->ByteCount = 0;
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> if (rc)
> cifs_dbg(VFS, "Send error in FindClose = %d\n", rc);
> @@ -4454,6 +4520,7 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
> int rc = 0;
> TRANSACTION2_QPI_REQ *pSMB = NULL;
> TRANSACTION2_QPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int name_len, bytes_returned;
> __u16 params, byte_count;
>
> @@ -4464,8 +4531,9 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
> GetInodeNumberRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -4489,7 +4557,7 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qpi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -4500,10 +4568,10 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc);
> @@ -4546,6 +4614,7 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
> /* TRANS2_GET_DFS_REFERRAL */
> TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
> TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int name_len;
> @@ -4565,8 +4634,9 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
> */
> rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc,
> (void **)&pSMB, (void **)&pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> /* server pointer checked in called function,
> but should never be null here anyway */
> @@ -4608,7 +4678,7 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
> + struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel));
> pSMB->SetupCount = 1;
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
> @@ -4616,10 +4686,10 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
> pSMB->ParameterCount = cpu_to_le16(params);
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->MaxReferralLevel = cpu_to_le16(3);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc);
> @@ -4661,6 +4731,7 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_QFSI_REQ *pSMB = NULL;
> TRANSACTION2_QFSI_RSP *pSMBr = NULL;
> FILE_SYSTEM_ALLOC_INFO *response_data;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, byte_count;
> @@ -4669,8 +4740,9 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
> oldQFSInfoRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2; /* level */
> pSMB->TotalDataCount = 0;
> @@ -4685,17 +4757,17 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalParameterCount = cpu_to_le16(params);
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qfsi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
> pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
> @@ -4748,6 +4820,7 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_QFSI_REQ *pSMB = NULL;
> TRANSACTION2_QFSI_RSP *pSMBr = NULL;
> FILE_SYSTEM_SIZE_INFO *response_data;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, byte_count;
> @@ -4756,8 +4829,9 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
> QFSInfoRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2; /* level */
> pSMB->TotalDataCount = 0;
> @@ -4772,17 +4846,17 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalParameterCount = cpu_to_le16(params);
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qfsi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc);
> @@ -4834,6 +4908,7 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
> TRANSACTION2_QFSI_REQ *pSMB = NULL;
> TRANSACTION2_QFSI_RSP *pSMBr = NULL;
> FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, byte_count;
> @@ -4842,8 +4917,9 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
> QFSAttributeRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2; /* level */
> pSMB->TotalDataCount = 0;
> @@ -4859,17 +4935,17 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
> pSMB->TotalParameterCount = cpu_to_le16(params);
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qfsi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc);
> @@ -4904,6 +4980,7 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
> TRANSACTION2_QFSI_REQ *pSMB = NULL;
> TRANSACTION2_QFSI_RSP *pSMBr = NULL;
> FILE_SYSTEM_DEVICE_INFO *response_data;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, byte_count;
> @@ -4912,8 +4989,9 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
> QFSDeviceRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2; /* level */
> pSMB->TotalDataCount = 0;
> @@ -4929,7 +5007,7 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
> pSMB->TotalParameterCount = cpu_to_le16(params);
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qfsi_req, InformationLevel));
>
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> @@ -4937,10 +5015,10 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc);
> @@ -4975,6 +5053,7 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
> TRANSACTION2_QFSI_REQ *pSMB = NULL;
> TRANSACTION2_QFSI_RSP *pSMBr = NULL;
> FILE_SYSTEM_UNIX_INFO *response_data;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, byte_count;
> @@ -4983,8 +5062,9 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
> QFSUnixRetry:
> rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
> (void **) &pSMB, (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2; /* level */
> pSMB->TotalDataCount = 0;
> @@ -5002,15 +5082,15 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
> pSMB->ParameterCount = cpu_to_le16(params);
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
> - smb_com_transaction2_qfsi_req, InformationLevel) - 4);
> + smb_com_transaction2_qfsi_req, InformationLevel));
> pSMB->SetupCount = 1;
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc);
> @@ -5044,6 +5124,7 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
> /* level 0x200 SMB_SET_CIFS_UNIX_INFO */
> TRANSACTION2_SETFSI_REQ *pSMB = NULL;
> TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, param_offset, offset, byte_count;
> @@ -5053,8 +5134,9 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
> /* BB switch to small buf init to save memory */
> rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
> (void **) &pSMB, (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 4; /* 2 bytes zero followed by info level. */
> pSMB->MaxSetupCount = 0;
> @@ -5062,8 +5144,7 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
> pSMB->Flags = 0;
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
> - - 4;
> + param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum);
> offset = param_offset + params;
>
> pSMB->MaxParameterCount = cpu_to_le16(4);
> @@ -5090,10 +5171,10 @@ CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap)
> pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
> pSMB->ClientUnixCap = cpu_to_le64(cap);
>
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc);
> @@ -5120,6 +5201,7 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_QFSI_REQ *pSMB = NULL;
> TRANSACTION2_QFSI_RSP *pSMBr = NULL;
> FILE_SYSTEM_POSIX_INFO *response_data;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned = 0;
> __u16 params, byte_count;
> @@ -5128,8 +5210,9 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
> QFSPosixRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> params = 2; /* level */
> pSMB->TotalDataCount = 0;
> @@ -5147,15 +5230,15 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = cpu_to_le16(params);
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
> - smb_com_transaction2_qfsi_req, InformationLevel) - 4);
> + smb_com_transaction2_qfsi_req, InformationLevel));
> pSMB->SetupCount = 1;
> pSMB->Reserved3 = 0;
> pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
> pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc);
> @@ -5220,6 +5303,7 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
> struct smb_com_transaction2_spi_req *pSMB = NULL;
> struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
> struct file_end_of_file_info *parm_data;
> + unsigned int in_len;
> int name_len;
> int rc = 0;
> int bytes_returned = 0;
> @@ -5231,8 +5315,9 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
> SetEOFRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -5253,7 +5338,7 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
> if (set_allocation) {
> if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
> @@ -5285,10 +5370,10 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = cpu_to_le16(params);
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> parm_data->FileSize = cpu_to_le64(size);
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc);
> @@ -5307,15 +5392,16 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
> {
> struct smb_com_transaction2_sfi_req *pSMB = NULL;
> struct file_end_of_file_info *parm_data;
> + unsigned int in_len;
> int rc = 0;
> __u16 params, param_offset, offset, byte_count, count;
>
> cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n",
> (long long)size);
> rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
> -
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16));
> @@ -5326,7 +5412,7 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Flags = 0;
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
> offset = param_offset + params;
>
> count = sizeof(struct file_end_of_file_info);
> @@ -5342,9 +5428,8 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalDataCount = pSMB->DataCount;
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> parm_data =
> - (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4);
> + (struct file_end_of_file_info *)(((char *)pSMB) + offset);
> pSMB->DataOffset = cpu_to_le16(offset);
> parm_data->FileSize = cpu_to_le64(size);
> pSMB->Fid = cfile->fid.netfid;
> @@ -5364,9 +5449,9 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
> cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
> }
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> if (rc) {
> cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n",
> @@ -5388,6 +5473,7 @@ SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
> SETATTR_REQ *pSMB;
> SETATTR_RSP *pSMBr;
> struct timespec64 ts;
> + unsigned int in_len;
> int bytes_returned;
> int name_len;
> int rc;
> @@ -5397,8 +5483,9 @@ SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
> retry:
> rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -5420,10 +5507,10 @@ SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
> }
> pSMB->BufferFormat = 0x04;
> name_len++; /* account for buffer type byte */
> - inc_rfc1001_len(pSMB, (__u16)name_len);
> + in_len += name_len;
> pSMB->ByteCount = cpu_to_le16(name_len);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "Send error in %s = %d\n", __func__, rc);
> @@ -5447,15 +5534,16 @@ CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
> {
> struct smb_com_transaction2_sfi_req *pSMB = NULL;
> + unsigned int in_len;
> char *data_offset;
> int rc = 0;
> __u16 params, param_offset, offset, byte_count, count;
>
> cifs_dbg(FYI, "Set Times (via SetFileInfo)\n");
> rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
> -
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
> @@ -5466,11 +5554,10 @@ CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Flags = 0;
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
> offset = param_offset + params;
>
> - data_offset = (char *)pSMB +
> - offsetof(struct smb_hdr, Protocol) + offset;
> + data_offset = (char *)pSMB + offset;
>
> count = sizeof(FILE_BASIC_INFO);
> pSMB->MaxParameterCount = cpu_to_le16(2);
> @@ -5492,10 +5579,10 @@ CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> else
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> if (rc)
> cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
> @@ -5512,15 +5599,16 @@ CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
> bool delete_file, __u16 fid, __u32 pid_of_opener)
> {
> struct smb_com_transaction2_sfi_req *pSMB = NULL;
> + unsigned int in_len;
> char *data_offset;
> int rc = 0;
> __u16 params, param_offset, offset, byte_count, count;
>
> cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n");
> rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
> -
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
> @@ -5531,11 +5619,9 @@ CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Flags = 0;
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
> offset = param_offset + params;
> -
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - data_offset = (char *)(pSMB) + offset + 4;
> + data_offset = (char *)(pSMB) + offset;
>
> count = 1;
> pSMB->MaxParameterCount = cpu_to_le16(2);
> @@ -5554,10 +5640,10 @@ CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Fid = fid;
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> *data_offset = delete_file ? 1 : 0;
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> if (rc)
> cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc);
> @@ -5605,6 +5691,7 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> {
> TRANSACTION2_SPI_REQ *pSMB = NULL;
> TRANSACTION2_SPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int name_len;
> int rc = 0;
> int bytes_returned = 0;
> @@ -5617,8 +5704,9 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> SetTimesRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -5641,7 +5729,7 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
> data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset;
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
> @@ -5660,10 +5748,10 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> else
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc);
> @@ -5733,15 +5821,16 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> u16 fid, u32 pid_of_opener)
> {
> struct smb_com_transaction2_sfi_req *pSMB = NULL;
> + unsigned int in_len;
> char *data_offset;
> int rc = 0;
> u16 params, param_offset, offset, byte_count, count;
>
> cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n");
> rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
> -
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
> pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
> @@ -5752,11 +5841,10 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Flags = 0;
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> - param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
> + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid);
> offset = param_offset + params;
>
> - data_offset = (char *)pSMB +
> - offsetof(struct smb_hdr, Protocol) + offset;
> + data_offset = (char *)pSMB + offset;
>
> count = sizeof(FILE_UNIX_BASIC_INFO);
>
> @@ -5776,12 +5864,12 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Fid = fid;
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
>
> - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
> + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, in_len, 0);
> cifs_small_buf_release(pSMB);
> if (rc)
> cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n",
> @@ -5801,6 +5889,7 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> {
> TRANSACTION2_SPI_REQ *pSMB = NULL;
> TRANSACTION2_SPI_RSP *pSMBr = NULL;
> + unsigned int in_len;
> int name_len;
> int rc = 0;
> int bytes_returned = 0;
> @@ -5811,8 +5900,9 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> setPermsRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -5835,10 +5925,9 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
> - /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */
> - data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4);
> + data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset);
> memset(data_offset, 0, count);
> pSMB->DataOffset = cpu_to_le16(offset);
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
> @@ -5852,12 +5941,12 @@ CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->TotalDataCount = pSMB->DataCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
>
> cifs_fill_unix_set_info(data_offset, args);
>
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc);
> @@ -5889,6 +5978,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
> TRANSACTION2_QPI_RSP *pSMBr = NULL;
> int remap = cifs_remap(cifs_sb);
> struct nls_table *nls_codepage = cifs_sb->local_nls;
> + unsigned int in_len;
> int rc = 0;
> int bytes_returned;
> int list_len;
> @@ -5903,8 +5993,9 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
> QAllEAsRetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> list_len =
> @@ -5927,7 +6018,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> pSMB->ParameterOffset = cpu_to_le16(offsetof(
> - struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
> + struct smb_com_transaction2_qpi_req, InformationLevel));
> pSMB->DataCount = 0;
> pSMB->DataOffset = 0;
> pSMB->SetupCount = 1;
> @@ -5938,10 +6029,10 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = pSMB->TotalParameterCount;
> pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
>
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc) {
> cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc);
> @@ -6073,6 +6164,7 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
> struct smb_com_transaction2_spi_req *pSMB = NULL;
> struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
> struct fealist *parm_data;
> + unsigned int in_len;
> int name_len;
> int rc = 0;
> int bytes_returned = 0;
> @@ -6083,8 +6175,9 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
> SetEARetry:
> rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
> (void **) &pSMBr);
> - if (rc)
> + if (rc < 0)
> return rc;
> + in_len = rc;
>
> if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
> name_len =
> @@ -6116,12 +6209,12 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->Reserved2 = 0;
> param_offset = offsetof(struct smb_com_transaction2_spi_req,
> - InformationLevel) - 4;
> + InformationLevel);
> offset = param_offset + params;
> pSMB->InformationLevel =
> cpu_to_le16(SMB_SET_FILE_EA);
>
> - parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset;
> + parm_data = (void *)pSMB + offset;
> pSMB->ParameterOffset = cpu_to_le16(param_offset);
> pSMB->DataOffset = cpu_to_le16(offset);
> pSMB->SetupCount = 1;
> @@ -6150,9 +6243,9 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->ParameterCount = cpu_to_le16(params);
> pSMB->TotalParameterCount = pSMB->ParameterCount;
> pSMB->Reserved4 = 0;
> - inc_rfc1001_len(pSMB, byte_count);
> + in_len += byte_count;
> pSMB->ByteCount = cpu_to_le16(byte_count);
> - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
> + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
> (struct smb_hdr *) pSMBr, &bytes_returned, 0);
> if (rc)
> cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc);
> diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
> index 2ec25e2cc8ec..d67b256a2ee7 100644
> --- a/fs/smb/client/cifstransport.c
> +++ b/fs/smb/client/cifstransport.c
> @@ -75,14 +75,14 @@ int
> smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
> unsigned int smb_buf_length)
> {
> - struct kvec iov[2];
> - struct smb_rqst rqst = { .rq_iov = iov,
> - .rq_nvec = 2 };
> -
> - iov[0].iov_base = smb_buffer;
> - iov[0].iov_len = 4;
> - iov[1].iov_base = (char *)smb_buffer + 4;
> - iov[1].iov_len = smb_buf_length;
> + struct kvec iov[1] = {
> + [0].iov_base = smb_buffer,
> + [0].iov_len = smb_buf_length,
> + };
> + struct smb_rqst rqst = {
> + .rq_iov = iov,
> + .rq_nvec = ARRAY_SIZE(iov),
> + };
>
> return __smb_send_rqst(server, 1, &rqst);
> }
> @@ -126,10 +126,6 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
> struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
> struct smb_message *smb;
>
> - if (rqst->rq_iov[0].iov_len != 4 ||
> - rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
> - return ERR_PTR(-EIO);
> -
> /* enable signing if server requires it */
> if (server->sign)
> hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
> @@ -158,7 +154,7 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
> */
> int
> SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
> - char *in_buf, int flags)
> + char *in_buf, unsigned int in_len, int flags)
> {
> int rc;
> struct kvec iov[1];
> @@ -166,7 +162,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
> int resp_buf_type;
>
> iov[0].iov_base = in_buf;
> - iov[0].iov_len = get_rfc1002_len(in_buf) + 4;
> + iov[0].iov_len = in_len;
> flags |= CIFS_NO_RSP_BUF;
> rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
> cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
> @@ -178,21 +174,19 @@ int
> cifs_check_receive(struct smb_message *smb, struct TCP_Server_Info *server,
> bool log_error)
> {
> - unsigned int len = get_rfc1002_len(smb->resp_buf) + 4;
> + unsigned int len = smb->response_pdu_len;
>
> dump_smb(smb->resp_buf, min_t(u32, 92, len));
>
> /* convert the length into a more usable form */
> if (server->sign) {
> - struct kvec iov[2];
> + struct kvec iov[1];
> int rc = 0;
> struct smb_rqst rqst = { .rq_iov = iov,
> - .rq_nvec = 2 };
> + .rq_nvec = ARRAY_SIZE(iov) };
>
> iov[0].iov_base = smb->resp_buf;
> - iov[0].iov_len = 4;
> - iov[1].iov_base = (char *)smb->resp_buf + 4;
> - iov[1].iov_len = len - 4;
> + iov[0].iov_len = len;
> /* FIXME: add code to kill session */
> rc = cifs_verify_signature(&rqst, server,
> smb->sequence_number);
> @@ -213,10 +207,6 @@ cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
> struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
> struct smb_message *smb;
>
> - if (rqst->rq_iov[0].iov_len != 4 ||
> - rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
> - return ERR_PTR(-EIO);
> -
> rc = allocate_mid(ses, hdr, &smb);
> if (rc)
> return ERR_PTR(rc);
> @@ -233,53 +223,29 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
> struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
> const int flags, struct kvec *resp_iov)
> {
> - struct smb_rqst rqst;
> - struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
> - int rc;
> -
> - if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
> - new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec),
> - GFP_KERNEL);
> - if (!new_iov) {
> - /* otherwise cifs_send_recv below sets resp_buf_type */
> - *resp_buf_type = CIFS_NO_BUFFER;
> - return -ENOMEM;
> - }
> - } else
> - new_iov = s_iov;
> -
> - /* 1st iov is a RFC1001 length followed by the rest of the packet */
> - memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
> + struct smb_rqst rqst = {
> + .rq_iov = iov,
> + .rq_nvec = n_vec,
> + };
>
> - new_iov[0].iov_base = new_iov[1].iov_base;
> - new_iov[0].iov_len = 4;
> - new_iov[1].iov_base += 4;
> - new_iov[1].iov_len -= 4;
> -
> - memset(&rqst, 0, sizeof(struct smb_rqst));
> - rqst.rq_iov = new_iov;
> - rqst.rq_nvec = n_vec + 1;
> -
> - rc = cifs_send_recv(xid, ses, ses->server,
> - &rqst, resp_buf_type, flags, resp_iov);
> - if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
> - kfree(new_iov);
> - return rc;
> + return cifs_send_recv(xid, ses, ses->server,
> + &rqst, resp_buf_type, flags, resp_iov);
> }
>
> int
> SendReceive(const unsigned int xid, struct cifs_ses *ses,
> - struct smb_hdr *in_buf, struct smb_hdr *out_buf,
> - int *pbytes_returned, const int flags)
> + struct smb_hdr *in_buf, unsigned int in_len,
> + struct smb_hdr *out_buf, int *pbytes_returned, const int flags)
> {
> int rc = 0;
> struct smb_message *smb;
> - unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
> - struct kvec iov = { .iov_base = in_buf, .iov_len = len };
> + struct kvec iov = { .iov_base = in_buf, .iov_len = in_len };
> struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
> struct cifs_credits credits = { .value = 1, .instance = 0 };
> struct TCP_Server_Info *server;
>
> + if (WARN_ON_ONCE(in_len > 0xffffff))
> + return -EIO;
> if (ses == NULL) {
> cifs_dbg(VFS, "Null smb session\n");
> return -EIO;
> @@ -301,9 +267,9 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
> to the same server. We may make this configurable later or
> use ses->maxReq */
>
> - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
> + if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
> cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
> - len);
> + in_len);
> return -EIO;
> }
>
> @@ -325,7 +291,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
> return rc;
> }
>
> - rc = cifs_sign_smb(in_buf, server, &smb->sequence_number);
> + rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
> if (rc) {
> cifs_server_unlock(server);
> goto out;
> @@ -333,7 +299,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
>
> smb->mid_state = MID_REQUEST_SUBMITTED;
>
> - rc = smb_send(server, in_buf, len);
> + rc = smb_send(server, in_buf, in_len);
> cifs_save_when_sent(smb);
>
> if (rc < 0)
> @@ -372,8 +338,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
> goto out;
> }
>
> - *pbytes_returned = get_rfc1002_len(smb->resp_buf);
> - memcpy(out_buf, smb->resp_buf, *pbytes_returned + 4);
> + *pbytes_returned = smb->response_pdu_len;
> + memcpy(out_buf, smb->resp_buf, *pbytes_returned);
> rc = cifs_check_receive(smb, server, 0);
> out:
> delete_mid(smb);
> @@ -387,8 +353,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
>
> static int
> send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
> - struct smb_hdr *in_buf,
> - struct smb_hdr *out_buf)
> + struct smb_hdr *in_buf, unsigned int in_len,
> + struct smb_hdr *out_buf)
> {
> int bytes_returned;
> struct cifs_ses *ses = tcon->ses;
> @@ -403,25 +369,25 @@ send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
> pSMB->Timeout = 0;
> pSMB->hdr.Mid = get_next_mid(ses->server);
>
> - return SendReceive(xid, ses, in_buf, out_buf,
> + return SendReceive(xid, ses, in_buf, in_len, out_buf,
> &bytes_returned, 0);
> }
>
> -int
> -SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> - struct smb_hdr *in_buf, struct smb_hdr *out_buf,
> - int *pbytes_returned)
> +int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> + struct smb_hdr *in_buf, unsigned int in_len,
> + struct smb_hdr *out_buf, int *pbytes_returned)
> {
> int rc = 0;
> int rstart = 0;
> struct smb_message *smb;
> struct cifs_ses *ses;
> - unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
> - struct kvec iov = { .iov_base = in_buf, .iov_len = len };
> + struct kvec iov = { .iov_base = in_buf, .iov_len = in_len };
> struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
> unsigned int instance;
> struct TCP_Server_Info *server;
>
> + if (WARN_ON_ONCE(in_len > 0xffffff))
> + return -EIO;
> if (tcon == NULL || tcon->ses == NULL) {
> cifs_dbg(VFS, "Null smb session\n");
> return -EIO;
> @@ -445,9 +411,9 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> to the same server. We may make this configurable later or
> use ses->maxReq */
>
> - if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
> + if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
> cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
> - len);
> + in_len);
> return -EIO;
> }
>
> @@ -467,7 +433,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> return rc;
> }
>
> - rc = cifs_sign_smb(in_buf, server, &smb->sequence_number);
> + rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
> if (rc) {
> delete_mid(smb);
> cifs_server_unlock(server);
> @@ -475,7 +441,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> }
>
> smb->mid_state = MID_REQUEST_SUBMITTED;
> - rc = smb_send(server, in_buf, len);
> + rc = smb_send(server, in_buf, in_len);
> cifs_save_when_sent(smb);
>
> if (rc < 0)
> @@ -516,7 +482,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
> to cause the blocking lock to return. */
>
> - rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
> + rc = send_lock_cancel(xid, tcon, in_buf, in_len, out_buf);
>
> /* If we get -ENOLCK back the lock may have
> already been removed. Don't exit in this case. */
> @@ -557,8 +523,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> goto out;
> }
>
> - *pbytes_returned = get_rfc1002_len(smb->resp_buf);
> - memcpy(out_buf, smb->resp_buf, *pbytes_returned + 4);
> + *pbytes_returned = smb->response_pdu_len;
> + memcpy(out_buf, smb->resp_buf, *pbytes_returned);
> rc = cifs_check_receive(smb, server, 0);
> out:
> delete_mid(smb);
> diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
> index ee61eb8d909f..86a328b3615a 100644
> --- a/fs/smb/client/connect.c
> +++ b/fs/smb/client/connect.c
> @@ -1156,15 +1156,14 @@ standard_receive3(struct TCP_Server_Info *server, struct smb_message *smb)
> unsigned int pdu_length = server->pdu_size;
>
> /* make sure this will fit in a large buffer */
> - if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) -
> - HEADER_PREAMBLE_SIZE(server)) {
> + if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) {
> cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
> cifs_reconnect(server, true);
> return -ECONNABORTED;
> }
>
> /* switch to large buffer if too big for a small one */
> - if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
> + if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) {
> server->large_buf = true;
> memcpy(server->bigbuf, buf, server->total_read);
> buf = server->bigbuf;
> @@ -1197,7 +1196,8 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct smb_message *smb)
> * 48 bytes is enough to display the header and a little bit
> * into the payload for debugging purposes.
> */
> - rc = server->ops->check_message(buf, server->total_read, server);
> + rc = server->ops->check_message(buf, server->pdu_size,
> + server->total_read, server);
> if (rc)
> cifs_dump_mem("Bad SMB: ", buf,
> min_t(unsigned int, server->total_read, 48));
> @@ -1287,16 +1287,13 @@ cifs_demultiplex_thread(void *p)
> if (length < 0)
> continue;
>
> - if (is_smb1(server))
> - server->total_read = length;
> - else
> - server->total_read = 0;
> + server->total_read = 0;
>
> /*
> * The right amount was read from socket - 4 bytes,
> * so we can now interpret the length field.
> */
> - pdu_length = get_rfc1002_len(buf);
> + pdu_length = be32_to_cpup(((__be32 *)buf)) & 0xffffff;
>
> cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
> if (!is_smb_response(server, buf[0]))
> @@ -1315,9 +1312,8 @@ cifs_demultiplex_thread(void *p)
> }
>
> /* read down to the MID */
> - length = cifs_read_from_socket(server,
> - buf + HEADER_PREAMBLE_SIZE(server),
> - MID_HEADER_SIZE(server));
> + length = cifs_read_from_socket(server, buf,
> + MID_HEADER_SIZE(server));
> if (length < 0)
> continue;
> server->total_read += length;
> @@ -1349,6 +1345,8 @@ cifs_demultiplex_thread(void *p)
> bufs[0] = buf;
> num_smbs = 1;
>
> + if (smbs[0])
> + smbs[0]->response_pdu_len = pdu_length;
> if (!smbs[0] || !smbs[0]->receive)
> length = standard_receive3(server, smbs[0]);
> else
> @@ -1407,7 +1405,7 @@ cifs_demultiplex_thread(void *p)
> smb2_add_credits_from_hdr(bufs[i], server);
> #ifdef CONFIG_CIFS_DEBUG2
> if (server->ops->dump_detail)
> - server->ops->dump_detail(bufs[i],
> + server->ops->dump_detail(bufs[i], pdu_length,
> server);
> cifs_dump_mids(server);
> #endif /* CIFS_DEBUG2 */
> @@ -4000,7 +3998,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
> TCONX_RSP *pSMBr;
> unsigned char *bcc_ptr;
> int rc = 0;
> - int length;
> + int length, in_len;
> __u16 bytes_left, count;
>
> if (ses == NULL)
> @@ -4012,8 +4010,8 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
>
> smb_buffer_response = smb_buffer;
>
> - header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
> - NULL /*no tid */, 4 /*wct */);
> + in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
> + NULL /*no tid */, 4 /*wct */);
>
> smb_buffer->Mid = get_next_mid(ses->server);
> smb_buffer->Uid = ses->Suid;
> @@ -4054,11 +4052,11 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
> bcc_ptr += strlen("?????");
> bcc_ptr += 1;
> count = bcc_ptr - &pSMB->Password[0];
> - be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
> + in_len += count;
> pSMB->ByteCount = cpu_to_le16(count);
>
> - rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
> - 0);
> + rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
> + &length, 0);
>
> /* above now done in SendReceive */
> if (rc == 0) {
> diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
> index 8967c771bdb2..6e59c79dbbc6 100644
> --- a/fs/smb/client/misc.c
> +++ b/fs/smb/client/misc.c
> @@ -265,19 +265,18 @@ free_rsp_buf(int resp_buftype, void *rsp)
>
> /* NB: MID can not be set if treeCon not passed in, in that
> case it is responsibility of caller to set the mid */
> -void
> +unsigned int
> header_assemble(struct smb_hdr *buffer, char smb_command,
> const struct cifs_tcon *treeCon, int word_count
> /* length of fixed section (word count) in two byte units */)
> {
> + unsigned int in_len;
> char *temp = (char *) buffer;
>
> memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
>
> - buffer->smb_buf_length = cpu_to_be32(
> - (2 * word_count) + sizeof(struct smb_hdr) -
> - 4 /* RFC 1001 length field does not count */ +
> - 2 /* for bcc field itself */) ;
> + in_len = (2 * word_count) + sizeof(struct smb_hdr) +
> + 2 /* for bcc field itself */;
>
> buffer->Protocol[0] = 0xFF;
> buffer->Protocol[1] = 'S';
> @@ -312,7 +311,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command,
>
> /* endian conversion of flags is now done just before sending */
> buffer->WordCount = (char) word_count;
> - return;
> + return in_len;
> }
>
> static int
> @@ -347,10 +346,11 @@ check_smb_hdr(struct smb_hdr *smb)
> }
>
> int
> -checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
> +checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
> + struct TCP_Server_Info *server)
> {
> struct smb_hdr *smb = (struct smb_hdr *)buf;
> - __u32 rfclen = be32_to_cpu(smb->smb_buf_length);
> + __u32 rfclen = pdu_len;
> __u32 clc_len; /* calculated length */
> cifs_dbg(FYI, "checkSMB Length: 0x%x, smb_buf_length: 0x%x\n",
> total_read, rfclen);
> @@ -395,24 +395,24 @@ checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)
> return -EIO;
> clc_len = smbCalcSize(smb);
>
> - if (4 + rfclen != total_read) {
> - cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n",
> - rfclen);
> + if (rfclen != total_read) {
> + cifs_dbg(VFS, "Length read does not match RFC1001 length %d/%d\n",
> + rfclen, total_read);
> return -EIO;
> }
>
> - if (4 + rfclen != clc_len) {
> + if (rfclen != clc_len) {
> __u16 mid = get_mid(smb);
> /* check if bcc wrapped around for large read responses */
> if ((rfclen > 64 * 1024) && (rfclen > clc_len)) {
> /* check if lengths match mod 64K */
> - if (((4 + rfclen) & 0xFFFF) == (clc_len & 0xFFFF))
> + if (((rfclen) & 0xFFFF) == (clc_len & 0xFFFF))
> return 0; /* bcc wrapped */
> }
> cifs_dbg(FYI, "Calculated size %u vs length %u mismatch for mid=%u\n",
> - clc_len, 4 + rfclen, mid);
> + clc_len, rfclen, mid);
>
> - if (4 + rfclen < clc_len) {
> + if (rfclen < clc_len) {
> cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n",
> rfclen, mid);
> return -EIO;
> @@ -452,7 +452,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
> (struct smb_com_transaction_change_notify_rsp *)buf;
> struct file_notify_information *pnotify;
> __u32 data_offset = 0;
> - size_t len = srv->total_read - sizeof(pSMBr->hdr.smb_buf_length);
> + size_t len = srv->total_read - srv->pdu_size;
>
> if (get_bcc(buf) > sizeof(struct file_notify_information)) {
> data_offset = le32_to_cpu(pSMBr->DataOffset);
> diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
> index 8af53f9b3675..4cec7d7b6d9c 100644
> --- a/fs/smb/client/sess.c
> +++ b/fs/smb/client/sess.c
> @@ -1314,6 +1314,7 @@ struct sess_data {
> struct nls_table *nls_cp;
> void (*func)(struct sess_data *);
> int result;
> + unsigned int in_len;
>
> /* we will send the SMB in three pieces:
> * a fixed length beginning part, an optional
> @@ -1337,11 +1338,12 @@ sess_alloc_buffer(struct sess_data *sess_data, int wct)
> rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
> (void **)&smb_buf);
>
> - if (rc)
> + if (rc < 0)
> return rc;
>
> + sess_data->in_len = rc;
> sess_data->iov[0].iov_base = (char *)smb_buf;
> - sess_data->iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
> + sess_data->iov[0].iov_len = sess_data->in_len;
> /*
> * This variable will be used to clear the buffer
> * allocated above in case of any error in the calling function.
> @@ -1419,7 +1421,7 @@ sess_sendreceive(struct sess_data *sess_data)
> struct kvec rsp_iov = { NULL, 0 };
>
> count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
> - be32_add_cpu(&smb_buf->smb_buf_length, count);
> + sess_data->in_len += count;
> put_bcc(count, smb_buf);
>
> rc = SendReceive2(sess_data->xid, sess_data->ses,
> diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
> index e22a09ac9e53..91205685057c 100644
> --- a/fs/smb/client/smb1ops.c
> +++ b/fs/smb/client/smb1ops.c
> @@ -36,15 +36,15 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
> {
> int rc = 0;
> struct smb_hdr *in_buf = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
> + unsigned int in_len = rqst->rq_iov[0].iov_len;
>
> - /* -4 for RFC1001 length and +2 for BCC field */
> - in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
> + /* +2 for BCC field */
> in_buf->Command = SMB_COM_NT_CANCEL;
> in_buf->WordCount = 0;
> put_bcc(0, in_buf);
>
> cifs_server_lock(server);
> - rc = cifs_sign_smb(in_buf, server, &smb->sequence_number);
> + rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
> if (rc) {
> cifs_server_unlock(server);
> return rc;
> @@ -56,7 +56,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
> * after signing here.
> */
> --server->sequence_number;
> - rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
> + rc = smb_send(server, in_buf, in_len);
> if (rc < 0)
> server->sequence_number--;
>
> @@ -290,7 +290,7 @@ check2ndT2(char *buf)
> }
>
> static int
> -coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
> +coalesce_t2(char *second_buf, struct smb_hdr *target_hdr, unsigned int *pdu_len)
> {
> struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)second_buf;
> struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)target_hdr;
> @@ -356,15 +356,15 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
> }
> put_bcc(byte_count, target_hdr);
>
> - byte_count = be32_to_cpu(target_hdr->smb_buf_length);
> + byte_count = *pdu_len;
> byte_count += total_in_src;
> /* don't allow buffer to overflow */
> - if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
> + if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
> cifs_dbg(FYI, "coalesced BCC exceeds buffer size (%u)\n",
> byte_count);
> return -ENOBUFS;
> }
> - target_hdr->smb_buf_length = cpu_to_be32(byte_count);
> + *pdu_len = byte_count;
>
> /* copy second buffer into end of first buffer */
> memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
> @@ -399,7 +399,7 @@ cifs_check_trans2(struct smb_message *smb, struct TCP_Server_Info *server,
> smb->multiRsp = true;
> if (smb->resp_buf) {
> /* merge response - fix up 1st*/
> - malformed = coalesce_t2(buf, smb->resp_buf);
> + malformed = coalesce_t2(buf, smb->resp_buf, &smb->response_pdu_len);
> if (malformed > 0)
> return true;
> /* All parts received or packet is malformed. */
> @@ -462,7 +462,7 @@ smb1_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
> if (!(server->capabilities & CAP_LARGE_WRITE_X) ||
> (!(server->capabilities & CAP_UNIX) && server->sign))
> wsize = min_t(unsigned int, wsize,
> - server->maxBuf - sizeof(WRITE_REQ) + 4);
> + server->maxBuf - sizeof(WRITE_REQ));
>
> /* hard limit of CIFS_MAX_WSIZE */
> wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
> @@ -1488,7 +1488,6 @@ struct smb_version_values smb1_values = {
> .exclusive_lock_type = 0,
> .shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
> .unlock_lock_type = 0,
> - .header_preamble_size = 4,
> .header_size = sizeof(struct smb_hdr),
> .max_header_size = MAX_CIFS_HDR_SIZE,
> .read_rsp_size = sizeof(READ_RSP),
> diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
> index d06617f62d3b..fc278c1dacbb 100644
> --- a/fs/smb/client/smb1proto.h
> +++ b/fs/smb/client/smb1proto.h
> @@ -212,7 +212,7 @@ int smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
> unsigned int smb_buf_length);
> struct smb_message *cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst);
> int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
> - char *in_buf, int flags);
> + char *in_buf, unsigned int in_len, int flags);
> int cifs_check_receive(struct smb_message *mid, struct TCP_Server_Info *server,
> bool log_error);
> struct smb_message *cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
> @@ -221,10 +221,10 @@ int SendReceive2(const unsigned int xid, struct cifs_ses *ses,
> struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
> const int flags, struct kvec *resp_iov);
> int SendReceive(const unsigned int xid, struct cifs_ses *ses,
> - struct smb_hdr *in_buf, struct smb_hdr *out_buf,
> - int *pbytes_returned, const int flags);
> + struct smb_hdr *in_buf, unsigned int in_len,
> + struct smb_hdr *out_buf, int *pbytes_returned, const int flags);
> int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
> - struct smb_hdr *in_buf, struct smb_hdr *out_buf,
> - int *pbytes_returned);
> + struct smb_hdr *in_buf, unsigned int in_len,
> + struct smb_hdr *out_buf, int *pbytes_returned);
>
> #endif /* _SMB1PROTO_H */
> diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
> index f0eb25033d72..84e6b01000c6 100644
> --- a/fs/smb/client/smb2misc.c
> +++ b/fs/smb/client/smb2misc.c
> @@ -134,7 +134,8 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
> }
>
> int
> -smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
> +smb2_check_message(char *buf, unsigned int pdu_len, unsigned int len,
> + struct TCP_Server_Info *server)
> {
> struct TCP_Server_Info *pserver;
> struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
> diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
> index bf401c686686..5c8ed852cf55 100644
> --- a/fs/smb/client/smb2ops.c
> +++ b/fs/smb/client/smb2ops.c
> @@ -432,7 +432,7 @@ smb2_find_dequeue_mid(struct TCP_Server_Info *server, char *buf)
> }
>
> static void
> -smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
> +smb2_dump_detail(void *buf, size_t buf_len, struct TCP_Server_Info *server)
> {
> #ifdef CONFIG_CIFS_DEBUG2
> struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
> @@ -440,7 +440,7 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
> cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
> shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
> shdr->Id.SyncId.ProcessId);
> - if (!server->ops->check_message(buf, server->total_read, server)) {
> + if (!server->ops->check_message(buf, buf_len, server->total_read, server)) {
> cifs_server_dbg(VFS, "smb buf %p len %u\n", buf,
> server->ops->calc_smb_size(buf));
> }
> @@ -5769,7 +5769,6 @@ struct smb_version_values smb20_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> @@ -5791,7 +5790,6 @@ struct smb_version_values smb21_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> @@ -5812,7 +5810,6 @@ struct smb_version_values smb3any_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> @@ -5833,7 +5830,6 @@ struct smb_version_values smbdefault_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> @@ -5854,7 +5850,6 @@ struct smb_version_values smb30_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> @@ -5875,7 +5870,6 @@ struct smb_version_values smb302_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> @@ -5896,7 +5890,6 @@ struct smb_version_values smb311_values = {
> .shared_lock_type = SMB2_LOCKFLAG_SHARED,
> .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
> .header_size = sizeof(struct smb2_hdr),
> - .header_preamble_size = 0,
> .max_header_size = MAX_SMB2_HDR_SIZE,
> .read_rsp_size = sizeof(struct smb2_read_rsp),
> .lock_cmd = SMB2_LOCK,
> diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
> index ffc6e8cf9e47..9ca8e1a24e81 100644
> --- a/fs/smb/client/smb2proto.h
> +++ b/fs/smb/client/smb2proto.h
> @@ -90,7 +90,8 @@ int map_smb2_to_linux_error(char *buf, bool log_err);
> /*
> * smb2misc.c
> */
> -int smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server);
> +int smb2_check_message(char *buf, unsigned int pdu_len, unsigned int len,
> + struct TCP_Server_Info *server);
> char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *shdr);
> unsigned int smb2_calc_size(void *buf);
> __le16 *cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb);
> diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
> index 52083b79609b..2e338e186809 100644
> --- a/fs/smb/client/transport.c
> +++ b/fs/smb/client/transport.c
> @@ -290,8 +290,8 @@ int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
> sigfillset(&mask);
> sigprocmask(SIG_BLOCK, &mask, &oldmask);
>
> - /* Generate a rfc1002 marker for SMB2+ */
> - if (!is_smb1(server)) {
> + /* Generate a rfc1002 marker */
> + {
> struct kvec hiov = {
> .iov_base = &rfc1002_marker,
> .iov_len = 4
> @@ -1045,8 +1045,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
>
> buf = (char *)smb[i]->resp_buf;
> resp_iov[i].iov_base = buf;
> - resp_iov[i].iov_len = smb[i]->resp_buf_size +
> - HEADER_PREAMBLE_SIZE(server);
> + resp_iov[i].iov_len = smb[i]->resp_buf_size;
>
> if (smb[i]->large_buf)
> resp_buf_type[i] = CIFS_LARGE_BUFFER;
> @@ -1113,8 +1112,7 @@ int
> cifs_discard_remaining_data(struct TCP_Server_Info *server)
> {
> unsigned int rfclen = server->pdu_size;
> - size_t remaining = rfclen + HEADER_PREAMBLE_SIZE(server) -
> - server->total_read;
> + size_t remaining = rfclen - server->total_read;
>
> while (remaining > 0) {
> ssize_t length;
> @@ -1159,7 +1157,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
> unsigned int data_offset, data_len;
> struct cifs_io_subrequest *rdata = smb->callback_data;
> char *buf = server->smallbuf;
> - unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server);
> + unsigned int buflen = server->pdu_size;
> bool use_rdma_mr = false;
>
> cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%zu\n",
> @@ -1193,14 +1191,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
>
> /* set up first two iov for signature check and to get credits */
> rdata->iov[0].iov_base = buf;
> - rdata->iov[0].iov_len = HEADER_PREAMBLE_SIZE(server);
> - rdata->iov[1].iov_base = buf + HEADER_PREAMBLE_SIZE(server);
> - rdata->iov[1].iov_len =
> - server->total_read - HEADER_PREAMBLE_SIZE(server);
> + rdata->iov[0].iov_len = server->total_read;
> cifs_dbg(FYI, "0: iov_base=%p iov_len=%zu\n",
> rdata->iov[0].iov_base, rdata->iov[0].iov_len);
> - cifs_dbg(FYI, "1: iov_base=%p iov_len=%zu\n",
> - rdata->iov[1].iov_base, rdata->iov[1].iov_len);
>
> /* Was the SMB read successful? */
> rdata->result = server->ops->map_error(buf, false);
> @@ -1220,8 +1213,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
> return cifs_readv_discard(server, smb);
> }
>
> - data_offset = server->ops->read_data_offset(buf) +
> - HEADER_PREAMBLE_SIZE(server);
> + data_offset = server->ops->read_data_offset(buf);
> if (data_offset < server->total_read) {
> /*
> * win2k8 sometimes sends an offset of 0 when the read
> diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
> index f38c5739a9d2..945a8e0cf36c 100644
> --- a/fs/smb/common/smb2pdu.h
> +++ b/fs/smb/common/smb2pdu.h
> @@ -2016,9 +2016,6 @@ struct smb2_lease_ack {
> * MS-SMB 2.2.3.1
> */
> struct smb_hdr {
> - __be32 smb_buf_length; /* BB length is only two (rarely three) bytes,
> - with one or two byte "type" preceding it that will be
> - zero - we could mask the type byte off */
> __u8 Protocol[4];
> __u8 Command;
> union {
> diff --git a/fs/smb/common/smbglob.h b/fs/smb/common/smbglob.h
> index 7853b5771128..9562845a5617 100644
> --- a/fs/smb/common/smbglob.h
> +++ b/fs/smb/common/smbglob.h
> @@ -26,7 +26,6 @@ struct smb_version_values {
> __u32 exclusive_lock_type;
> __u32 shared_lock_type;
> __u32 unlock_lock_type;
> - size_t header_preamble_size;
> size_t header_size;
> size_t max_header_size;
> size_t read_rsp_size;
>
>
Powered by blists - more mailing lists