linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer
@ 2025-11-24 12:42 David Howells
  2025-11-24 12:42 ` [PATCH v4 01/11] cifs: Use netfs_alloc/free_folioq_buffer() David Howells
                   ` (10 more replies)
  0 siblings, 11 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel

Hi Steve,

Could you take these patches extracted from my I/O layer rewrite for the
upcoming merge window.  The performance change should be neutral, but it
cleans up the code a bit.

 (1) Use netfs_alloc/free_folioq_buffer() rather than cifs doing its own
     version.

 (2) Do some minor cleanups so that patch 2 can be generated wholly by a
     script.

 (3) Organise the declarations in the cifs client header files, naming the
     arguments the same as for the implementations, inserting divider
     comments, ordering them the same as they're found in the files and
     dividing them better between general, smb1 and smb2/3 categories.

     The organisation is entirely scripted with the script in the second
     patch's commit message.  The first patch does a bit of preparation to
     make sure that the second patch's output will build.

     By filling in the argument names, this stops checkpatch moaning about
     unnamed arguments from search-and-replace changes in later patches.
     (Note that it doesn't fix func pointer declarations).

     smbdirect is left untouched as requested by Stefan Metzmacher.

 (4) Rename struct mid_q_entry to smb_message.  In my rewrite, smb_message
     will get allocated in the marshalling functions in smb2pdu.c and
     cifssmb.c rather than in transport.c and used to hand parameters down
     - and so I think it could be better named for that.

 (5) Remove the RFC1002 header from the smb_hdr struct so that it's
     consistent with SMB2/3.  This allows I/O routines to be simplified and
     shared.

 (6) Make SMB1's SendReceive() wrap cifs_send_recv() and thus share code
     with SMB2/3.

 (7) Clean up a bunch of extra kvec[] that were required for RFC1002
     headers from SMB1's header struct.

 (8) Replace SendReceiveBlockingLock() with SendReceive() plus flags.

 (9) Remove the server pointer from smb_message.  It can be passed down
     from the caller to all places that need it.

(10) Don't need state locking in smb2_get_mid_entry() as we're just doing a
     single read inside the lock.  READ_ONCE() should suffice instead.

(11) Add a tracepoint to log EIO errors and up to a couple of bits of info
     for each to make it easier to find out why an EIO error happened when
     the system is very busy without introducing printk delays.

The patches can be found here also:

	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=cifs-cleanup

Thanks,
David

Changes
=======
ver #4)
 - Rebased on the ksmbd-for-next branch.
 - The read tracepoint patch got merged, so drop it.
 - Move the netfs_alloc, etc. patch first.
 - Fix a couple of prototypes that need to be conditional (may need some post
   cleanup).
 - Fixed another couple of headers that needed their own prototype lists.
 - Fixed #include order in a couple of places.

ver #3)
 - Rebased on the ksmbd-for-next branch.
 - Add the patches to clean up the function prototypes in the headers.
   - Don't touch smbdirect.
   - Put prototypes into netlink.h and cached_dir.h rather than
     centralising them.
   - Indent the arguments in the prototypes to the opening bracket + 1.
 - Cleaned up most other checkpatch complaints.
 - Added the EIO tracepoint patch to the end.

ver #2)
 - Rebased on the ksmbd-for-next-next branch.
 - Moved the patch to use netfs_alloc/free_folioq_buffer() down the stack.

David Howells (11):
  cifs: Use netfs_alloc/free_folioq_buffer()
  cifs: Do some preparation prior to organising the function
    declarations
  cifs: Clean up declarations
  cifs: Rename mid_q_entry to smb_message
  cifs: Remove the RFC1002 header from smb_hdr
  cifs: Make smb1's SendReceive() wrap cifs_send_recv()
  cifs: Clean up some places where an extra kvec[] was required for
    rfc1002
  cifs: Replace SendReceiveBlockingLock() with SendReceive() plus flags
  cifs: Remove the server pointer from smb_message
  cifs: Don't need state locking in smb2_get_mid_entry()
  cifs: Add a tracepoint to log EIO errors

 fs/smb/client/cached_dir.c    |    2 +-
 fs/smb/client/cached_dir.h    |   37 +-
 fs/smb/client/cifs_debug.c    |   51 +-
 fs/smb/client/cifs_debug.h    |   15 +-
 fs/smb/client/cifs_spnego.h   |    2 -
 fs/smb/client/cifs_swn.h      |   15 +-
 fs/smb/client/cifs_unicode.c  |    1 +
 fs/smb/client/cifs_unicode.h  |   16 -
 fs/smb/client/cifsacl.c       |   11 +-
 fs/smb/client/cifsencrypt.c   |   83 +--
 fs/smb/client/cifsfs.c        |   36 +-
 fs/smb/client/cifsfs.h        |   64 --
 fs/smb/client/cifsglob.h      |  219 ++----
 fs/smb/client/cifspdu.h       |   13 +-
 fs/smb/client/cifsproto.h     | 1318 +++++++++++++++++----------------
 fs/smb/client/cifssmb.c       |  932 +++++++++++++----------
 fs/smb/client/cifstransport.c |  439 ++---------
 fs/smb/client/compress.c      |   23 +-
 fs/smb/client/compress.h      |   20 +-
 fs/smb/client/connect.c       |  200 ++---
 fs/smb/client/dfs.h           |   12 +-
 fs/smb/client/dfs_cache.h     |    9 +-
 fs/smb/client/dir.c           |    9 +-
 fs/smb/client/dns_resolve.h   |    3 -
 fs/smb/client/file.c          |    7 +-
 fs/smb/client/fs_context.c    |    2 +-
 fs/smb/client/fs_context.h    |    9 -
 fs/smb/client/fscache.h       |   13 +-
 fs/smb/client/inode.c         |   15 +-
 fs/smb/client/ioctl.c         |    1 +
 fs/smb/client/link.c          |   11 +-
 fs/smb/client/misc.c          |   53 +-
 fs/smb/client/netlink.h       |    8 +-
 fs/smb/client/netmisc.c       |   21 +-
 fs/smb/client/nterr.h         |    2 -
 fs/smb/client/ntlmssp.h       |   13 -
 fs/smb/client/readdir.c       |    2 +-
 fs/smb/client/reparse.c       |   53 +-
 fs/smb/client/reparse.h       |   11 -
 fs/smb/client/sess.c          |   17 +-
 fs/smb/client/smb1ops.c       |  116 ++-
 fs/smb/client/smb1proto.h     |  227 ++++++
 fs/smb/client/smb2file.c      |    9 +-
 fs/smb/client/smb2inode.c     |   13 +-
 fs/smb/client/smb2maperror.c  |    6 +-
 fs/smb/client/smb2misc.c      |   11 +-
 fs/smb/client/smb2ops.c       |  253 +++----
 fs/smb/client/smb2pdu.c       |  230 +++---
 fs/smb/client/smb2proto.h     |  516 +++++++------
 fs/smb/client/smb2transport.c |  113 ++-
 fs/smb/client/smbdirect.c     |   18 +-
 fs/smb/client/smbdirect.h     |    1 +
 fs/smb/client/trace.h         |  153 ++++
 fs/smb/client/transport.c     |  302 ++++----
 fs/smb/client/xattr.c         |    2 +-
 fs/smb/common/smb2pdu.h       |    3 -
 fs/smb/common/smbglob.h       |    1 -
 57 files changed, 2887 insertions(+), 2855 deletions(-)
 create mode 100644 fs/smb/client/smb1proto.h


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v4 01/11] cifs: Use netfs_alloc/free_folioq_buffer()
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 02/11] cifs: Do some preparation prior to organising the function declarations David Howells
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Use netfs_alloc/free_folioq_buffer() rather than doing its own version.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com> (RDMA, smbdirect)
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/smb2ops.c | 75 +++++++----------------------------------
 1 file changed, 12 insertions(+), 63 deletions(-)

diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 4b005a7adce0..549fffbca246 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4484,61 +4484,6 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
 	return rc;
 }
 
-/*
- * Clear a read buffer, discarding the folios which have the 1st mark set.
- */
-static void cifs_clear_folioq_buffer(struct folio_queue *buffer)
-{
-	struct folio_queue *folioq;
-
-	while ((folioq = buffer)) {
-		for (int s = 0; s < folioq_count(folioq); s++)
-			if (folioq_is_marked(folioq, s))
-				folio_put(folioq_folio(folioq, s));
-		buffer = folioq->next;
-		kfree(folioq);
-	}
-}
-
-/*
- * Allocate buffer space into a folio queue.
- */
-static struct folio_queue *cifs_alloc_folioq_buffer(ssize_t size)
-{
-	struct folio_queue *buffer = NULL, *tail = NULL, *p;
-	struct folio *folio;
-	unsigned int slot;
-
-	do {
-		if (!tail || folioq_full(tail)) {
-			p = kmalloc(sizeof(*p), GFP_NOFS);
-			if (!p)
-				goto nomem;
-			folioq_init(p, 0);
-			if (tail) {
-				tail->next = p;
-				p->prev = tail;
-			} else {
-				buffer = p;
-			}
-			tail = p;
-		}
-
-		folio = folio_alloc(GFP_KERNEL|__GFP_HIGHMEM, 0);
-		if (!folio)
-			goto nomem;
-
-		slot = folioq_append_mark(tail, folio);
-		size -= folioq_folio_size(tail, slot);
-	} while (size > 0);
-
-	return buffer;
-
-nomem:
-	cifs_clear_folioq_buffer(buffer);
-	return NULL;
-}
-
 /*
  * Copy data from an iterator to the folios in a folio queue buffer.
  */
@@ -4564,7 +4509,7 @@ void
 smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst)
 {
 	for (int i = 0; i < num_rqst; i++)
-		cifs_clear_folioq_buffer(rqst[i].rq_buffer);
+		netfs_free_folioq_buffer(rqst[i].rq_buffer);
 }
 
 /*
@@ -4599,8 +4544,11 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
 		new->rq_nvec = old->rq_nvec;
 
 		if (size > 0) {
-			buffer = cifs_alloc_folioq_buffer(size);
-			if (!buffer)
+			size_t cur_size = 0;
+
+			rc = netfs_alloc_folioq_buffer(NULL, &buffer, &cur_size,
+						       size, GFP_NOFS);
+			if (rc < 0)
 				goto err_free;
 
 			new->rq_buffer = buffer;
@@ -4932,7 +4880,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
 	}
 
 free_pages:
-	cifs_clear_folioq_buffer(dw->buffer);
+	netfs_free_folioq_buffer(dw->buffer);
 	cifs_small_buf_release(dw->buf);
 	kfree(dw);
 }
@@ -4970,9 +4918,10 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
 	dw->len = len;
 	len = round_up(dw->len, PAGE_SIZE);
 
-	rc = -ENOMEM;
-	dw->buffer = cifs_alloc_folioq_buffer(len);
-	if (!dw->buffer)
+	size_t cur_size = 0;
+
+	rc = netfs_alloc_folioq_buffer(NULL, &dw->buffer, &cur_size, len, GFP_NOFS);
+	if (rc < 0)
 		goto discard_data;
 
 	iov_iter_folio_queue(&iter, ITER_DEST, dw->buffer, 0, 0, len);
@@ -5033,7 +4982,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
 	}
 
 free_pages:
-	cifs_clear_folioq_buffer(dw->buffer);
+	netfs_free_folioq_buffer(dw->buffer);
 free_dw:
 	kfree(dw);
 	return rc;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 02/11] cifs: Do some preparation prior to organising the function declarations
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
  2025-11-24 12:42 ` [PATCH v4 01/11] cifs: Use netfs_alloc/free_folioq_buffer() David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 03/11] cifs: Clean up declarations David Howells
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel

Make some preparatory changes prior to running a script to organise the
function declarations within the fs/smb/client/ headers.  These include:

 (1) Creating an smb1proto.h file and #including it in places that will
     need it.  It will be populated by a script in a follow on patch.

 (2) Insert a line saying "/* PROTOTYPES */" in the target headers to set
     the point at which prototypes should be inserted in that file.

 (3) Remove "inline" from the dummy cifs_proc_init/clean() functions as
     they are in a .c file.

 (4) Move should_compress()'s kdoc comment to the .c file and remove kdoc
     markers from the comments.

 (5) Rename CIFS_ALLOW_INSECURE_LEGACY in #endif comments to have CONFIG_
     on the front to allow the script to recognise it.

 (6) Don't let comments have bare words at the left margin as that confused
     the simplistic function detection code in the script.

 (7) Adjust some argument lists so that when the cleanup script is run they
     don't end up over 100 chars.

 (8) Fix a few comments to have missing '*' added or the "*/" moved to
     their own lines so that checkpatch doesn't moan over the cleanup
     script patch.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: linux-cifs@vger.kernel.org
---
 fs/smb/client/cached_dir.h    |  1 +
 fs/smb/client/cifs_debug.c    |  4 ++--
 fs/smb/client/cifs_debug.h    |  2 ++
 fs/smb/client/cifs_swn.h      |  2 ++
 fs/smb/client/cifs_unicode.c  |  1 +
 fs/smb/client/cifsacl.c       |  1 +
 fs/smb/client/cifsfs.c        |  5 +++--
 fs/smb/client/cifsglob.h      |  8 +++++++-
 fs/smb/client/cifsproto.h     | 15 +++------------
 fs/smb/client/cifssmb.c       |  1 +
 fs/smb/client/cifstransport.c |  1 +
 fs/smb/client/compress.c      | 21 ++++++++++++++++++---
 fs/smb/client/compress.h      | 20 +++-----------------
 fs/smb/client/connect.c       |  1 +
 fs/smb/client/dfs.h           |  1 +
 fs/smb/client/dfs_cache.h     |  1 +
 fs/smb/client/dir.c           |  3 ++-
 fs/smb/client/file.c          |  1 +
 fs/smb/client/fs_context.c    |  2 +-
 fs/smb/client/fscache.h       |  4 +---
 fs/smb/client/inode.c         |  1 +
 fs/smb/client/ioctl.c         |  1 +
 fs/smb/client/link.c          |  1 +
 fs/smb/client/misc.c          |  3 ++-
 fs/smb/client/netlink.h       |  1 +
 fs/smb/client/netmisc.c       |  2 +-
 fs/smb/client/sess.c          |  1 +
 fs/smb/client/smb1ops.c       |  2 ++
 fs/smb/client/smb1proto.h     | 20 ++++++++++++++++++++
 fs/smb/client/smb2file.c      |  3 ++-
 fs/smb/client/smb2inode.c     |  1 -
 fs/smb/client/smb2maperror.c  |  3 +--
 fs/smb/client/smb2ops.c       |  4 ++--
 fs/smb/client/smb2pdu.c       |  5 +++--
 fs/smb/client/smb2proto.h     |  9 ++++-----
 fs/smb/client/smbdirect.h     |  2 ++
 36 files changed, 97 insertions(+), 57 deletions(-)
 create mode 100644 fs/smb/client/smb1proto.h

diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index 1e383db7c337..b843442db2d4 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -77,6 +77,7 @@ is_valid_cached_dir(struct cached_fid *cfid)
 	return cfid->time && cfid->has_lease;
 }
 
+/* PROTOTYPES */
 extern struct cached_fids *init_cached_dirs(void);
 extern void free_cached_dirs(struct cached_fids *cfids);
 extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 1fb71d2d31b5..08538ad0f8dc 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -1307,11 +1307,11 @@ static const struct proc_ops cifs_mount_params_proc_ops = {
 };
 
 #else
-inline void cifs_proc_init(void)
+void cifs_proc_init(void)
 {
 }
 
-inline void cifs_proc_clean(void)
+void cifs_proc_clean(void)
 {
 }
 #endif /* PROC_FS */
diff --git a/fs/smb/client/cifs_debug.h b/fs/smb/client/cifs_debug.h
index ce5cfd236fdb..526afdb33cc6 100644
--- a/fs/smb/client/cifs_debug.h
+++ b/fs/smb/client/cifs_debug.h
@@ -14,6 +14,8 @@
 
 #define pr_fmt(fmt) "CIFS: " fmt
 
+/* PROTOTYPES */
+
 void cifs_dump_mem(char *label, void *data, int length);
 void cifs_dump_detail(void *buf, struct TCP_Server_Info *ptcp_info);
 void cifs_dump_mids(struct TCP_Server_Info *);
diff --git a/fs/smb/client/cifs_swn.h b/fs/smb/client/cifs_swn.h
index 8a9d2a5c9077..7063539c41c8 100644
--- a/fs/smb/client/cifs_swn.h
+++ b/fs/smb/client/cifs_swn.h
@@ -14,6 +14,8 @@ struct sk_buff;
 struct genl_info;
 
 #ifdef CONFIG_CIFS_SWN_UPCALL
+
+/* PROTOTYPES */
 extern int cifs_swn_register(struct cifs_tcon *tcon);
 
 extern int cifs_swn_unregister(struct cifs_tcon *tcon);
diff --git a/fs/smb/client/cifs_unicode.c b/fs/smb/client/cifs_unicode.c
index f8659d36793f..d73aee26c555 100644
--- a/fs/smb/client/cifs_unicode.c
+++ b/fs/smb/client/cifs_unicode.c
@@ -10,6 +10,7 @@
 #include "cifs_unicode.h"
 #include "cifspdu.h"
 #include "cifsglob.h"
+#include "cifsproto.h"
 #include "cifs_debug.h"
 
 int cifs_remap(struct cifs_sb_info *cifs_sb)
diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
index ce2ebc213a1d..7b88ef38bdf4 100644
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -21,6 +21,7 @@
 #include "cifsglob.h"
 #include "cifsacl.h"
 #include "cifsproto.h"
+#include "smb1proto.h"
 #include "cifs_debug.h"
 #include "fs_context.h"
 #include "cifs_fs_sb.h"
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 185ac41bd7e9..cbb34e3e2862 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -28,6 +28,8 @@
 #include <linux/splice.h>
 #include <linux/uuid.h>
 #include <linux/xattr.h>
+#include <linux/mm.h>
+#include <linux/key-type.h>
 #include <uapi/linux/magic.h>
 #include <net/ipv6.h>
 #include "cifsfs.h"
@@ -35,10 +37,9 @@
 #define DECLARE_GLOBALS_HERE
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "smb2proto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
-#include <linux/mm.h>
-#include <linux/key-type.h>
 #include "cifs_spnego.h"
 #include "fscache.h"
 #ifdef CONFIG_CIFS_DFS_UPCALL
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 0c76e0a31386..f859c5407fbc 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -2114,7 +2114,7 @@ extern struct smb_version_operations smb1_operations;
 extern struct smb_version_values smb1_values;
 extern struct smb_version_operations smb20_operations;
 extern struct smb_version_values smb20_values;
-#endif /* CIFS_ALLOW_INSECURE_LEGACY */
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 extern struct smb_version_operations smb21_operations;
 extern struct smb_version_values smb21_values;
 extern struct smb_version_values smbdefault_values;
@@ -2369,4 +2369,10 @@ static inline void mid_execute_callback(struct mid_q_entry *mid)
 	 (le32_to_cpu((tcon)->fsAttrInfo.Attributes) & \
 	  FILE_SUPPORTS_REPARSE_POINTS))
 
+struct cifs_calc_sig_ctx {
+	struct md5_ctx *md5;
+	struct hmac_sha256_ctx *hmac;
+	struct shash_desc *shash;
+};
+
 #endif	/* _CIFS_GLOB_H */
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 3528c365a452..aaa9e4f70f79 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -9,7 +9,7 @@
 #define _CIFSPROTO_H
 #include <linux/nls.h>
 #include <linux/ctype.h>
-#include "cifsglob.h"
+#include <cifsglob.h>
 #include "trace.h"
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dfs_cache.h"
@@ -19,11 +19,7 @@ struct statfs;
 struct smb_rqst;
 struct smb3_fs_context;
 
-/*
- *****************************************************************
- * All Prototypes
- *****************************************************************
- */
+/* PROTOTYPES */
 
 extern struct smb_hdr *cifs_buf_get(void);
 extern void cifs_buf_release(void *);
@@ -603,7 +599,7 @@ extern int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
 			   const struct nls_table *nls_codepage, int remap);
 extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
 			const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
-#endif /* CIFS_ALLOW_INSECURE_LEGACY */
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
 extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr);
 extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
@@ -635,11 +631,6 @@ int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
 			   struct cifs_sb_info *cifs_sb,
 			   const unsigned char *path, char *pbuf,
 			   unsigned int *pbytes_written);
-struct cifs_calc_sig_ctx {
-	struct md5_ctx *md5;
-	struct hmac_sha256_ctx *hmac;
-	struct shash_desc *shash;
-};
 int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 			  char *signature, struct cifs_calc_sig_ctx *ctx);
 enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 428e582e0414..85a9fa3b3768 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -31,6 +31,7 @@
 #include "cifsglob.h"
 #include "cifsacl.h"
 #include "cifsproto.h"
+#include "smb1proto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
 #include "fscache.h"
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 4c4f5befb6d3..9b3711af6038 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -26,6 +26,7 @@
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifs_debug.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "smbdirect.h"
 #include "compress.h"
diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c
index db709f5cd2e1..fb2a48f1d2ad 100644
--- a/fs/smb/client/compress.c
+++ b/fs/smb/client/compress.c
@@ -44,7 +44,7 @@ struct bucket {
 	unsigned int count;
 };
 
-/**
+/*
  * has_low_entropy() - Compute Shannon entropy of the sampled data.
  * @bkt:	Bytes counts of the sample.
  * @slen:	Size of the sample.
@@ -82,7 +82,7 @@ static bool has_low_entropy(struct bucket *bkt, size_t slen)
 #define BYTE_DIST_BAD		0
 #define BYTE_DIST_GOOD		1
 #define BYTE_DIST_MAYBE		2
-/**
+/*
  * calc_byte_distribution() - Compute byte distribution on the sampled data.
  * @bkt:	Byte counts of the sample.
  * @slen:	Size of the sample.
@@ -182,7 +182,7 @@ static int collect_sample(const struct iov_iter *source, ssize_t max, u8 *sample
 	return s;
 }
 
-/**
+/*
  * is_compressible() - Determines if a chunk of data is compressible.
  * @data: Iterator containing uncompressed data.
  *
@@ -261,6 +261,21 @@ static bool is_compressible(const struct iov_iter *data)
 	return ret;
 }
 
+/*
+ * should_compress() - Determines if a request (write) or the response to a
+ *		       request (read) should be compressed.
+ * @tcon: tcon of the request is being sent to
+ * @rqst: request to evaluate
+ *
+ * Return: true iff:
+ * - compression was successfully negotiated with server
+ * - server has enabled compression for the share
+ * - it's a read or write request
+ * - (write only) request length is >= SMB_COMPRESS_MIN_LEN
+ * - (write only) is_compressible() returns 1
+ *
+ * Return false otherwise.
+ */
 bool should_compress(const struct cifs_tcon *tcon, const struct smb_rqst *rq)
 {
 	const struct smb2_hdr *shdr = rq->rq_iov->iov_base;
diff --git a/fs/smb/client/compress.h b/fs/smb/client/compress.h
index f3ed1d3e52fb..d843274e2a3d 100644
--- a/fs/smb/client/compress.h
+++ b/fs/smb/client/compress.h
@@ -29,26 +29,12 @@
 #ifdef CONFIG_CIFS_COMPRESSION
 typedef int (*compress_send_fn)(struct TCP_Server_Info *, int, struct smb_rqst *);
 
-int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_send_fn send_fn);
+/* PROTOTYPES */
 
-/**
- * should_compress() - Determines if a request (write) or the response to a
- *		       request (read) should be compressed.
- * @tcon: tcon of the request is being sent to
- * @rqst: request to evaluate
- *
- * Return: true iff:
- * - compression was successfully negotiated with server
- * - server has enabled compression for the share
- * - it's a read or write request
- * - (write only) request length is >= SMB_COMPRESS_MIN_LEN
- * - (write only) is_compressible() returns 1
- *
- * Return false otherwise.
- */
+int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_send_fn send_fn);
 bool should_compress(const struct cifs_tcon *tcon, const struct smb_rqst *rq);
 
-/**
+/*
  * smb_compress_alg_valid() - Validate a compression algorithm.
  * @alg: Compression algorithm to check.
  * @valid_none: Conditional check whether NONE algorithm should be
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index f236f4e3b128..338f11a9e4ad 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -42,6 +42,7 @@
 #include "nterr.h"
 #include "rfc1002pdu.h"
 #include "fscache.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "smbdirect.h"
 #include "dns_resolve.h"
diff --git a/fs/smb/client/dfs.h b/fs/smb/client/dfs.h
index e60f0a24a8a1..21e2c9fd62e6 100644
--- a/fs/smb/client/dfs.h
+++ b/fs/smb/client/dfs.h
@@ -41,6 +41,7 @@ struct dfs_ref_walk {
 #define ref_walk_fpath(w)	(ref_walk_cur(w)->full_path)
 #define ref_walk_tl(w)		(&ref_walk_cur(w)->tl)
 #define ref_walk_ses(w)	(ref_walk_cur(w)->ses)
+/* PROTOTYPES */
 
 static inline struct dfs_ref_walk *ref_walk_alloc(void)
 {
diff --git a/fs/smb/client/dfs_cache.h b/fs/smb/client/dfs_cache.h
index 18a08a2ca93b..f311310a22fc 100644
--- a/fs/smb/client/dfs_cache.h
+++ b/fs/smb/client/dfs_cache.h
@@ -32,6 +32,7 @@ struct dfs_cache_tgt_iterator {
 	int it_path_consumed;
 	struct list_head it_list;
 };
+/* PROTOTYPES */
 
 int dfs_cache_init(void);
 void dfs_cache_destroy(void);
diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
index da5597dbf5b9..2cf0c4f1746d 100644
--- a/fs/smb/client/dir.c
+++ b/fs/smb/client/dir.c
@@ -17,6 +17,7 @@
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "smb1proto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
@@ -457,7 +458,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
 
 int
 cifs_atomic_open(struct inode *inode, struct dentry *direntry,
-		 struct file *file, unsigned oflags, umode_t mode)
+		 struct file *file, unsigned int oflags, umode_t mode)
 {
 	int rc;
 	unsigned int xid;
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 474dadeb1593..0939b91c5acc 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -27,6 +27,7 @@
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index 2a0d8b87bd8e..0a96bd9d0a16 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -505,7 +505,7 @@ cifs_parse_smb_version(struct fs_context *fc, char *value, struct smb3_fs_contex
 	case Smb_20:
 		cifs_errorf(fc, "vers=2.0 mount not permitted when legacy dialects disabled\n");
 		return 1;
-#endif /* CIFS_ALLOW_INSECURE_LEGACY */
+#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 	case Smb_21:
 		ctx->ops = &smb21_operations;
 		ctx->vals = &smb21_values;
diff --git a/fs/smb/client/fscache.h b/fs/smb/client/fscache.h
index f06cb24f5f3c..162865381dac 100644
--- a/fs/smb/client/fscache.h
+++ b/fs/smb/client/fscache.h
@@ -35,9 +35,7 @@ struct cifs_fscache_inode_coherency_data {
 
 #ifdef CONFIG_CIFS_FSCACHE
 
-/*
- * fscache.c
- */
+/* PROTOTYPES */
 extern int cifs_fscache_get_super_cookie(struct cifs_tcon *);
 extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
 
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index c2ac39d89df2..a6489517495d 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -18,6 +18,7 @@
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
diff --git a/fs/smb/client/ioctl.c b/fs/smb/client/ioctl.c
index 0a9935ce05a5..356dd46b017b 100644
--- a/fs/smb/client/ioctl.c
+++ b/fs/smb/client/ioctl.c
@@ -19,6 +19,7 @@
 #include "cifs_debug.h"
 #include "cifsfs.h"
 #include "cifs_ioctl.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "smb2glob.h"
 #include <linux/btrfs.h>
diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
index 70f3c0c67eeb..d92eb14b97dd 100644
--- a/fs/smb/client/link.c
+++ b/fs/smb/client/link.c
@@ -17,6 +17,7 @@
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "cifs_ioctl.h"
 #include "fs_context.h"
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
index 340c44dc7b5b..8967c771bdb2 100644
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -18,6 +18,7 @@
 #include "nterr.h"
 #include "cifs_unicode.h"
 #include "smb2pdu.h"
+#include "smb2proto.h"
 #include "cifsfs.h"
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dns_resolve.h"
@@ -265,7 +266,7 @@ 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
-header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
+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  */)
 {
diff --git a/fs/smb/client/netlink.h b/fs/smb/client/netlink.h
index e2fa8ed24c54..9d73b23858b8 100644
--- a/fs/smb/client/netlink.h
+++ b/fs/smb/client/netlink.h
@@ -10,6 +10,7 @@
 
 extern struct genl_family cifs_genl_family;
 
+/* PROTOTYPES */
 extern int cifs_genl_init(void);
 extern void cifs_genl_exit(void);
 
diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
index 9ec20601cee2..4e0bb1920eae 100644
--- a/fs/smb/client/netmisc.c
+++ b/fs/smb/client/netmisc.c
@@ -200,7 +200,7 @@ cifs_set_port(struct sockaddr *addr, const unsigned short int port)
 }
 
 /*****************************************************************************
-convert a NT status code to a dos class/code
+ *convert a NT status code to a dos class/code
  *****************************************************************************/
 /* NT status -> dos error map */
 static const struct {
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
index ef3b498b0a02..8af53f9b3675 100644
--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -20,6 +20,7 @@
 #include <linux/version.h>
 #include "cifsfs.h"
 #include "cifs_spnego.h"
+#include "smb1proto.h"
 #include "smb2proto.h"
 #include "fs_context.h"
 
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index a15ebd3f0d50..3af1e19e6a80 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -10,6 +10,8 @@
 #include <uapi/linux/magic.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "smb1proto.h"
+#include "smb2proto.h"
 #include "cifs_debug.h"
 #include "cifspdu.h"
 #include "cifs_unicode.h"
diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
new file mode 100644
index 000000000000..68ab0447b671
--- /dev/null
+++ b/fs/smb/client/smb1proto.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2002,2008
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ */
+#ifndef _SMB1PROTO_H
+#define _SMB1PROTO_H
+
+#include <linux/nls.h>
+#include <linux/ctype.h>
+#include "trace.h"
+#ifdef CONFIG_CIFS_DFS_UPCALL
+#include "dfs_cache.h"
+#endif
+
+/* PROTOTYPES */
+
+#endif /* _SMB1PROTO_H */
diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
index a7f629238830..66e5d6f9e3b7 100644
--- a/fs/smb/client/smb2file.c
+++ b/fs/smb/client/smb2file.c
@@ -140,7 +140,8 @@ int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec
 					 cifs_sb);
 }
 
-int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf)
+int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+		   __u32 *oplock, void *buf)
 {
 	int rc;
 	__le16 *smb2_path;
diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
index d0aad4821ed4..8f86c05d0036 100644
--- a/fs/smb/client/smb2inode.c
+++ b/fs/smb/client/smb2inode.c
@@ -21,7 +21,6 @@
 #include "cifs_unicode.h"
 #include "fscache.h"
 #include "smb2glob.h"
-#include "smb2pdu.h"
 #include "smb2proto.h"
 #include "cached_dir.h"
 #include "../common/smb2status.h"
diff --git a/fs/smb/client/smb2maperror.c b/fs/smb/client/smb2maperror.c
index 12c2b868789f..29cf456dade9 100644
--- a/fs/smb/client/smb2maperror.c
+++ b/fs/smb/client/smb2maperror.c
@@ -10,10 +10,9 @@
 #include <linux/errno.h>
 #include "cifsglob.h"
 #include "cifs_debug.h"
-#include "smb2pdu.h"
 #include "smb2proto.h"
-#include "../common/smb2status.h"
 #include "smb2glob.h"
+#include "../common/smb2status.h"
 #include "trace.h"
 
 struct status_to_posix_error {
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 549fffbca246..24cdae973d13 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -17,9 +17,9 @@
 #include <uapi/linux/magic.h>
 #include "cifsfs.h"
 #include "cifsglob.h"
-#include "smb2pdu.h"
-#include "smb2proto.h"
 #include "cifsproto.h"
+#include "smb2proto.h"
+#include "smb2pdu.h"
 #include "cifs_debug.h"
 #include "cifs_unicode.h"
 #include "../common/smb2status.h"
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index ef2c6ac500f7..5921bfe00161 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -26,8 +26,8 @@
 #include <linux/netfs.h>
 #include <trace/events/netfs.h>
 #include "cifsglob.h"
-#include "cifsacl.h"
 #include "cifsproto.h"
+#include "cifsacl.h"
 #include "smb2proto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
@@ -3913,7 +3913,8 @@ int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
 /* currently unused, as now we are doing compounding instead (see smb311_posix_query_path_info) */
 int
 SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
-		u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen)
+			u64 persistent_fid, u64 volatile_fid,
+			struct smb311_posix_qinfo *data, u32 *plen)
 {
 	size_t output_len = sizeof(struct smb311_posix_qinfo *) +
 			(sizeof(struct smb_sid) * 2) + (PATH_MAX * 2);
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 5241daaae543..dca9bc875f8d 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -9,17 +9,16 @@
  */
 #ifndef _SMB2PROTO_H
 #define _SMB2PROTO_H
+
 #include <linux/nls.h>
 #include <linux/key-type.h>
+#include "cached_dir.h"
 
 struct statfs;
 struct smb_rqst;
 
-/*
- *****************************************************************
- * All Prototypes
- *****************************************************************
- */
+/* PROTOTYPES */
+
 extern int map_smb2_to_linux_error(char *buf, bool log_err);
 extern int smb2_check_message(char *buf, unsigned int length,
 			      struct TCP_Server_Info *server);
diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h
index 577d37dbeb8a..73822800e36c 100644
--- a/fs/smb/client/smbdirect.h
+++ b/fs/smb/client/smbdirect.h
@@ -62,6 +62,8 @@ struct smbdirect_mr_io *smbd_register_mr(
 	bool writing, bool need_invalidate);
 void smbd_deregister_mr(struct smbdirect_mr_io *mr);
 
+/* PROTOTYPES */
+
 #else
 #define cifs_rdma_enabled(server)	0
 struct smbd_connection {};


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 03/11] cifs: Clean up declarations
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
  2025-11-24 12:42 ` [PATCH v4 01/11] cifs: Use netfs_alloc/free_folioq_buffer() David Howells
  2025-11-24 12:42 ` [PATCH v4 02/11] cifs: Do some preparation prior to organising the function declarations David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 04/11] cifs: Rename mid_q_entry to smb_message David Howells
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Use this script, run as "cifs_proto.pl fs/smb/client/*.[ch]" to organise
the function declarations.  Most of the declarations will be split between
cifsproto.h, smb1proto.h and smb2proto.h but with exceptions for
compress.h, fscache.h and cifs_swn.h.

The declarations are inserted into each target proto file in place of line
containing a comment of the form "/* PROTOTYPES */".  The old header
declarations are removed.  Note that this script, as it stands, cannot be
used again on its output as it inserts dividing comments to categorise the
prototypes list by source filename.

The declarations are copied from the .c file, so that the argument names
will match and ordered by appearance in the .c file.

Note that this must be applied on top of the preparatory patch otherwise it
won't work.

use strict;
unless (@ARGV) {
    die "Usage: $0 <c_file1> [<c_file2> ...]\n";
}
my $filename = "-";
my $lineno = 0;
my @proto = "";
my @smb1proto = "";
my @smb2proto = "";
my @smbdirect = "";
my @netlink = "";
my @cached_dir = "";
my @cifs_debug = "";
my @dfs = "";
my @dfs_cache = "";
my @compress = "";
my @fscache = "";
my @swn = "";
my %funcs = ();
sub error(@) {
    print STDERR $filename, ":", $lineno, ": ", @_, "\n";
    exit(1);
}
sub pad($) {
    my ($line) = @_;
    my @lines = split(/[\n]/, $line);
    return $line if ($#lines <= 0);
    for (my $i = 0; $i <= $#lines; $i++) {
	$lines[$i] =~ s/^[ \t]+//;
    }
    my $b = index($lines[0], "(");
    return $line if ($b < 0);
    my $indent = "";
    $b++;
    $indent .= "\t" x ($b / 8);
    $indent .= " " x ($b % 8);
    for (my $i = 1; $i <= $#lines; $i++) {
	$lines[$i] = $indent . $lines[$i];
    }
    my $rev = join("\n", @lines);
    return $rev;
}
foreach my $file (@ARGV) {
    # Open the file for reading.
    next if $file =~ /trace[.]h$/;
    next if $file =~ /smbdirect[.][ch]$/;
    open my $fh, "<$file"
        or die "Could not open file '$file'";
    $filename = $file;
    $lineno = 0;
    my $state = 0;
    my $qual = "";
    my $type = "";
    my $func = "";
    my $funcdef = "";
    my $bracket = 0;
    my $comment = 0;
    my $filemarker = 0;
    my $insecure = 0;
    my $header = 0;
    my $inline = 0;
    my $f_content = "";
    my $copy = "";
    my $config = "";
    $header = 1 if ($file =~ m!.h$!);
    $insecure = 1 if ($file =~ m!/smb1ops.c|/cifssmb.c|/cifstransport.c!);
    foreach my $line (<$fh>) {
        $lineno++;
        $copy .= $line;
        unless ($line) {
            $f_content .= $copy;
            $copy = "";
            next;
        }
        if ($comment) {
            $comment = 0 if ($line =~ m![*]/!);
            $f_content .= $copy;
            $copy = "";
            next;
        }
        if ($line =~ /^[#]/) {
            # if ($line =~ /ifdef.*CONFIG_CIFS_ALLOW_INSECURE_LEGACY/) {
            #   $insecure++;
            # } elsif ($line =~ /endif.*CONFIG_CIFS_ALLOW_INSECURE_LEGACY/) {
            #   $insecure--;
            # }
            if ($header) {
                if ($line =~ /ifdef.*(CONFIG_[A-Z0-9_])/) {
                    error("multiconfig") if $config;
                    $config = $1;
                    $insecure++ if ($config eq "CONFIG_CIFS_ALLOW_INSECURE_LEGACY");
                } elsif ($line =~ /endif/) {
                    $insecure-- if ($config eq "CONFIG_CIFS_ALLOW_INSECURE_LEGACY");
                    $config = "";
                }
            }
            $f_content .= $copy;
            $copy = "";
            next;
        }
        if ($line =~ /^[{]/ ||
            $line =~ /##/ ||
            $line =~ /^[_a-z0-9A-Z]+:$/ || # goto label
            $line =~ /^do [{]/ ||
            $line =~ m!^//!) {
            $f_content .= $copy;
            $copy = "";
            next;
        }
        if ($line =~ m!^/[*]!) {
            $comment = 1 unless ($line =~ m![*]/!);
            $f_content .= $copy;
            $copy = "";
            next;
        }
        if ($line =~ /^[}]/) {
                $type = "";
                $qual = "";
                $func = "";
                $funcdef = "";
                $f_content .= $copy;
                $copy = "";
                next;
        }
        if ($line =~ /^typedef/) {
            $type = "";
            $qual = "";
            $func = "";
            $funcdef = "";
            $f_content .= $copy;
            $copy = "";
            next;
        }
        if ($line =~ /^(static|extern|inline|noinline|noinline_for_stack|__always_inline)\W/) {
            error("Unexpected qualifier '$1'") if ($state != 0);
            while ($line =~ /^(static|extern|inline|noinline|noinline_for_stack|__always_inline)\W/) {
                $qual .= $1 . " ";
                $inline = 1 if ($1 eq "inline");
                $inline = 1 if ($1 eq "__always_inline");
                $line = substr($line, length($1));
                $line =~ s/^\s+//;
            }
        }
        if ($state == 0) {
            if ($line =~ /^\s/) {
                $f_content .= $copy;
                $copy = "";
                next;
            }
            while ($line =~ /^(unsigned|signed|bool|char|short|int|long|void|const|volatile|(struct|union|enum)\s+[_a-zA-Z][_a-zA-Z0-9]*|[*]|__init|__exit|__le16|__le32|__le64|__be16|__be32|__be64)/) {
                $type .= " " if $type;
                $type .= $1;
                $line = substr($line, length($1));
                $line =~ s/^\s+//;
            }
            if ($line =~ /^struct [{]/) {
                $type = "";
                $qual = "";
                $func = "";
                $funcdef = "";
                $f_content .= $copy;
                $copy = "";
                next;
            }
            if (index($line, "=") >= 0) {
                $type = "";
                $qual = "";
                $func = "";
                $funcdef = "";
                $f_content .= $copy;
                $copy = "";
                next;
            }
            while ($line =~ /(^[_a-zA-Z][_a-zA-Z0-9]*)/) {
                my $name = $1;
                $line = substr($line, length($name));
                next if ($line =~ /^[{]/);
                $line =~ s/^\s+//;
                if (substr($line, 0, 1) eq "(") {
                    $state = 1;
                    $line = substr($line, 1);
                    $func = $name;
                    $funcdef = $qual . $type . " " . $func . "(";
                    $funcdef =~ s/[*] /*/;
                    $bracket = 1;
                    last;
                } elsif (substr($line, 0, 1) eq "[") {
                    last;
                } elsif (substr($line, 0, 1) eq ";") {
                    last;
                } else {
                    if ($type) {
                        if (index($line, ";") >= 0 && index($line, "(") == -1) {
                            last;
                        }
                        error("Unexpected name '$name' after '$type'");
                    }
                    $type .= " " if $type;
                    $type .= $name;
                    if ($line =~ /^(\s*[*]+)/) {
                        my $ptr = $1;
                        $type .= $ptr;
                        $line = substr($line, length($ptr));
                    }
                }
            }
        }
        if ($state == 1) {
            my $o;
            my $c;
            while ($o = index($line, "("),
                   $c = index($line, ")"), 1) {
                my $b;
                if ($o == -1) {
                    if ($c == -1) {
                        $funcdef .= $line;
                        last;
                    } else {
                        $b = $c;
                        $bracket--;
                        unless ($bracket) {
                            $funcdef .= substr($line, 0, $b + 1);
                            $line = substr($line, $b + 1);
                            $state = 2;
                            last;
                        }
                    }
                } else {
                    $b = $o;
                    if ($c == -1) {
                        $bracket++;
                    } elsif ($c < $o) {
                        $b = $c;
                        $bracket--;
                        unless ($bracket) {
                            $funcdef .= substr($line, 0, $b + 1);
                            $line = substr($line, $b + 1);
                            $state = 2;
                            last;
                        }
                    } else {
                        $bracket++;
                    }
                }
                $funcdef .= substr($line, 0, $b);
                $line = substr($line, $b + 1);
            }
        }
        if ($state == 2) {
            $inline = 1 if ($qual =~ /inline/);
            if (!$header &&
                $qual !~ /static/ &&
                $func ne "__acquires" &&
                $func ne "__releases" &&
                $func ne "module_init" &&
                $func ne "module_exit" &&
                $func ne "module_param" &&
                $func ne "module_param_call" &&
                $func ne "PROC_FILE_DEFINE" &&
                $func !~ /MODULE_/ &&
                $func !~ /DEFINE_/) {
                my $p;
                if ($insecure) {
                    $p = \@smb1proto;
                } elsif ($file =~ m!/smb2!) {
                    $p = \@smb2proto;
                } elsif ($file =~ m!/smbdirect.c!) {
                    $p = \@smbdirect;
                } elsif ($file =~ m!/netlink.c!) {
                    $p = \@netlink;
                } elsif ($file =~ m!/compress.c!) {
                    $p = \@compress;
                } elsif ($file =~ m!/cached_dir.c!) {
                    $p = \@cached_dir;
                } elsif ($file =~ m!/cifs_debug.c!) {
                    $p = \@cifs_debug;
                } elsif ($file =~ m!/dfs_cache.c!) {
                    $p = \@dfs_cache;
                } elsif ($file =~ m!/dfs.c!) {
                    $p = \@dfs;
                } elsif ($file =~ m!/fscache.c!) {
                    $p = \@fscache;
                } elsif ($file =~ m!/cifs_swn.c!) {
                    $p = \@swn;
                } else {
                    $p = \@proto;
                }
                unless ($filemarker) {
                    my $n = $file;
                    $n =~ s!.*/!!;
                    push @{$p}, "\n/*\n * $n\n */\n";
                    $filemarker = 1;
                }
		$funcdef = pad($funcdef) . ";\n";
		if ($funcdef =~ /cifs_inval_name_dfs_link_error/) {
		    $funcdef = "#ifdef CONFIG_CIFS_DFS_UPCALL\n" . $funcdef . "#endif\n";
		} elsif ($funcdef =~ /cifs_listxattr/) {
		    $funcdef = "#ifdef CONFIG_CIFS_XATTR\n" . $funcdef . "#endif\n";
		}
                push @{$p}, $funcdef;
            } elsif (!$header || $inline) {
                $f_content .= $copy;
            }

            $funcdef = "";
            $type = "";
            $qual = "";
            $func = "";
            $inline = 0;
            $state = 0;
            $copy = "";
        }
        if ($line =~ /;/) {
            $type = "";
            $qual = "";
            $func = "";
            $funcdef = "";
            $state = 0;
            $f_content .= $copy;
            $copy = "";
        }
    }
    close($fh);
    if ($header) {
        $f_content =~ s/[\n]{3,}/\n\n/g;
        open my $fh, ">$file"
            or die "Could not open file '$file' for writing";
        print($fh $f_content) or die $file;
        close($fh) or die $file;
    }
}
sub insert_protos($$)
{
    my ($file, $protos) = @_;
    open my $fh, "<$file"
        or die "Could not open file '$file'";
    my @lines = <$fh>;
    close($fh);
    open $fh, ">$file"
        or die "Could not open file '$file' for writing";
    foreach my $line (@lines) {
        if ($line eq "/* PROTOTYPES */\n") {
            print($fh @{$protos}) or die $file;
        } else {
            print($fh $line) or die $file;
        }
    }
    close($fh) or die $file;
}
insert_protos("fs/smb/client/cifsproto.h", \@proto);
insert_protos("fs/smb/client/smb1proto.h", \@smb1proto);
insert_protos("fs/smb/client/smb2proto.h", \@smb2proto);
insert_protos("fs/smb/client/smbdirect.h", \@smbdirect);
insert_protos("fs/smb/client/netlink.h", \@netlink);
insert_protos("fs/smb/client/compress.h", \@compress);
insert_protos("fs/smb/client/cached_dir.h", \@cached_dir);
insert_protos("fs/smb/client/cifs_debug.h", \@cifs_debug);
insert_protos("fs/smb/client/dfs.h", \@dfs);
insert_protos("fs/smb/client/dfs_cache.h", \@dfs_cache);
insert_protos("fs/smb/client/fscache.h", \@fscache);
insert_protos("fs/smb/client/cifs_swn.h", \@swn);

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cached_dir.h   |   38 +-
 fs/smb/client/cifs_debug.h   |   15 +-
 fs/smb/client/cifs_spnego.h  |    2 -
 fs/smb/client/cifs_swn.h     |   17 +-
 fs/smb/client/cifs_unicode.h |   16 -
 fs/smb/client/cifsfs.h       |   64 --
 fs/smb/client/cifsglob.h     |   22 -
 fs/smb/client/cifspdu.h      |   11 -
 fs/smb/client/cifsproto.h    | 1190 ++++++++++++++++------------------
 fs/smb/client/compress.h     |    6 +-
 fs/smb/client/dfs.h          |   13 +-
 fs/smb/client/dfs_cache.h    |   10 +-
 fs/smb/client/dns_resolve.h  |    3 -
 fs/smb/client/fs_context.h   |    9 -
 fs/smb/client/fscache.h      |   15 +-
 fs/smb/client/netlink.h      |    9 +-
 fs/smb/client/nterr.h        |    2 -
 fs/smb/client/ntlmssp.h      |   13 -
 fs/smb/client/reparse.h      |   11 -
 fs/smb/client/smb1proto.h    |  212 +++++-
 fs/smb/client/smb2proto.h    |  512 +++++++--------
 fs/smb/client/smbdirect.h    |    1 -
 22 files changed, 1083 insertions(+), 1108 deletions(-)

diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index b843442db2d4..6decac9225a3 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -8,7 +8,6 @@
 #ifndef _CACHED_DIR_H
 #define _CACHED_DIR_H
 
-
 struct cached_dirent {
 	struct list_head entry;
 	char *name;
@@ -77,23 +76,24 @@ is_valid_cached_dir(struct cached_fid *cfid)
 	return cfid->time && cfid->has_lease;
 }
 
-/* PROTOTYPES */
-extern struct cached_fids *init_cached_dirs(void);
-extern void free_cached_dirs(struct cached_fids *cfids);
-extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
-			   const char *path,
-			   struct cifs_sb_info *cifs_sb,
-			   bool lookup_only, struct cached_fid **cfid);
-extern int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
-				     struct dentry *dentry,
-				     struct cached_fid **cfid);
-extern void close_cached_dir(struct cached_fid *cfid);
-extern void drop_cached_dir_by_name(const unsigned int xid,
-				    struct cifs_tcon *tcon,
-				    const char *name,
-				    struct cifs_sb_info *cifs_sb);
-extern void close_all_cached_dirs(struct cifs_sb_info *cifs_sb);
-extern void invalidate_all_cached_dirs(struct cifs_tcon *tcon);
-extern bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]);
+
+/*
+ * cached_dir.c
+ */
+int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+		    const char *path,
+		    struct cifs_sb_info *cifs_sb,
+		    bool lookup_only, struct cached_fid **ret_cfid);
+int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
+			      struct dentry *dentry,
+			      struct cached_fid **ret_cfid);
+void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
+			     const char *name, struct cifs_sb_info *cifs_sb);
+void close_cached_dir(struct cached_fid *cfid);
+void close_all_cached_dirs(struct cifs_sb_info *cifs_sb);
+void invalidate_all_cached_dirs(struct cifs_tcon *tcon);
+bool cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]);
+struct cached_fids *init_cached_dirs(void);
+void free_cached_dirs(struct cached_fids *cfids);
 
 #endif			/* _CACHED_DIR_H */
diff --git a/fs/smb/client/cifs_debug.h b/fs/smb/client/cifs_debug.h
index 526afdb33cc6..fd264c39cfbf 100644
--- a/fs/smb/client/cifs_debug.h
+++ b/fs/smb/client/cifs_debug.h
@@ -14,13 +14,19 @@
 
 #define pr_fmt(fmt) "CIFS: " fmt
 
-/* PROTOTYPES */
 
+/*
+ * cifs_debug.c
+ */
 void cifs_dump_mem(char *label, void *data, int length);
-void cifs_dump_detail(void *buf, struct TCP_Server_Info *ptcp_info);
-void cifs_dump_mids(struct TCP_Server_Info *);
+void cifs_dump_detail(void *buf, struct TCP_Server_Info *server);
+void cifs_dump_mids(struct TCP_Server_Info *server);
+void cifs_proc_init(void);
+void cifs_proc_clean(void);
+void cifs_proc_init(void);
+void cifs_proc_clean(void);
+
 extern bool traceSMB;		/* flag which enables the function below */
-void dump_smb(void *, int);
 #define CIFS_INFO	0x01
 #define CIFS_RC		0x02
 #define CIFS_TIMER	0x04
@@ -41,7 +47,6 @@ extern int cifsFYI;
  */
 #ifdef CONFIG_CIFS_DEBUG
 
-
 /*
  * When adding tracepoints and debug messages we have various choices.
  * Some considerations:
diff --git a/fs/smb/client/cifs_spnego.h b/fs/smb/client/cifs_spnego.h
index e4d751b0c812..8eb57900b9ee 100644
--- a/fs/smb/client/cifs_spnego.h
+++ b/fs/smb/client/cifs_spnego.h
@@ -29,8 +29,6 @@ struct cifs_spnego_msg {
 
 #ifdef __KERNEL__
 extern struct key_type cifs_spnego_key_type;
-extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo,
-				       struct TCP_Server_Info *server);
 #endif /* KERNEL */
 
 #endif /* _CIFS_SPNEGO_H */
diff --git a/fs/smb/client/cifs_swn.h b/fs/smb/client/cifs_swn.h
index 7063539c41c8..6d4ad7e35953 100644
--- a/fs/smb/client/cifs_swn.h
+++ b/fs/smb/client/cifs_swn.h
@@ -15,16 +15,15 @@ struct genl_info;
 
 #ifdef CONFIG_CIFS_SWN_UPCALL
 
-/* PROTOTYPES */
-extern int cifs_swn_register(struct cifs_tcon *tcon);
 
-extern int cifs_swn_unregister(struct cifs_tcon *tcon);
-
-extern int cifs_swn_notify(struct sk_buff *skb, struct genl_info *info);
-
-extern void cifs_swn_dump(struct seq_file *m);
-
-extern void cifs_swn_check(void);
+/*
+ * cifs_swn.c
+ */
+int cifs_swn_notify(struct sk_buff *skb, struct genl_info *info);
+int cifs_swn_register(struct cifs_tcon *tcon);
+int cifs_swn_unregister(struct cifs_tcon *tcon);
+void cifs_swn_dump(struct seq_file *m);
+void cifs_swn_check(void);
 
 static inline bool cifs_swn_set_server_dstaddr(struct TCP_Server_Info *server)
 {
diff --git a/fs/smb/client/cifs_unicode.h b/fs/smb/client/cifs_unicode.h
index e137a0dfbbe9..55400e7ba70b 100644
--- a/fs/smb/client/cifs_unicode.h
+++ b/fs/smb/client/cifs_unicode.h
@@ -55,22 +55,6 @@
 #define SFU_MAP_UNI_RSVD	2
 
 #ifdef __KERNEL__
-int cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
-		    const struct nls_table *cp, int map_type);
-int cifs_utf16_bytes(const __le16 *from, int maxbytes,
-		     const struct nls_table *codepage);
-int cifs_strtoUTF16(__le16 *, const char *, int, const struct nls_table *);
-char *cifs_strndup_from_utf16(const char *src, const int maxlen,
-			      const bool is_unicode,
-			      const struct nls_table *codepage);
-extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen,
-			      const struct nls_table *cp, int mapChars);
-extern int cifs_remap(struct cifs_sb_info *cifs_sb);
-extern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen,
-				     int *utf16_len, const struct nls_table *cp,
-				     int remap);
 #endif
 
-wchar_t cifs_toupper(wchar_t in);
-
 #endif /* _CIFS_UNICODE_H */
diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h
index e9534258d1ef..462be3d9e5cf 100644
--- a/fs/smb/client/cifsfs.h
+++ b/fs/smb/client/cifsfs.h
@@ -43,46 +43,14 @@ extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
 
 /* Functions related to super block operations */
-extern void cifs_sb_active(struct super_block *sb);
-extern void cifs_sb_deactive(struct super_block *sb);
 
 /* Functions related to inodes */
 extern const struct inode_operations cifs_dir_inode_ops;
-extern struct inode *cifs_root_iget(struct super_block *);
-extern int cifs_create(struct mnt_idmap *, struct inode *,
-		       struct dentry *, umode_t, bool excl);
-extern int cifs_atomic_open(struct inode *, struct dentry *,
-			    struct file *, unsigned, umode_t);
-extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
-				  unsigned int);
-extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
-extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
-extern int cifs_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
-		      umode_t, dev_t);
-extern struct dentry *cifs_mkdir(struct mnt_idmap *, struct inode *, struct dentry *,
-				 umode_t);
-extern int cifs_rmdir(struct inode *, struct dentry *);
-extern int cifs_rename2(struct mnt_idmap *, struct inode *,
-			struct dentry *, struct inode *, struct dentry *,
-			unsigned int);
-extern int cifs_revalidate_file_attr(struct file *filp);
-extern int cifs_revalidate_dentry_attr(struct dentry *);
-extern int cifs_revalidate_file(struct file *filp);
-extern int cifs_revalidate_dentry(struct dentry *);
-extern int cifs_revalidate_mapping(struct inode *inode);
-extern int cifs_zap_mapping(struct inode *inode);
-extern int cifs_getattr(struct mnt_idmap *, const struct path *,
-			struct kstat *, u32, unsigned int);
-extern int cifs_setattr(struct mnt_idmap *, struct dentry *,
-			struct iattr *);
-extern int cifs_fiemap(struct inode *, struct fiemap_extent_info *, u64 start,
-		       u64 len);
 
 extern const struct inode_operations cifs_file_inode_ops;
 extern const struct inode_operations cifs_symlink_inode_ops;
 extern const struct inode_operations cifs_namespace_inode_operations;
 
-
 /* Functions related to files and directories */
 extern const struct netfs_request_ops cifs_req_ops;
 extern const struct file_operations cifs_file_ops;
@@ -91,54 +59,22 @@ extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
 extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */
 extern const struct file_operations cifs_file_direct_nobrl_ops;
 extern const struct file_operations cifs_file_strict_nobrl_ops;
-extern int cifs_open(struct inode *inode, struct file *file);
-extern int cifs_close(struct inode *inode, struct file *file);
-extern int cifs_closedir(struct inode *inode, struct file *file);
-extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
-extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
-ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
-ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter);
-extern int cifs_flock(struct file *pfile, int cmd, struct file_lock *plock);
-extern int cifs_lock(struct file *, int, struct file_lock *);
-extern int cifs_fsync(struct file *, loff_t, loff_t, int);
-extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
-extern int cifs_flush(struct file *, fl_owner_t id);
-int cifs_file_mmap_prepare(struct vm_area_desc *desc);
-int cifs_file_strict_mmap_prepare(struct vm_area_desc *desc);
 extern const struct file_operations cifs_dir_ops;
-extern int cifs_readdir(struct file *file, struct dir_context *ctx);
 
 /* Functions related to dir entries */
 extern const struct dentry_operations cifs_dentry_ops;
 extern const struct dentry_operations cifs_ci_dentry_ops;
 
-extern struct vfsmount *cifs_d_automount(struct path *path);
-
 /* Functions related to symlinks */
-extern const char *cifs_get_link(struct dentry *, struct inode *,
-			struct delayed_call *);
-extern int cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
-			struct dentry *direntry, const char *symname);
 
 #ifdef CONFIG_CIFS_XATTR
 extern const struct xattr_handler * const cifs_xattr_handlers[];
-extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
 #else
 # define cifs_xattr_handlers NULL
 # define cifs_listxattr NULL
 #endif
 
-extern ssize_t cifs_file_copychunk_range(unsigned int xid,
-					struct file *src_file, loff_t off,
-					struct file *dst_file, loff_t destoff,
-					size_t len, unsigned int flags);
-
-extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
-extern void cifs_setsize(struct inode *inode, loff_t offset);
-
 struct smb3_fs_context;
-extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
-					 int flags, struct smb3_fs_context *ctx);
 
 #ifdef CONFIG_CIFS_NFSD_EXPORT
 extern const struct export_operations cifs_export_ops;
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index f859c5407fbc..c74df2260d6b 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1325,9 +1325,6 @@ struct tcon_link {
 	struct cifs_tcon	*tl_tcon;
 };
 
-extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
-extern void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst);
-
 static inline struct cifs_tcon *
 tlink_tcon(struct tcon_link *tlink)
 {
@@ -1340,8 +1337,6 @@ cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
 	return cifs_sb->master_tlink;
 }
 
-extern void cifs_put_tlink(struct tcon_link *tlink);
-
 static inline struct tcon_link *
 cifs_get_tlink(struct tcon_link *tlink)
 {
@@ -1351,7 +1346,6 @@ cifs_get_tlink(struct tcon_link *tlink)
 }
 
 /* This function is always expected to succeed */
-extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
 
 #define CIFS_OPLOCK_NO_CHANGE 0xfe
 
@@ -1523,16 +1517,6 @@ cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
 	++cifs_file->count;
 }
 
-struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
-void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_hdlr,
-		       bool offload);
-void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
-int cifs_file_flush(const unsigned int xid, struct inode *inode,
-		    struct cifsFileInfo *cfile);
-int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
-		       const char *full_path, struct cifsFileInfo *open_file,
-		       loff_t size);
-
 #define CIFS_CACHE_READ_FLG	1
 #define CIFS_CACHE_HANDLE_FLG	2
 #define CIFS_CACHE_RH_FLG	(CIFS_CACHE_READ_FLG | CIFS_CACHE_HANDLE_FLG)
@@ -1646,7 +1630,6 @@ static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
 	spin_unlock(&tcon->stat_lock);
 }
 
-
 /*
  * This is the prototype for the mid receive function. This function is for
  * receiving the rest of the SMB frame, starting with the WordCount (which is
@@ -1853,7 +1836,6 @@ static inline bool is_replayable_error(int error)
 	return false;
 }
 
-
 /* cifs_get_writable_file() flags */
 enum cifs_writable_file_flags {
 	FIND_WR_ANY			= 0U,
@@ -2088,10 +2070,6 @@ extern unsigned int dir_cache_timeout; /* max time for directory lease caching o
 extern bool disable_legacy_dialects;  /* forbid vers=1.0 and vers=2.0 mounts */
 extern atomic_t mid_count;
 
-void cifs_oplock_break(struct work_struct *work);
-void cifs_queue_oplock_break(struct cifsFileInfo *cfile);
-void smb2_deferred_work_close(struct work_struct *work);
-
 extern const struct slow_work_ops cifs_oplock_break_ops;
 extern struct workqueue_struct *cifsiod_wq;
 extern struct workqueue_struct *decrypt_wq;
diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
index 49f35cb3cf2e..19a463d55fbf 100644
--- a/fs/smb/client/cifspdu.h
+++ b/fs/smb/client/cifspdu.h
@@ -577,10 +577,8 @@ struct ntlmv2_resp {
 	/* array of name entries could follow ending in minimum 4 byte struct */
 } __packed;
 
-
 #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
 
-
 /*
  * Capabilities bits (for NTLM SessSetup request)
  * See MS-CIFS 2.2.4.52.2
@@ -636,7 +634,6 @@ typedef struct smb_com_tconx_rsp_ext {
 	/* STRING NativeFileSystem */
 } __packed TCONX_RSP_EXT;
 
-
 /* tree connect Flags */
 #define DISCONNECT_TID          0x0001
 #define TCON_EXTENDED_SIGNATURES 0x0004
@@ -836,7 +833,6 @@ typedef struct smb_com_open_rsp_ext {
 	__u16 ByteCount;        /* bct = 0 */
 } __packed OPEN_RSP_EXT;
 
-
 /* format of legacy open request */
 typedef struct smb_com_openx_req {
 	struct smb_hdr	hdr;	/* wct = 15 */
@@ -1293,7 +1289,6 @@ typedef struct smb_com_transaction_qsec_req {
 	__le32 AclFlags;
 } __packed QUERY_SEC_DESC_REQ;
 
-
 typedef struct smb_com_transaction_ssec_req {
 	struct smb_hdr hdr;     /* wct = 19 */
 	__u8 MaxSetupCount;
@@ -1488,7 +1483,6 @@ struct smb_t2_rsp {
 #define SMB_QUERY_FILE_MODE_INFO        0x3f8
 #define SMB_QUERY_FILE_ALGN_INFO        0x3f9
 
-
 #define SMB_SET_FILE_BASIC_INFO	        0x101
 #define SMB_SET_FILE_DISPOSITION_INFO   0x102
 #define SMB_SET_FILE_ALLOCATION_INFO    0x103
@@ -2031,7 +2025,6 @@ typedef struct {
 #define CIFS_UNIX_CAP_MASK              0x00000013
 #endif /* CONFIG_CIFS_POSIX */
 
-
 #define CIFS_POSIX_EXTENSIONS           0x00000010 /* support for new QFSInfo */
 
 /* DeviceType Flags */
@@ -2103,7 +2096,6 @@ typedef struct {
 	__u16 Pad;
 } __packed FILE_STANDARD_INFO;	/* level 0x102 QPathInfo */
 
-
 /* defines for enumerating possible values of the Unix type field below */
 #define UNIX_FILE      0
 #define UNIX_DIR       1
@@ -2278,7 +2270,6 @@ struct file_attrib_tag {
 	__le32 ReparseTag;
 } __packed;      /* level 0x40b */
 
-
 /********************************************************/
 /*  FindFirst/FindNext transact2 data buffer formats    */
 /********************************************************/
@@ -2308,7 +2299,6 @@ typedef struct {
 	char FileName[];
 } __packed FIND_FILE_STANDARD_INFO; /* level 0x1 FF resp data */
 
-
 struct fea {
 	unsigned char EA_flags;
 	__u8 name_len;
@@ -2331,7 +2321,6 @@ struct data_blob {
 	void (*free) (struct data_blob *data_blob);
 } __packed;
 
-
 #ifdef CONFIG_CIFS_POSIX
 /*
 	For better POSIX semantics from Linux client, (even better
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index aaa9e4f70f79..16b9ad555793 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -19,20 +19,562 @@ struct statfs;
 struct smb_rqst;
 struct smb3_fs_context;
 
-/* PROTOTYPES */
-
-extern struct smb_hdr *cifs_buf_get(void);
-extern void cifs_buf_release(void *);
-extern struct smb_hdr *cifs_small_buf_get(void);
-extern void cifs_small_buf_release(void *);
-extern void free_rsp_buf(int, void *);
-extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
-			unsigned int /* length */);
-extern int smb_send_kvec(struct TCP_Server_Info *server,
-			 struct msghdr *msg,
-			 size_t *sent);
-extern unsigned int _get_xid(void);
-extern void _free_xid(unsigned int);
+
+/*
+ * asn1.c
+ */
+int decode_negTokenInit(unsigned char *security_blob, int length,
+			struct TCP_Server_Info *server);
+int cifs_gssapi_this_mech(void *context, size_t hdrlen,
+			  unsigned char tag, const void *value, size_t vlen);
+int cifs_neg_token_init_mech_type(void *context, size_t hdrlen,
+				  unsigned char tag,
+				  const void *value, size_t vlen);
+
+/*
+ * cifsacl.c
+ */
+int sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
+	      struct cifs_fattr *fattr, uint sidtype);
+int init_cifs_idmap(void);
+void exit_cifs_idmap(void);
+unsigned int setup_authusers_ACE(struct smb_ace *pntace);
+unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
+				    bool posix,
+				    __u64 nmode);
+unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace);
+struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
+				     const struct cifs_fid *cifsfid, u32 *pacllen,
+				     u32 info);
+struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+			      struct inode *inode, const char *path,
+			      u32 *pacllen, u32 info);
+int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
+		 struct inode *inode, const char *path, int aclflag);
+int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
+		      struct inode *inode, bool mode_from_special_sid,
+		      const char *path, const struct cifs_fid *pfid);
+int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
+			kuid_t uid, kgid_t gid);
+struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
+			       struct dentry *dentry, int type);
+int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+		 struct posix_acl *acl, int type);
+
+/*
+ * cifsencrypt.c
+ */
+int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+			  char *signature, struct cifs_calc_sig_ctx *ctx);
+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,
+		  __u32 *pexpected_response_sequence_number);
+int cifs_verify_signature(struct smb_rqst *rqst,
+			  struct TCP_Server_Info *server,
+			  __u32 expected_sequence_number);
+int setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp);
+int calc_seckey(struct cifs_ses *ses);
+void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
+
+/*
+ * cifsfs.c
+ */
+void cifs_sb_active(struct super_block *sb);
+void cifs_sb_deactive(struct super_block *sb);
+struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
+				  int flags, struct smb3_fs_context *old_ctx);
+const char *cifs_get_link(struct dentry *dentry, struct inode *inode,
+			  struct delayed_call *done);
+ssize_t cifs_file_copychunk_range(unsigned int xid,
+				  struct file *src_file, loff_t off,
+				  struct file *dst_file, loff_t destoff,
+				  size_t len, unsigned int flags);
+
+/*
+ * cifsroot.c
+ */
+int __init cifs_root_data(char **dev, char **opts);
+
+/*
+ * cifs_spnego.c
+ */
+struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo,
+				struct TCP_Server_Info *server);
+int init_cifs_spnego(void);
+void exit_cifs_spnego(void);
+
+/*
+ * cifs_unicode.c
+ */
+int cifs_remap(struct cifs_sb_info *cifs_sb);
+int cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
+		    const struct nls_table *codepage, int map_type);
+int cifs_strtoUTF16(__le16 *to, const char *from, int len,
+		    const struct nls_table *codepage);
+int cifs_utf16_bytes(const __le16 *from, int maxbytes,
+		     const struct nls_table *codepage);
+char *cifs_strndup_from_utf16(const char *src, const int maxlen,
+			      const bool is_unicode, const struct nls_table *codepage);
+int cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
+		       const struct nls_table *cp, int map_chars);
+__le16 *cifs_strndup_to_utf16(const char *src, const int maxlen, int *utf16_len,
+			      const struct nls_table *cp, int remap);
+
+/*
+ * connect.c
+ */
+void smb2_query_server_interfaces(struct work_struct *work);
+void cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
+				     bool all_channels);
+void cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
+					   bool mark_smb_session);
+int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session);
+int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
+			  unsigned int to_read);
+ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read);
+int cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter,
+			       unsigned int to_read);
+void dequeue_mid(struct mid_q_entry *mid, bool malformed);
+int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
+int cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid);
+int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs);
+bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
+struct TCP_Server_Info *cifs_find_tcp_session(struct smb3_fs_context *ctx);
+void cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect);
+struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx,
+					     struct TCP_Server_Info *primary_server);
+struct cifs_tcon *cifs_setup_ipc(struct cifs_ses *ses, bool seal);
+void __cifs_put_smb_ses(struct cifs_ses *ses);
+struct cifs_ses *cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
+void cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);
+void cifs_put_tlink(struct tcon_link *tlink);
+int cifs_match_super(struct super_block *sb, void *data);
+void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
+			  struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
+int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb);
+void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx);
+int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx);
+int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx);
+int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx);
+int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
+int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
+int CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+	     const char *tree, struct cifs_tcon *tcon,
+	     const struct nls_table *nls_codepage);
+void cifs_umount(struct cifs_sb_info *cifs_sb);
+int cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses,
+			    struct TCP_Server_Info *server);
+int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
+		       struct TCP_Server_Info *server,
+		       struct nls_table *nls_info);
+struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
+struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
+int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon);
+
+/*
+ * dir.c
+ */
+char *cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb,
+			      struct cifs_tcon *tcon, int add_treename);
+const char *build_path_from_dentry(struct dentry *direntry, void *page);
+char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
+					       const char *tree, int tree_len,
+					       bool prefix);
+char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
+					     bool prefix);
+int cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+		     struct file *file, unsigned int oflags, umode_t mode);
+int cifs_create(struct mnt_idmap *idmap, struct inode *inode,
+		struct dentry *direntry, umode_t mode, bool excl);
+int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode,
+	       struct dentry *direntry, umode_t mode, dev_t device_number);
+struct dentry *cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
+			   unsigned int flags);
+
+/*
+ * dns_resolve.c
+ */
+int dns_resolve_name(const char *dom, const char *name,
+		     size_t namelen, struct sockaddr *ip_addr);
+
+/*
+ * file.c
+ */
+void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
+int cifs_posix_open(const char *full_path, struct inode **pinode,
+		    struct super_block *sb, int mode, unsigned int f_flags,
+		    __u32 *poplock, __u16 *pnetfid, unsigned int xid);
+void cifs_down_write(struct rw_semaphore *sem);
+void serverclose_work(struct work_struct *work);
+struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+				       struct tcon_link *tlink, __u32 oplock,
+				       const char *symlink_target);
+struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
+void serverclose_work(struct work_struct *work);
+void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
+void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,
+		       bool wait_oplock_handler, bool offload);
+int cifs_file_flush(const unsigned int xid, struct inode *inode,
+		    struct cifsFileInfo *cfile);
+int cifs_open(struct inode *inode, struct file *file);
+void smb2_deferred_work_close(struct work_struct *work);
+int cifs_close(struct inode *inode, struct file *file);
+void cifs_reopen_persistent_handles(struct cifs_tcon *tcon);
+int cifs_closedir(struct inode *inode, struct file *file);
+void cifs_del_lock_waiters(struct cifsLockInfo *lock);
+bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
+			     __u8 type, __u16 flags,
+			     struct cifsLockInfo **conf_lock, int rw_check);
+int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
+void cifs_move_llist(struct list_head *source, struct list_head *dest);
+int cifs_get_hardlink_path(struct cifs_tcon *tcon, struct inode *inode,
+			   struct file *file);
+void cifs_free_llist(struct list_head *llist);
+int cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
+		      unsigned int xid);
+int cifs_flock(struct file *file, int cmd, struct file_lock *fl);
+int cifs_lock(struct file *file, int cmd, struct file_lock *flock);
+void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result);
+struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
+					bool fsuid_only);
+int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
+			   struct cifsFileInfo **ret_file);
+struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, int flags);
+int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
+			   int flags,
+			   struct cifsFileInfo **ret_file);
+int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
+			   struct cifsFileInfo **ret_file);
+int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
+		      int datasync);
+int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
+int cifs_flush(struct file *file, fl_owner_t id);
+ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
+ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter);
+ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
+ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
+int cifs_file_strict_mmap_prepare(struct vm_area_desc *desc);
+int cifs_file_mmap_prepare(struct vm_area_desc *desc);
+bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,
+			    bool from_readdir);
+void cifs_oplock_break(struct work_struct *work);
+
+/*
+ * fs_context.c
+ */
+int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
+int smb3_parse_opt(const char *options, const char *key, char **val);
+char *cifs_sanitize_prepath(char *prepath, gfp_t gfp);
+char *smb3_fs_context_fullpath(const struct smb3_fs_context *ctx, char dirsep);
+int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx);
+int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
+int smb3_init_fs_context(struct fs_context *fc);
+void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx);
+void smb3_cleanup_fs_context(struct smb3_fs_context *ctx);
+void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
+
+/*
+ * inode.c
+ */
+int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
+			bool from_readdir);
+void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
+void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
+			      struct cifs_sb_info *cifs_sb);
+int cifs_get_inode_info_unix(struct inode **pinode,
+			     const unsigned char *full_path,
+			     struct super_block *sb, unsigned int xid);
+int cifs_get_inode_info_unix(struct inode **pinode,
+			     const unsigned char *full_path,
+			     struct super_block *sb, unsigned int xid);
+umode_t wire_mode_to_posix(u32 wire, bool is_dir);
+int cifs_get_inode_info(struct inode **inode,
+			const char *full_path,
+			struct cifs_open_info_data *data,
+			struct super_block *sb, int xid,
+			const struct cifs_fid *fid);
+int smb311_posix_get_inode_info(struct inode **inode,
+				const char *full_path,
+				struct cifs_open_info_data *data,
+				struct super_block *sb,
+				const unsigned int xid);
+struct inode *cifs_iget(struct super_block *sb, struct cifs_fattr *fattr);
+struct inode *cifs_root_iget(struct super_block *sb);
+int cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
+		       const char *full_path, __u32 dosattr);
+int cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
+			       const unsigned int xid);
+int cifs_unlink(struct inode *dir, struct dentry *dentry);
+struct dentry *cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
+			  struct dentry *direntry, umode_t mode);
+int cifs_rmdir(struct inode *inode, struct dentry *direntry);
+int cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
+		 struct dentry *source_dentry, struct inode *target_dir,
+		 struct dentry *target_dentry, unsigned int flags);
+int cifs_revalidate_mapping(struct inode *inode);
+int cifs_zap_mapping(struct inode *inode);
+int cifs_revalidate_file_attr(struct file *filp);
+int cifs_revalidate_dentry_attr(struct dentry *dentry);
+int cifs_revalidate_file(struct file *filp);
+int cifs_revalidate_dentry(struct dentry *dentry);
+int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,
+		 struct kstat *stat, u32 request_mask, unsigned int flags);
+int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start,
+		u64 len);
+void cifs_setsize(struct inode *inode, loff_t offset);
+int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
+		       const char *full_path, struct cifsFileInfo *open_file,
+		       loff_t size);
+int cifs_setattr(struct mnt_idmap *idmap, struct dentry *direntry,
+		 struct iattr *attrs);
+
+/*
+ * ioctl.c
+ */
+long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg);
+
+/*
+ * link.c
+ */
+bool couldbe_mf_symlink(const struct cifs_fattr *fattr);
+int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+		     struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
+		     const unsigned char *path);
+int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+			  struct cifs_sb_info *cifs_sb, const unsigned char *path,
+			  char *pbuf, unsigned int *pbytes_read);
+int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+			   struct cifs_sb_info *cifs_sb, const unsigned char *path,
+			   char *pbuf, unsigned int *pbytes_written);
+int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+			  struct cifs_sb_info *cifs_sb, const unsigned char *path,
+			  char *pbuf, unsigned int *pbytes_read);
+int smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+			   struct cifs_sb_info *cifs_sb, const unsigned char *path,
+			   char *pbuf, unsigned int *pbytes_written);
+int cifs_hardlink(struct dentry *old_file, struct inode *inode,
+		  struct dentry *direntry);
+int cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
+		 struct dentry *direntry, const char *symname);
+
+/*
+ * misc.c
+ */
+unsigned int _get_xid(void);
+void _free_xid(unsigned int xid);
+struct cifs_ses *sesInfoAlloc(void);
+void sesInfoFree(struct cifs_ses *buf_to_free);
+struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled, enum smb3_tcon_ref_trace trace);
+void tconInfoFree(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);
+struct smb_hdr *cifs_buf_get(void);
+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);
+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);
+void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
+int cifs_get_writer(struct cifsInodeInfo *cinode);
+void cifs_put_writer(struct cifsInodeInfo *cinode);
+void cifs_queue_oplock_break(struct cifsFileInfo *cfile);
+void cifs_done_oplock_break(struct cifsInodeInfo *cinode);
+bool backup_cred(struct cifs_sb_info *cifs_sb);
+void cifs_del_pending_open(struct cifs_pending_open *open);
+void cifs_add_pending_open_locked(struct cifs_fid *fid, struct tcon_link *tlink,
+				  struct cifs_pending_open *open);
+void cifs_add_pending_open(struct cifs_fid *fid, struct tcon_link *tlink,
+			   struct cifs_pending_open *open);
+bool cifs_is_deferred_close(struct cifsFileInfo *cfile, struct cifs_deferred_close **pdclose);
+void cifs_add_deferred_close(struct cifsFileInfo *cfile, struct cifs_deferred_close *dclose);
+void cifs_del_deferred_close(struct cifsFileInfo *cfile);
+void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
+void cifs_close_all_deferred_files(struct cifs_tcon *tcon);
+void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon,
+					   struct dentry *dentry);
+void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
+					     const char *path);
+int parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
+			unsigned int *num_of_nodes,
+			struct dfs_info3_param **target_nodes,
+			const struct nls_table *nls_codepage, int remap,
+			const char *searchName, bool is_unicode);
+int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
+void cifs_free_hash(struct shash_desc **sdesc);
+void extract_unc_hostname(const char *unc, const char **h, size_t *len);
+int copy_path_name(char *dst, const char *src);
+struct super_block *cifs_get_dfs_tcon_super(struct cifs_tcon *tcon);
+void cifs_put_tcp_super(struct super_block *sb);
+int match_target_ip(struct TCP_Server_Info *server,
+		    const char *host, size_t hostlen,
+		    bool *result);
+int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix);
+#ifdef CONFIG_CIFS_DFS_UPCALL
+int cifs_inval_name_dfs_link_error(const unsigned int xid,
+				   struct cifs_tcon *tcon,
+				   struct cifs_sb_info *cifs_sb,
+				   const char *full_path,
+				   bool *islink);
+#endif
+int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry);
+
+/*
+ * namespace.c
+ */
+void cifs_release_automount_timer(void);
+char *cifs_build_devname(char *nodename, const char *prepath);
+struct vfsmount *cifs_d_automount(struct path *path);
+
+/*
+ * netmisc.c
+ */
+int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
+void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
+int map_smb_to_linux_error(char *buf, bool logErr);
+int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr);
+unsigned int smbCalcSize(void *buf);
+struct timespec64 cifs_NTtimeToUnix(__le64 ntutc);
+u64 cifs_UnixTimeToNT(struct timespec64 t);
+struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset);
+
+/*
+ * readdir.c
+ */
+void cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
+			    struct cifs_sb_info *cifs_sb);
+int cifs_readdir(struct file *file, struct dir_context *ctx);
+
+/*
+ * reparse.c
+ */
+int create_reparse_symlink(const unsigned int xid, struct inode *inode,
+			   struct dentry *dentry, struct cifs_tcon *tcon,
+			   const char *full_path, const char *symname);
+int mknod_reparse(unsigned int xid, struct inode *inode,
+		  struct dentry *dentry, struct cifs_tcon *tcon,
+		  const char *full_path, umode_t mode, dev_t dev);
+int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
+			      bool relative,
+			      const char *full_path,
+			      struct cifs_sb_info *cifs_sb);
+int parse_reparse_point(struct reparse_data_buffer *buf,
+			u32 plen, struct cifs_sb_info *cifs_sb,
+			const char *full_path,
+			struct cifs_open_info_data *data);
+struct reparse_data_buffer *smb2_get_reparse_point_buffer(const struct kvec *rsp_iov,
+							  u32 *plen);
+bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
+				 struct cifs_fattr *fattr,
+				 struct cifs_open_info_data *data);
+
+/*
+ * sess.c
+ */
+bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface);
+int cifs_ses_get_chan_index(struct cifs_ses *ses,
+			    struct TCP_Server_Info *server);
+void cifs_chan_set_in_reconnect(struct cifs_ses *ses,
+				struct TCP_Server_Info *server);
+void cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
+				  struct TCP_Server_Info *server);
+void cifs_chan_set_need_reconnect(struct cifs_ses *ses,
+				  struct TCP_Server_Info *server);
+void cifs_chan_clear_need_reconnect(struct cifs_ses *ses,
+				    struct TCP_Server_Info *server);
+bool cifs_chan_needs_reconnect(struct cifs_ses *ses,
+			       struct TCP_Server_Info *server);
+bool cifs_chan_is_iface_active(struct cifs_ses *ses,
+			       struct TCP_Server_Info *server);
+int cifs_try_adding_channels(struct cifs_ses *ses);
+void cifs_disable_secondary_channels(struct cifs_ses *ses);
+void cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
+int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
+			     struct cifs_ses *ses);
+int build_ntlmssp_negotiate_blob(unsigned char **pbuffer,
+				 u16 *buflen,
+				 struct cifs_ses *ses,
+				 struct TCP_Server_Info *server,
+				 const struct nls_table *nls_cp);
+int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer,
+				      u16 *buflen,
+				      struct cifs_ses *ses,
+				      struct TCP_Server_Info *server,
+				      const struct nls_table *nls_cp);
+int build_ntlmssp_auth_blob(unsigned char **pbuffer,
+			    u16 *buflen,
+			    struct cifs_ses *ses,
+			    struct TCP_Server_Info *server,
+			    const struct nls_table *nls_cp);
+enum securityEnum cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested);
+int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
+		   struct TCP_Server_Info *server,
+		   const struct nls_table *nls_cp);
+
+/*
+ * smbencrypt.c
+ */
+int E_md4hash(const unsigned char *passwd, unsigned char *p16,
+	      const struct nls_table *codepage);
+
+/*
+ * transport.c
+ */
+void cifs_wake_up_task(struct mid_q_entry *mid);
+void __release_mid(struct kref *refcount);
+void delete_mid(struct mid_q_entry *mid);
+int smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
+		  size_t *sent);
+unsigned long smb_rqst_len(struct TCP_Server_Info *server, struct smb_rqst *rqst);
+int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
+		    struct smb_rqst *rqst);
+int wait_for_free_request(struct TCP_Server_Info *server, const int flags,
+			  unsigned int *instance);
+int cifs_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
+			  size_t *num, struct cifs_credits *credits);
+int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ);
+int cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
+		    mid_receive_t *receive, mid_callback_t *callback,
+		    mid_handle_t *handle, void *cbdata, const int flags,
+		    const struct cifs_credits *exist_credits);
+int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server);
+struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
+int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
+		       struct TCP_Server_Info *server,
+		       const int flags, const int num_rqst, struct smb_rqst *rqst,
+		       int *resp_buf_type, struct kvec *resp_iov);
+int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
+		   struct TCP_Server_Info *server,
+		   struct smb_rqst *rqst, int *resp_buf_type, const int flags,
+		   struct kvec *resp_iov);
+int cifs_discard_remaining_data(struct TCP_Server_Info *server);
+int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
+
+/*
+ * unc.c
+ */
+char *extract_hostname(const char *unc);
+char *extract_sharename(const char *unc);
+
+/*
+ * winucase.c
+ */
+wchar_t cifs_toupper(wchar_t in);
+wchar_t cifs_toupper(wchar_t in);
+
+/*
+ * xattr.c
+ */
+#ifdef CONFIG_CIFS_XATTR
+ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size);
+#endif
+
 #define get_xid()							\
 ({									\
 	unsigned int __xid = _get_xid();				\
@@ -53,16 +595,6 @@ do {									\
 	else								\
 		trace_smb3_exit_done(curr_xid, __func__);		\
 } while (0)
-extern int init_cifs_idmap(void);
-extern void exit_cifs_idmap(void);
-extern int init_cifs_spnego(void);
-extern void exit_cifs_spnego(void);
-extern const char *build_path_from_dentry(struct dentry *, void *);
-char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
-					       const char *tree, int tree_len,
-					       bool prefix);
-extern char *build_path_from_dentry_optional_prefix(struct dentry *direntry,
-						    void *page, bool prefix);
 static inline void *alloc_dentry_path(void)
 {
 	return __getname();
@@ -74,61 +606,6 @@ static inline void free_dentry_path(void *page)
 		__putname(page);
 }
 
-extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
-				     struct cifs_sb_info *cifs_sb,
-				     struct cifs_tcon *tcon,
-				     int add_treename);
-extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
-char *cifs_build_devname(char *nodename, const char *prepath);
-extern void delete_mid(struct mid_q_entry *mid);
-void __release_mid(struct kref *refcount);
-extern void cifs_wake_up_task(struct mid_q_entry *mid);
-extern int cifs_handle_standard(struct TCP_Server_Info *server,
-				struct mid_q_entry *mid);
-extern char *smb3_fs_context_fullpath(const struct smb3_fs_context *ctx,
-				      char dirsep);
-extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx);
-extern int smb3_parse_opt(const char *options, const char *key, char **val);
-extern int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs);
-extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
-extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
-extern int cifs_call_async(struct TCP_Server_Info *server,
-			struct smb_rqst *rqst,
-			mid_receive_t *receive, mid_callback_t *callback,
-			mid_handle_t *handle, void *cbdata, const int flags,
-			const struct cifs_credits *exist_credits);
-extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
-extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
-			  struct TCP_Server_Info *server,
-			  struct smb_rqst *rqst, int *resp_buf_type,
-			  const int flags, struct kvec *resp_iov);
-extern int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
-			      struct TCP_Server_Info *server,
-			      const int flags, const int num_rqst,
-			      struct smb_rqst *rqst, int *resp_buf_type,
-			      struct kvec *resp_iov);
-extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
-			struct smb_hdr * /* input */ ,
-			struct smb_hdr * /* out */ ,
-			int * /* bytes returned */ , const int);
-extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
-			    char *in_buf, int flags);
-int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server);
-extern struct mid_q_entry *cifs_setup_request(struct cifs_ses *,
-				struct TCP_Server_Info *,
-				struct smb_rqst *);
-extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *,
-						struct smb_rqst *);
-int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
-		    struct smb_rqst *rqst);
-extern int cifs_check_receive(struct mid_q_entry *mid,
-			struct TCP_Server_Info *server, bool log_error);
-int wait_for_free_request(struct TCP_Server_Info *server, const int flags,
-			  unsigned int *instance);
-extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server,
-				 size_t size, size_t *num,
-				 struct cifs_credits *credits);
-
 static inline int
 send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 	    struct mid_q_entry *mid)
@@ -137,299 +614,6 @@ send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 				server->ops->send_cancel(server, rqst, mid) : 0;
 }
 
-int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ);
-extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
-			struct kvec *, int /* nvec to send */,
-			int * /* type of buf returned */, const int flags,
-			struct kvec * /* resp vec */);
-extern int SendReceiveBlockingLock(const unsigned int xid,
-			struct cifs_tcon *ptcon,
-			struct smb_hdr *in_buf,
-			struct smb_hdr *out_buf,
-			int *bytes_returned);
-
-void smb2_query_server_interfaces(struct work_struct *work);
-void
-cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
-				      bool all_channels);
-void
-cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
-				      bool mark_smb_session);
-extern int cifs_reconnect(struct TCP_Server_Info *server,
-			  bool mark_smb_session);
-extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr);
-extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
-extern bool backup_cred(struct cifs_sb_info *);
-extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
-				   bool from_readdir);
-extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
-			    unsigned int bytes_written);
-void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result);
-extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
-extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
-				  int flags,
-				  struct cifsFileInfo **ret_file);
-extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
-				  int flags,
-				  struct cifsFileInfo **ret_file);
-extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
-				  struct cifsFileInfo **ret_file);
-extern int cifs_get_hardlink_path(struct cifs_tcon *tcon, struct inode *inode,
-				  struct file *file);
-extern unsigned int smbCalcSize(void *buf);
-extern int decode_negTokenInit(unsigned char *security_blob, int length,
-			struct TCP_Server_Info *server);
-extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
-extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
-extern int map_smb_to_linux_error(char *buf, bool logErr);
-extern int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr);
-extern void header_assemble(struct smb_hdr *, char /* command */ ,
-			    const struct cifs_tcon *, int /* length of
-			    fixed section (word count) in two byte units */);
-extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
-				struct cifs_ses *ses,
-				void **request_buf);
-extern enum securityEnum select_sectype(struct TCP_Server_Info *server,
-				enum securityEnum requested);
-extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
-			  struct TCP_Server_Info *server,
-			  const struct nls_table *nls_cp);
-extern struct timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
-extern u64 cifs_UnixTimeToNT(struct timespec64);
-extern struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
-				      int offset);
-extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
-extern int cifs_get_writer(struct cifsInodeInfo *cinode);
-extern void cifs_put_writer(struct cifsInodeInfo *cinode);
-extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode);
-extern int cifs_unlock_range(struct cifsFileInfo *cfile,
-			     struct file_lock *flock, const unsigned int xid);
-extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
-
-extern void cifs_down_write(struct rw_semaphore *sem);
-struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
-				       struct tcon_link *tlink, __u32 oplock,
-				       const char *symlink_target);
-extern int cifs_posix_open(const char *full_path, struct inode **inode,
-			   struct super_block *sb, int mode,
-			   unsigned int f_flags, __u32 *oplock, __u16 *netfid,
-			   unsigned int xid);
-void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
-extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
-				     FILE_UNIX_BASIC_INFO *info,
-				     struct cifs_sb_info *cifs_sb);
-extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
-					struct cifs_sb_info *);
-extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
-			       bool from_readdir);
-extern struct inode *cifs_iget(struct super_block *sb,
-			       struct cifs_fattr *fattr);
-
-int cifs_get_inode_info(struct inode **inode, const char *full_path,
-			struct cifs_open_info_data *data, struct super_block *sb, int xid,
-			const struct cifs_fid *fid);
-extern int smb311_posix_get_inode_info(struct inode **inode,
-				       const char *full_path,
-				       struct cifs_open_info_data *data,
-				       struct super_block *sb,
-				       const unsigned int xid);
-extern int cifs_get_inode_info_unix(struct inode **pinode,
-			const unsigned char *search_path,
-			struct super_block *sb, unsigned int xid);
-extern int cifs_set_file_info(struct inode *inode, struct iattr *attrs,
-			      unsigned int xid, const char *full_path, __u32 dosattr);
-extern int cifs_rename_pending_delete(const char *full_path,
-				      struct dentry *dentry,
-				      const unsigned int xid);
-extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
-				struct cifs_fattr *fattr, uint sidtype);
-extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
-			      struct cifs_fattr *fattr, struct inode *inode,
-			      bool get_mode_from_special_sid,
-			      const char *path, const struct cifs_fid *pfid);
-extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
-					kuid_t uid, kgid_t gid);
-extern struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifssmb, struct inode *ino,
-				      const char *path, u32 *plen, u32 info);
-extern struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifssb,
-				const struct cifs_fid *pfid, u32 *plen, u32 info);
-extern struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
-				      struct dentry *dentry, int type);
-extern int cifs_set_acl(struct mnt_idmap *idmap,
-			struct dentry *dentry, struct posix_acl *acl, int type);
-extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino,
-				const char *path, int flag);
-extern unsigned int setup_authusers_ACE(struct smb_ace *pace);
-extern unsigned int setup_special_mode_ACE(struct smb_ace *pace,
-					   bool posix,
-					   __u64 nmode);
-extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace);
-
-extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
-extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
-			         unsigned int to_read);
-extern ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server,
-					size_t to_read);
-int cifs_read_iter_from_socket(struct TCP_Server_Info *server,
-			       struct iov_iter *iter,
-			       unsigned int to_read);
-extern int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb);
-void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx);
-int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx);
-int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx);
-int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx);
-extern int cifs_match_super(struct super_block *, void *);
-extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
-extern void cifs_umount(struct cifs_sb_info *);
-extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
-extern void cifs_reopen_persistent_handles(struct cifs_tcon *tcon);
-
-extern bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset,
-				    __u64 length, __u8 type, __u16 flags,
-				    struct cifsLockInfo **conf_lock,
-				    int rw_check);
-extern void cifs_add_pending_open(struct cifs_fid *fid,
-				  struct tcon_link *tlink,
-				  struct cifs_pending_open *open);
-extern void cifs_add_pending_open_locked(struct cifs_fid *fid,
-					 struct tcon_link *tlink,
-					 struct cifs_pending_open *open);
-extern void cifs_del_pending_open(struct cifs_pending_open *open);
-
-extern bool cifs_is_deferred_close(struct cifsFileInfo *cfile,
-				struct cifs_deferred_close **dclose);
-
-extern void cifs_add_deferred_close(struct cifsFileInfo *cfile,
-				struct cifs_deferred_close *dclose);
-
-extern void cifs_del_deferred_close(struct cifsFileInfo *cfile);
-
-extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
-
-extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
-
-void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
-					   struct dentry *dentry);
-
-extern void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
-				const char *path);
-
-extern struct TCP_Server_Info *
-cifs_get_tcp_session(struct smb3_fs_context *ctx,
-		     struct TCP_Server_Info *primary_server);
-extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
-				 int from_reconnect);
-extern void cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);
-
-extern void cifs_release_automount_timer(void);
-
-void cifs_proc_init(void);
-void cifs_proc_clean(void);
-
-extern void cifs_move_llist(struct list_head *source, struct list_head *dest);
-extern void cifs_free_llist(struct list_head *llist);
-extern void cifs_del_lock_waiters(struct cifsLockInfo *lock);
-
-int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon);
-
-extern int cifs_negotiate_protocol(const unsigned int xid,
-				   struct cifs_ses *ses,
-				   struct TCP_Server_Info *server);
-extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
-			      struct TCP_Server_Info *server,
-			      struct nls_table *nls_info);
-extern int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
-extern int CIFSSMBNegotiate(const unsigned int xid,
-			    struct cifs_ses *ses,
-			    struct TCP_Server_Info *server);
-
-extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
-		    const char *tree, struct cifs_tcon *tcon,
-		    const struct nls_table *);
-
-extern int CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
-		const char *searchName, struct cifs_sb_info *cifs_sb,
-		__u16 *searchHandle, __u16 search_flags,
-		struct cifs_search_info *psrch_inf,
-		bool msearch);
-
-extern int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
-		__u16 searchHandle, __u16 search_flags,
-		struct cifs_search_info *psrch_inf);
-
-extern int CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
-			const __u16 search_handle);
-
-extern int CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			u16 netfid, FILE_ALL_INFO *pFindData);
-extern int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			    const char *search_Name, FILE_ALL_INFO *data,
-			    int legacy /* whether to use old info level */,
-			    const struct nls_table *nls_codepage, int remap);
-extern int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
-			       const char *search_name, FILE_ALL_INFO *data,
-			       const struct nls_table *nls_codepage, int remap);
-
-extern int CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
-extern int CIFSSMBUnixQPathInfo(const unsigned int xid,
-			struct cifs_tcon *tcon,
-			const unsigned char *searchName,
-			FILE_UNIX_BASIC_INFO *pFindData,
-			const struct nls_table *nls_codepage, int remap);
-
-extern int CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
-			   const char *search_name,
-			   struct dfs_info3_param **target_nodes,
-			   unsigned int *num_of_nodes,
-			   const struct nls_table *nls_codepage, int remap);
-
-extern int parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
-			       unsigned int *num_of_nodes,
-			       struct dfs_info3_param **target_nodes,
-			       const struct nls_table *nls_codepage, int remap,
-			       const char *searchName, bool is_unicode);
-extern void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
-				 struct cifs_sb_info *cifs_sb,
-				 struct smb3_fs_context *ctx);
-extern int CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			struct kstatfs *FSData);
-extern int SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			struct kstatfs *FSData);
-extern int CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			__u64 cap);
-
-extern int CIFSSMBQFSAttributeInfo(const unsigned int xid,
-			struct cifs_tcon *tcon);
-extern int CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon);
-extern int CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon);
-extern int CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			struct kstatfs *FSData);
-
-extern int SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
-			     const char *fileName, __le32 attributes, __le64 write_time,
-			     const struct nls_table *nls_codepage,
-			     struct cifs_sb_info *cifs_sb);
-extern int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			const char *fileName, const FILE_BASIC_INFO *data,
-			const struct nls_table *nls_codepage,
-			struct cifs_sb_info *cifs_sb);
-extern int CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
-			const FILE_BASIC_INFO *data, __u16 fid,
-			__u32 pid_of_opener);
-extern int CIFSSMBSetFileDisposition(const unsigned int xid,
-				     struct cifs_tcon *tcon,
-				     bool delete_file, __u16 fid,
-				     __u32 pid_of_opener);
-extern int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
-			 const char *file_name, __u64 size,
-			 struct cifs_sb_info *cifs_sb, bool set_allocation,
-			 struct dentry *dentry);
-extern int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
-			      struct cifsFileInfo *cfile, __u64 size,
-			      bool set_allocation);
-
 struct cifs_unix_set_info_args {
 	__u64	ctime;
 	__u64	atime;
@@ -440,260 +624,8 @@ struct cifs_unix_set_info_args {
 	dev_t	device;
 };
 
-extern int CIFSSMBUnixSetFileInfo(const unsigned int xid,
-				  struct cifs_tcon *tcon,
-				  const struct cifs_unix_set_info_args *args,
-				  u16 fid, u32 pid_of_opener);
-
-extern int CIFSSMBUnixSetPathInfo(const unsigned int xid,
-				  struct cifs_tcon *tcon, const char *file_name,
-				  const struct cifs_unix_set_info_args *args,
-				  const struct nls_table *nls_codepage,
-				  int remap);
-
-extern int CIFSSMBMkDir(const unsigned int xid, struct inode *inode,
-			umode_t mode, struct cifs_tcon *tcon,
-			const char *name, struct cifs_sb_info *cifs_sb);
-extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon,
-			const char *name, struct cifs_sb_info *cifs_sb);
-extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
-			const char *name, __u16 type,
-			const struct nls_table *nls_codepage,
-			int remap_special_chars);
-extern int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon,
-			  const char *name, struct cifs_sb_info *cifs_sb,
-			  struct dentry *dentry);
-int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
-		  struct dentry *source_dentry,
-		  const char *from_name, const char *to_name,
-		  struct cifs_sb_info *cifs_sb);
-extern int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *tcon,
-				 int netfid, const char *target_name,
-				 const struct nls_table *nls_codepage,
-				 int remap_special_chars);
-int CIFSCreateHardLink(const unsigned int xid,
-		       struct cifs_tcon *tcon,
-		       struct dentry *source_dentry,
-		       const char *from_name, const char *to_name,
-		       struct cifs_sb_info *cifs_sb);
-extern int CIFSUnixCreateHardLink(const unsigned int xid,
-			struct cifs_tcon *tcon,
-			const char *fromName, const char *toName,
-			const struct nls_table *nls_codepage,
-			int remap_special_chars);
-extern int CIFSUnixCreateSymLink(const unsigned int xid,
-			struct cifs_tcon *tcon,
-			const char *fromName, const char *toName,
-			const struct nls_table *nls_codepage, int remap);
-extern int CIFSSMBUnixQuerySymLink(const unsigned int xid,
-			struct cifs_tcon *tcon,
-			const unsigned char *searchName, char **syminfo,
-			const struct nls_table *nls_codepage, int remap);
-extern int cifs_query_reparse_point(const unsigned int xid,
-				    struct cifs_tcon *tcon,
-				    struct cifs_sb_info *cifs_sb,
-				    const char *full_path,
-				    u32 *tag, struct kvec *rsp,
-				    int *rsp_buftype);
-extern struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
-					       struct super_block *sb,
-					       const unsigned int xid,
-					       struct cifs_tcon *tcon,
-					       const char *full_path,
-					       bool directory,
-					       struct kvec *reparse_iov,
-					       struct kvec *xattr_iov);
-extern int CIFSSMB_set_compression(const unsigned int xid,
-				   struct cifs_tcon *tcon, __u16 fid);
-extern int CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms,
-		     int *oplock, FILE_ALL_INFO *buf);
-extern int SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
-			const char *fileName, const int disposition,
-			const int access_flags, const int omode,
-			__u16 *netfid, int *pOplock, FILE_ALL_INFO *,
-			const struct nls_table *nls_codepage, int remap);
-extern int CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
-			u32 posix_flags, __u64 mode, __u16 *netfid,
-			FILE_UNIX_BASIC_INFO *pRetData,
-			__u32 *pOplock, const char *name,
-			const struct nls_table *nls_codepage, int remap);
-extern int CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon,
-			const int smb_file_id);
-
-extern int CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon,
-			const int smb_file_id);
-
-extern int CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
-			unsigned int *nbytes, char **buf,
-			int *return_buf_type);
-extern int CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
-			unsigned int *nbytes, const char *buf);
-extern int CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
-			unsigned int *nbytes, struct kvec *iov, const int nvec);
-extern int CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
-				 const char *search_name, __u64 *inode_number,
-				 const struct nls_table *nls_codepage,
-				 int remap);
-
-extern int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
-		      const __u16 netfid, const __u8 lock_type,
-		      const __u32 num_unlock, const __u32 num_lock,
-		      LOCKING_ANDX_RANGE *buf);
-extern int CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
-			const __u16 netfid, const __u32 netpid, const __u64 len,
-			const __u64 offset, const __u32 numUnlock,
-			const __u32 numLock, const __u8 lockType,
-			const bool waitFlag, const __u8 oplock_level);
-extern int CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
-			const __u16 smb_file_id, const __u32 netpid,
-			const loff_t start_offset, const __u64 len,
-			struct file_lock *, const __u16 lock_type,
-			const bool waitFlag);
-extern int CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon);
-extern int CIFSSMBEcho(struct TCP_Server_Info *server);
-extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);
-
-extern struct cifs_ses *sesInfoAlloc(void);
-extern void sesInfoFree(struct cifs_ses *);
-extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled,
-					 enum smb3_tcon_ref_trace trace);
-extern void tconInfoFree(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);
-
-extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
-		   __u32 *pexpected_response_sequence_number);
-extern int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
-			  __u32 *);
-extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
-extern int cifs_verify_signature(struct smb_rqst *rqst,
-				 struct TCP_Server_Info *server,
-				__u32 expected_sequence_number);
-extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
-extern void cifs_crypto_secmech_release(struct TCP_Server_Info *server);
-extern int calc_seckey(struct cifs_ses *);
-extern int generate_smb30signingkey(struct cifs_ses *ses,
-				    struct TCP_Server_Info *server);
-extern int generate_smb311signingkey(struct cifs_ses *ses,
-				     struct TCP_Server_Info *server);
-
 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-extern ssize_t CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
-			const unsigned char *searchName,
-			const unsigned char *ea_name, char *EAData,
-			size_t bufsize, struct cifs_sb_info *cifs_sb);
-extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
-		const char *fileName, const char *ea_name,
-		const void *ea_value, const __u16 ea_value_len,
-		const struct nls_table *nls_codepage,
-		struct cifs_sb_info *cifs_sb);
-extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon,
-			__u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen, __u32 info);
-extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16,
-			struct smb_ntsd *pntsd, __u32 len, int aclflag);
-extern int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
-			   const unsigned char *searchName,
-			   struct posix_acl **acl, const int acl_type,
-			   const struct nls_table *nls_codepage, int remap);
-extern int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
-			   const unsigned char *fileName,
-			   const struct posix_acl *acl, const int acl_type,
-			   const struct nls_table *nls_codepage, int remap);
-extern int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
-			const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
-extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
-extern bool couldbe_mf_symlink(const struct cifs_fattr *fattr);
-extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
-			      struct cifs_sb_info *cifs_sb,
-			      struct cifs_fattr *fattr,
-			      const unsigned char *path);
-extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
-			const struct nls_table *codepage);
-
-extern struct TCP_Server_Info *
-cifs_find_tcp_session(struct smb3_fs_context *ctx);
-
-struct cifs_tcon *cifs_setup_ipc(struct cifs_ses *ses, bool seal);
-
-void __cifs_put_smb_ses(struct cifs_ses *ses);
-
-extern struct cifs_ses *
-cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
-
-int cifs_async_readv(struct cifs_io_subrequest *rdata);
-int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
-
-void cifs_async_writev(struct cifs_io_subrequest *wdata);
-int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
-			  struct cifs_sb_info *cifs_sb,
-			  const unsigned char *path, char *pbuf,
-			  unsigned int *pbytes_read);
-int cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
-			   struct cifs_sb_info *cifs_sb,
-			   const unsigned char *path, char *pbuf,
-			   unsigned int *pbytes_written);
-int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
-			  char *signature, struct cifs_calc_sig_ctx *ctx);
-enum securityEnum cifs_select_sectype(struct TCP_Server_Info *,
-					enum securityEnum);
-
-int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
-void cifs_free_hash(struct shash_desc **sdesc);
-
-int cifs_try_adding_channels(struct cifs_ses *ses);
-bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface);
-void cifs_ses_mark_for_reconnect(struct cifs_ses *ses);
-
-int
-cifs_ses_get_chan_index(struct cifs_ses *ses,
-			struct TCP_Server_Info *server);
-void
-cifs_chan_set_in_reconnect(struct cifs_ses *ses,
-			     struct TCP_Server_Info *server);
-void
-cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
-			       struct TCP_Server_Info *server);
-void
-cifs_chan_set_need_reconnect(struct cifs_ses *ses,
-			     struct TCP_Server_Info *server);
-void
-cifs_chan_clear_need_reconnect(struct cifs_ses *ses,
-			       struct TCP_Server_Info *server);
-bool
-cifs_chan_needs_reconnect(struct cifs_ses *ses,
-			  struct TCP_Server_Info *server);
-bool
-cifs_chan_is_iface_active(struct cifs_ses *ses,
-			  struct TCP_Server_Info *server);
-void
-cifs_disable_secondary_channels(struct cifs_ses *ses);
-void
-cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
-int
-SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount);
-
-void extract_unc_hostname(const char *unc, const char **h, size_t *len);
-int copy_path_name(char *dst, const char *src);
-int smb2_parse_query_directory(struct cifs_tcon *tcon, struct kvec *rsp_iov,
-			       int resp_buftype,
-			       struct cifs_search_info *srch_inf);
-
-struct super_block *cifs_get_dfs_tcon_super(struct cifs_tcon *tcon);
-void cifs_put_tcp_super(struct super_block *sb);
-int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix);
-char *extract_hostname(const char *unc);
-char *extract_sharename(const char *unc);
-int parse_reparse_point(struct reparse_data_buffer *buf,
-			u32 plen, struct cifs_sb_info *cifs_sb,
-			const char *full_path,
-			struct cifs_open_info_data *data);
-int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
-			 struct dentry *dentry, struct cifs_tcon *tcon,
-			 const char *full_path, umode_t mode, dev_t dev,
-			 const char *symname);
-int cifs_sfu_make_node(unsigned int xid, struct inode *inode,
-		       struct dentry *dentry, struct cifs_tcon *tcon,
-		       const char *full_path, umode_t mode, dev_t dev);
-umode_t wire_mode_to_posix(u32 wire, bool is_dir);
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
 static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
@@ -705,14 +637,6 @@ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
 			      referral, NULL);
 }
 
-int match_target_ip(struct TCP_Server_Info *server,
-		    const char *host, size_t hostlen,
-		    bool *result);
-int cifs_inval_name_dfs_link_error(const unsigned int xid,
-				   struct cifs_tcon *tcon,
-				   struct cifs_sb_info *cifs_sb,
-				   const char *full_path,
-				   bool *islink);
 #else
 static inline int cifs_inval_name_dfs_link_error(const unsigned int xid,
 				   struct cifs_tcon *tcon,
@@ -733,8 +657,6 @@ static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
 		return options;
 }
 
-int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry);
-
 static inline void cifs_put_smb_ses(struct cifs_ses *ses)
 {
 	__cifs_put_smb_ses(ses);
diff --git a/fs/smb/client/compress.h b/fs/smb/client/compress.h
index d843274e2a3d..4f831ab30da7 100644
--- a/fs/smb/client/compress.h
+++ b/fs/smb/client/compress.h
@@ -29,10 +29,12 @@
 #ifdef CONFIG_CIFS_COMPRESSION
 typedef int (*compress_send_fn)(struct TCP_Server_Info *, int, struct smb_rqst *);
 
-/* PROTOTYPES */
 
-int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_send_fn send_fn);
+/*
+ * compress.c
+ */
 bool should_compress(const struct cifs_tcon *tcon, const struct smb_rqst *rq);
+int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_send_fn send_fn);
 
 /*
  * smb_compress_alg_valid() - Validate a compression algorithm.
diff --git a/fs/smb/client/dfs.h b/fs/smb/client/dfs.h
index 21e2c9fd62e6..8459d2525881 100644
--- a/fs/smb/client/dfs.h
+++ b/fs/smb/client/dfs.h
@@ -41,7 +41,14 @@ struct dfs_ref_walk {
 #define ref_walk_fpath(w)	(ref_walk_cur(w)->full_path)
 #define ref_walk_tl(w)		(&ref_walk_cur(w)->tl)
 #define ref_walk_ses(w)	(ref_walk_cur(w)->ses)
-/* PROTOTYPES */
+
+/*
+ * dfs.c
+ */
+int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_param *ref,
+			      struct smb3_fs_context *ctx);
+int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx);
+int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon);
 
 static inline struct dfs_ref_walk *ref_walk_alloc(void)
 {
@@ -152,10 +159,6 @@ static inline void ref_walk_mark_end(struct dfs_ref_walk *rw)
 	ref->tit = ERR_PTR(-ENOENT); /* end marker */
 }
 
-int dfs_parse_target_referral(const char *full_path, const struct dfs_info3_param *ref,
-			      struct smb3_fs_context *ctx);
-int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx);
-
 static inline char *dfs_get_path(struct cifs_sb_info *cifs_sb, const char *path)
 {
 	return dfs_cache_canonical_path(path, cifs_sb->local_nls, cifs_remap(cifs_sb));
diff --git a/fs/smb/client/dfs_cache.h b/fs/smb/client/dfs_cache.h
index f311310a22fc..5900ef876297 100644
--- a/fs/smb/client/dfs_cache.h
+++ b/fs/smb/client/dfs_cache.h
@@ -32,12 +32,13 @@ struct dfs_cache_tgt_iterator {
 	int it_path_consumed;
 	struct list_head it_list;
 };
-/* PROTOTYPES */
 
+/*
+ * dfs_cache.c
+ */
+char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap);
 int dfs_cache_init(void);
 void dfs_cache_destroy(void);
-extern const struct proc_ops dfscache_proc_ops;
-
 int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nls_table *cp,
 		   int remap, const char *path, struct dfs_info3_param *ref,
 		   struct dfs_cache_tgt_list *tgt_list);
@@ -48,10 +49,11 @@ int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iter
 			       struct dfs_info3_param *ref);
 int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share,
 			    char **prefix);
-char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap);
 int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb);
 void dfs_cache_refresh(struct work_struct *work);
 
+extern const struct proc_ops dfscache_proc_ops;
+
 static inline struct dfs_cache_tgt_iterator *
 dfs_cache_get_next_tgt(struct dfs_cache_tgt_list *tl,
 		       struct dfs_cache_tgt_iterator *it)
diff --git a/fs/smb/client/dns_resolve.h b/fs/smb/client/dns_resolve.h
index 0dc706f2c422..69dc80533714 100644
--- a/fs/smb/client/dns_resolve.h
+++ b/fs/smb/client/dns_resolve.h
@@ -17,9 +17,6 @@
 
 #ifdef __KERNEL__
 
-int dns_resolve_name(const char *dom, const char *name,
-		     size_t namelen, struct sockaddr *ip_addr);
-
 static inline int dns_resolve_unc(const char *dom, const char *unc,
 				  struct sockaddr *ip_addr)
 {
diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h
index b0fec6b9a23b..6e1a14e98b57 100644
--- a/fs/smb/client/fs_context.h
+++ b/fs/smb/client/fs_context.h
@@ -359,26 +359,17 @@ static inline enum cifs_symlink_type cifs_symlink_type(struct cifs_sb_info *cifs
 	return CIFS_SYMLINK_TYPE_NONE;
 }
 
-extern int smb3_init_fs_context(struct fs_context *fc);
-extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx);
-extern void smb3_cleanup_fs_context(struct smb3_fs_context *ctx);
-
 static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *fc)
 {
 	return fc->fs_private;
 }
 
-extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
-extern int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
-extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
-
 /*
  * max deferred close timeout (jiffies) - 2^30
  */
 #define SMB3_MAX_DCLOSETIMEO (1 << 30)
 #define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */
 #define MAX_CACHED_FIDS 16
-extern char *cifs_sanitize_prepath(char *prepath, gfp_t gfp);
 
 extern struct mutex cifs_mount_mutex;
 
diff --git a/fs/smb/client/fscache.h b/fs/smb/client/fscache.h
index 162865381dac..54b64f0f45da 100644
--- a/fs/smb/client/fscache.h
+++ b/fs/smb/client/fscache.h
@@ -35,13 +35,15 @@ struct cifs_fscache_inode_coherency_data {
 
 #ifdef CONFIG_CIFS_FSCACHE
 
-/* PROTOTYPES */
-extern int cifs_fscache_get_super_cookie(struct cifs_tcon *);
-extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
 
-extern void cifs_fscache_get_inode_cookie(struct inode *inode);
-extern void cifs_fscache_release_inode_cookie(struct inode *);
-extern void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update);
+/*
+ * fscache.c
+ */
+int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon);
+void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon);
+void cifs_fscache_get_inode_cookie(struct inode *inode);
+void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update);
+void cifs_fscache_release_inode_cookie(struct inode *inode);
 
 static inline
 void cifs_fscache_fill_coherency(struct inode *inode,
@@ -57,7 +59,6 @@ void cifs_fscache_fill_coherency(struct inode *inode,
 	cd->last_change_time_nsec = cpu_to_le32(ctime.tv_nsec);
 }
 
-
 static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode)
 {
 	return netfs_i_cookie(&CIFS_I(inode)->netfs);
diff --git a/fs/smb/client/netlink.h b/fs/smb/client/netlink.h
index 9d73b23858b8..74ef50c9a8c6 100644
--- a/fs/smb/client/netlink.h
+++ b/fs/smb/client/netlink.h
@@ -10,8 +10,11 @@
 
 extern struct genl_family cifs_genl_family;
 
-/* PROTOTYPES */
-extern int cifs_genl_init(void);
-extern void cifs_genl_exit(void);
+
+/*
+ * netlink.c
+ */
+int cifs_genl_init(void);
+void cifs_genl_exit(void);
 
 #endif /* _CIFS_NETLINK_H */
diff --git a/fs/smb/client/nterr.h b/fs/smb/client/nterr.h
index 180602c22355..104cf2c2179b 100644
--- a/fs/smb/client/nterr.h
+++ b/fs/smb/client/nterr.h
@@ -10,8 +10,6 @@
 
 */
 
-
-
 #ifndef _NTERR_H
 #define _NTERR_H
 
diff --git a/fs/smb/client/ntlmssp.h b/fs/smb/client/ntlmssp.h
index a11fddc321f6..f3571970744a 100644
--- a/fs/smb/client/ntlmssp.h
+++ b/fs/smb/client/ntlmssp.h
@@ -142,16 +142,3 @@ typedef struct _AUTHENTICATE_MESSAGE {
  * Size of the session key (crypto key encrypted with the password
  */
 
-int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
-int build_ntlmssp_negotiate_blob(unsigned char **pbuffer, u16 *buflen,
-				 struct cifs_ses *ses,
-				 struct TCP_Server_Info *server,
-				 const struct nls_table *nls_cp);
-int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer, u16 *buflen,
-				 struct cifs_ses *ses,
-				 struct TCP_Server_Info *server,
-				 const struct nls_table *nls_cp);
-int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
-			struct cifs_ses *ses,
-			struct TCP_Server_Info *server,
-			const struct nls_table *nls_cp);
diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h
index 19caab2fd11e..f288fd8e5402 100644
--- a/fs/smb/client/reparse.h
+++ b/fs/smb/client/reparse.h
@@ -126,15 +126,4 @@ static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data)
 	return ret;
 }
 
-bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb,
-				 struct cifs_fattr *fattr,
-				 struct cifs_open_info_data *data);
-int create_reparse_symlink(const unsigned int xid, struct inode *inode,
-				struct dentry *dentry, struct cifs_tcon *tcon,
-				const char *full_path, const char *symname);
-int mknod_reparse(unsigned int xid, struct inode *inode,
-		       struct dentry *dentry, struct cifs_tcon *tcon,
-		       const char *full_path, umode_t mode, dev_t dev);
-struct reparse_data_buffer *smb2_get_reparse_point_buffer(const struct kvec *rsp_iov, u32 *len);
-
 #endif /* _CIFS_REPARSE_H */
diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
index 68ab0447b671..496be436dcea 100644
--- a/fs/smb/client/smb1proto.h
+++ b/fs/smb/client/smb1proto.h
@@ -15,6 +15,216 @@
 #include "dfs_cache.h"
 #endif
 
-/* PROTOTYPES */
+
+/*
+ * cifssmb.c
+ */
+int small_smb_init_no_tc(const int smb_command, const int wct,
+			 struct cifs_ses *ses, void **request_buf);
+int CIFSSMBNegotiate(const unsigned int xid,
+		     struct cifs_ses *ses,
+		     struct TCP_Server_Info *server);
+int CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon);
+int CIFSSMBEcho(struct TCP_Server_Info *server);
+int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);
+int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon,
+		     const char *fileName, __u16 type,
+		     const struct nls_table *nls_codepage, int remap);
+int CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+		   struct cifs_sb_info *cifs_sb, struct dentry *dentry);
+int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+		 struct cifs_sb_info *cifs_sb);
+int CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
+		 struct cifs_tcon *tcon, const char *name,
+		 struct cifs_sb_info *cifs_sb);
+int CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
+		    __u32 posix_flags, __u64 mode, __u16 *netfid,
+		    FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock,
+		    const char *name, const struct nls_table *nls_codepage,
+		    int remap);
+int SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
+		  const char *fileName, const int openDisposition,
+		  const int access_flags, const int create_options, __u16 *netfid,
+		  int *pOplock, FILE_ALL_INFO *pfile_info,
+		  const struct nls_table *nls_codepage, int remap);
+int CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
+	      FILE_ALL_INFO *buf);
+int cifs_async_readv(struct cifs_io_subrequest *rdata);
+int CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
+		unsigned int *nbytes, char **buf, int *pbuf_type);
+int CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
+		 unsigned int *nbytes, const char *buf);
+void cifs_async_writev(struct cifs_io_subrequest *wdata);
+int CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
+		  unsigned int *nbytes, struct kvec *iov, int n_vec);
+int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon,
+	       const __u16 netfid, const __u8 lock_type, const __u32 num_unlock,
+	       const __u32 num_lock, LOCKING_ANDX_RANGE *buf);
+int CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
+		const __u16 smb_file_id, const __u32 netpid, const __u64 len,
+		const __u64 offset, const __u32 numUnlock,
+		const __u32 numLock, const __u8 lockType,
+		const bool waitFlag, const __u8 oplock_level);
+int CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
+		     const __u16 smb_file_id, const __u32 netpid,
+		     const loff_t start_offset, const __u64 len,
+		     struct file_lock *pLockData, const __u16 lock_type,
+		     const bool waitFlag);
+int CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id);
+int CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id);
+int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
+		  struct dentry *source_dentry,
+		  const char *from_name, const char *to_name,
+		  struct cifs_sb_info *cifs_sb);
+int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon,
+			  int netfid, const char *target_name,
+			  const struct nls_table *nls_codepage, int remap);
+int CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon,
+			  const char *fromName, const char *toName,
+			  const struct nls_table *nls_codepage, int remap);
+int CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
+			   const char *fromName, const char *toName,
+			   const struct nls_table *nls_codepage, int remap);
+int CIFSCreateHardLink(const unsigned int xid,
+		       struct cifs_tcon *tcon,
+		       struct dentry *source_dentry,
+		       const char *from_name, const char *to_name,
+		       struct cifs_sb_info *cifs_sb);
+int CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
+			    const unsigned char *searchName, char **symlinkinfo,
+			    const struct nls_table *nls_codepage, int remap);
+int cifs_query_reparse_point(const unsigned int xid,
+			     struct cifs_tcon *tcon,
+			     struct cifs_sb_info *cifs_sb,
+			     const char *full_path,
+			     u32 *tag, struct kvec *rsp,
+			     int *rsp_buftype);
+struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data,
+					struct super_block *sb,
+					const unsigned int xid,
+					struct cifs_tcon *tcon,
+					const char *full_path,
+					bool directory,
+					struct kvec *reparse_iov,
+					struct kvec *xattr_iov);
+int CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+			    __u16 fid);
+int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
+		    const unsigned char *searchName, struct posix_acl **acl,
+		    const int acl_type, const struct nls_table *nls_codepage,
+		    int remap);
+int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
+		    const unsigned char *fileName, const struct posix_acl *acl,
+		    const int acl_type, const struct nls_table *nls_codepage,
+		    int remap);
+int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
+		    const unsigned char *searchName, struct posix_acl **acl,
+		    const int acl_type, const struct nls_table *nls_codepage,
+		    int remap);
+int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
+		    const unsigned char *fileName, const struct posix_acl *acl,
+		    const int acl_type, const struct nls_table *nls_codepage,
+		    int remap);
+int CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
+		   const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
+int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
+		      struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info);
+int CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
+		      struct smb_ntsd *pntsd, __u32 acllen, int aclflag);
+int SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
+			const char *search_name, FILE_ALL_INFO *data,
+			const struct nls_table *nls_codepage, int remap);
+int CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
+		     u16 netfid, FILE_ALL_INFO *pFindData);
+int CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
+		     const char *search_name, FILE_ALL_INFO *data,
+		     int legacy /* old style infolevel */,
+		     const struct nls_table *nls_codepage, int remap);
+int CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
+			 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
+int CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
+			 const unsigned char *searchName,
+			 FILE_UNIX_BASIC_INFO *pFindData,
+			 const struct nls_table *nls_codepage, int remap);
+int CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
+		  const char *searchName, struct cifs_sb_info *cifs_sb,
+		  __u16 *pnetfid, __u16 search_flags,
+		  struct cifs_search_info *psrch_inf, bool msearch);
+int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
+		 __u16 searchHandle, __u16 search_flags,
+		 struct cifs_search_info *psrch_inf);
+int CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon,
+		  const __u16 searchHandle);
+int CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
+			  const char *search_name, __u64 *inode_number,
+			  const struct nls_table *nls_codepage, int remap);
+int CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
+		    const char *search_name, struct dfs_info3_param **target_nodes,
+		    unsigned int *num_of_nodes,
+		    const struct nls_table *nls_codepage, int remap);
+int SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
+		  struct kstatfs *FSData);
+int CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
+		   struct kstatfs *FSData);
+int CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon);
+int CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon);
+int CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon);
+int CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap);
+int CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
+			struct kstatfs *FSData);
+int CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
+		  const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb,
+		  bool set_allocation, struct dentry *dentry);
+int CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon,
+		       struct cifsFileInfo *cfile, __u64 size, bool set_allocation);
+int SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon,
+		      const char *fileName, __le32 attributes, __le64 write_time,
+		      const struct nls_table *nls_codepage,
+		      struct cifs_sb_info *cifs_sb);
+int CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
+		       const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener);
+int CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
+			      bool delete_file, __u16 fid, __u32 pid_of_opener);
+int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
+		       const char *fileName, const FILE_BASIC_INFO *data,
+		       const struct nls_table *nls_codepage,
+		       struct cifs_sb_info *cifs_sb);
+int CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
+			   const struct cifs_unix_set_info_args *args,
+			   u16 fid, u32 pid_of_opener);
+int CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
+			   const char *file_name,
+			   const struct cifs_unix_set_info_args *args,
+			   const struct nls_table *nls_codepage, int remap);
+ssize_t CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
+		       const unsigned char *searchName, const unsigned char *ea_name,
+		       char *EAData, size_t buf_size,
+		       struct cifs_sb_info *cifs_sb);
+int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
+		 const char *fileName, const char *ea_name, const void *ea_value,
+		 const __u16 ea_value_len, const struct nls_table *nls_codepage,
+		 struct cifs_sb_info *cifs_sb);
+
+/*
+ * cifstransport.c
+ */
+int smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
+	     unsigned int smb_buf_length);
+struct mid_q_entry *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);
+int cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+		       bool log_error);
+struct mid_q_entry *cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
+				       struct smb_rqst *rqst);
+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);
+int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
+			    struct smb_hdr *in_buf, struct smb_hdr *out_buf,
+			    int *pbytes_returned);
 
 #endif /* _SMB1PROTO_H */
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index dca9bc875f8d..01cde09d98ac 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -17,76 +17,37 @@
 struct statfs;
 struct smb_rqst;
 
-/* PROTOTYPES */
 
-extern int map_smb2_to_linux_error(char *buf, bool log_err);
-extern int smb2_check_message(char *buf, unsigned int length,
-			      struct TCP_Server_Info *server);
-extern unsigned int smb2_calc_size(void *buf);
-extern char *smb2_get_data_area_len(int *off, int *len,
-				    struct smb2_hdr *shdr);
-extern __le16 *cifs_convert_path_to_utf16(const char *from,
-					  struct cifs_sb_info *cifs_sb);
+/*
+ * smb2file.c
+ */
+int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_info *cifs_sb);
+int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov,
+				const char *full_path, char **path);
+int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+		   __u32 *oplock, void *buf);
+int smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
+		      const unsigned int xid);
+int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
 
-extern int smb2_verify_signature(struct smb_rqst *, struct TCP_Server_Info *);
-extern int smb2_check_receive(struct mid_q_entry *mid,
-			      struct TCP_Server_Info *server, bool log_error);
-extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses,
-					      struct TCP_Server_Info *,
-					      struct smb_rqst *rqst);
-extern struct mid_q_entry *smb2_setup_async_request(
-			struct TCP_Server_Info *server, struct smb_rqst *rqst);
-extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server,
-						__u64 ses_id, __u32  tid);
-extern void smb2_echo_request(struct work_struct *work);
-extern __le32 smb2_get_lease_state(struct cifsInodeInfo *cinode);
-extern bool smb2_is_valid_oplock_break(char *buffer,
-				       struct TCP_Server_Info *srv);
-extern int smb3_handle_read_data(struct TCP_Server_Info *server,
-				 struct mid_q_entry *mid);
-extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
-				struct cifs_sb_info *cifs_sb, const char *path,
-				__u32 *reparse_tag);
-struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data,
-				     struct super_block *sb,
-				     const unsigned int xid,
-				     struct cifs_tcon *tcon,
-				     const char *full_path,
-				     bool directory,
-				     struct kvec *reparse_iov,
-				     struct kvec *xattr_iov);
-int smb2_query_reparse_point(const unsigned int xid,
-			     struct cifs_tcon *tcon,
-			     struct cifs_sb_info *cifs_sb,
-			     const char *full_path,
-			     u32 *tag, struct kvec *rsp,
-			     int *rsp_buftype);
+/*
+ * smb2inode.c
+ */
 int smb2_query_path_info(const unsigned int xid,
 			 struct cifs_tcon *tcon,
 			 struct cifs_sb_info *cifs_sb,
 			 const char *full_path,
 			 struct cifs_open_info_data *data);
-extern int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
-			      const char *full_path, __u64 size,
-			      struct cifs_sb_info *cifs_sb, bool set_alloc,
-				  struct dentry *dentry);
-extern int smb2_set_file_info(struct inode *inode, const char *full_path,
-			      FILE_BASIC_INFO *buf, const unsigned int xid);
-extern int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
-			       umode_t mode, struct cifs_tcon *tcon,
-			       const char *full_path,
-			       struct cifs_sb_info *cifs_sb);
-extern int smb2_mkdir(const unsigned int xid, struct inode *inode,
-		      umode_t mode, struct cifs_tcon *tcon,
-		      const char *name, struct cifs_sb_info *cifs_sb);
-extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path,
-			       struct cifs_sb_info *cifs_sb,
-			       struct cifs_tcon *tcon, const unsigned int xid);
-extern int smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
-		      const char *name, struct cifs_sb_info *cifs_sb);
-extern int smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon,
-		       const char *name, struct cifs_sb_info *cifs_sb,
-			   struct dentry *dentry);
+int smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
+	       struct cifs_tcon *tcon, const char *name,
+	       struct cifs_sb_info *cifs_sb);
+void smb2_mkdir_setinfo(struct inode *inode, const char *name,
+			struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon,
+			const unsigned int xid);
+int smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+	       struct cifs_sb_info *cifs_sb);
+int smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+		struct cifs_sb_info *cifs_sb, struct dentry *dentry);
 int smb2_rename_path(const unsigned int xid,
 		     struct cifs_tcon *tcon,
 		     struct dentry *source_dentry,
@@ -97,221 +58,242 @@ int smb2_create_hardlink(const unsigned int xid,
 			 struct dentry *source_dentry,
 			 const char *from_name, const char *to_name,
 			 struct cifs_sb_info *cifs_sb);
-extern int smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
-			struct cifs_sb_info *cifs_sb, const unsigned char *path,
-			char *pbuf, unsigned int *pbytes_written);
-extern int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
-			  struct cifs_sb_info *cifs_sb,
-			  const unsigned char *path, char *pbuf,
-			  unsigned int *pbytes_read);
-int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_info *cifs_sb);
-int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
-			      bool relative,
-			      const char *full_path,
-			      struct cifs_sb_info *cifs_sb);
-int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb,
-				const struct kvec *iov,
-				const char *full_path,
-				char **path);
-int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
-		   void *buf);
-extern int smb2_unlock_range(struct cifsFileInfo *cfile,
-			     struct file_lock *flock, const unsigned int xid);
-extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
-extern void smb2_reconnect_server(struct work_struct *work);
-extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
-extern unsigned long smb_rqst_len(struct TCP_Server_Info *server,
-				  struct smb_rqst *rqst);
-extern void smb2_set_next_command(struct cifs_tcon *tcon,
-				  struct smb_rqst *rqst);
-extern void smb2_set_related(struct smb_rqst *rqst);
-extern void smb2_set_replay(struct TCP_Server_Info *server,
-			    struct smb_rqst *rqst);
-extern bool smb2_should_replay(struct cifs_tcon *tcon,
-			  int *pretries,
-			  int *pcur_sleep);
+int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
+		       const char *full_path, __u64 size,
+		       struct cifs_sb_info *cifs_sb, bool set_alloc,
+		       struct dentry *dentry);
+int smb2_set_file_info(struct inode *inode, const char *full_path,
+		       FILE_BASIC_INFO *buf, const unsigned int xid);
+struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data,
+					struct super_block *sb,
+					const unsigned int xid,
+					struct cifs_tcon *tcon,
+					const char *full_path,
+					bool directory,
+					struct kvec *reparse_iov,
+					struct kvec *xattr_iov);
+int smb2_query_reparse_point(const unsigned int xid,
+			     struct cifs_tcon *tcon,
+			     struct cifs_sb_info *cifs_sb,
+			     const char *full_path,
+			     u32 *tag, struct kvec *rsp,
+			     int *rsp_buftype);
+int smb2_rename_pending_delete(const char *full_path,
+			       struct dentry *dentry,
+			       const unsigned int xid);
 
 /*
- * SMB2 Worker functions - most of protocol specific implementation details
- * are contained within these calls.
+ * smb2maperror.c
  */
-extern int SMB2_negotiate(const unsigned int xid,
-			  struct cifs_ses *ses,
-			  struct TCP_Server_Info *server);
-extern int SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
-			   struct TCP_Server_Info *server,
-			   const struct nls_table *nls_cp);
-extern int SMB2_logoff(const unsigned int xid, struct cifs_ses *ses);
-extern int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses,
-		     const char *tree, struct cifs_tcon *tcon,
-		     const struct nls_table *);
-extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
-extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
-		     __le16 *path, __u8 *oplock,
-		     struct smb2_file_all_info *buf,
-		     struct create_posix_rsp *posix,
-		     struct kvec *err_iov, int *resp_buftype);
-extern int SMB2_open_init(struct cifs_tcon *tcon,
-			  struct TCP_Server_Info *server,
-			  struct smb_rqst *rqst,
-			  __u8 *oplock, struct cifs_open_parms *oparms,
-			  __le16 *path);
-extern void SMB2_open_free(struct smb_rqst *rqst);
-extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
-		     u64 persistent_fid, u64 volatile_fid, u32 opcode,
-		     char *in_data, u32 indatalen, u32 maxoutlen,
-		     char **out_data, u32 *plen /* returned data len */);
-extern int SMB2_ioctl_init(struct cifs_tcon *tcon,
-			   struct TCP_Server_Info *server,
-			   struct smb_rqst *rqst,
-			   u64 persistent_fid, u64 volatile_fid, u32 opcode,
-			   char *in_data, u32 indatalen,
-			   __u32 max_response_size);
-extern void SMB2_ioctl_free(struct smb_rqst *rqst);
-extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
-			u64 persistent_fid, u64 volatile_fid, bool watch_tree,
-			u32 completion_filter, u32 max_out_data_len,
-			char **out_data, u32 *plen /* returned data len */);
+int map_smb2_to_linux_error(char *buf, bool log_err);
 
-extern int __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
-			u64 persistent_fid, u64 volatile_fid,
-			struct smb2_file_network_open_info *pbuf);
-extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
-		      u64 persistent_file_id, u64 volatile_file_id);
-extern int SMB2_close_init(struct cifs_tcon *tcon,
-			   struct TCP_Server_Info *server,
-			   struct smb_rqst *rqst,
-			   u64 persistent_fid, u64 volatile_fid,
-			   bool query_attrs);
-extern void SMB2_close_free(struct smb_rqst *rqst);
-extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon,
-		      u64 persistent_file_id, u64 volatile_file_id);
-extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
-			   struct cifs_tcon *tcon,
-			   struct TCP_Server_Info *server,
-			   u64 persistent_file_id, u64 volatile_file_id);
-extern void SMB2_flush_free(struct smb_rqst *rqst);
-extern int SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
-		u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen);
-extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
-			   u64 persistent_file_id, u64 volatile_file_id,
-			   struct smb2_file_all_info *data);
-extern int SMB2_query_info_init(struct cifs_tcon *tcon,
-				struct TCP_Server_Info *server,
-				struct smb_rqst *rqst,
-				u64 persistent_fid, u64 volatile_fid,
-				u8 info_class, u8 info_type,
-				u32 additional_info, size_t output_len,
-				size_t input_len, void *input);
-extern void SMB2_query_info_free(struct smb_rqst *rqst);
-extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
-			  u64 persistent_file_id, u64 volatile_file_id,
-			  void **data, unsigned int *plen, u32 info);
-extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
-			    u64 persistent_fid, u64 volatile_fid,
-			    __le64 *uniqueid);
-extern int smb2_async_readv(struct cifs_io_subrequest *rdata);
-extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
-		     unsigned int *nbytes, char **buf, int *buf_type);
-extern void smb2_async_writev(struct cifs_io_subrequest *wdata);
-extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
-		      unsigned int *nbytes, struct kvec *iov, int n_vec);
-extern int SMB2_echo(struct TCP_Server_Info *server);
-extern int SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
-				u64 persistent_fid, u64 volatile_fid, int index,
-				struct cifs_search_info *srch_inf);
-extern int SMB2_query_directory_init(unsigned int xid, struct cifs_tcon *tcon,
-				     struct TCP_Server_Info *server,
-				     struct smb_rqst *rqst,
-				     u64 persistent_fid, u64 volatile_fid,
-				     int index, int info_level);
-extern void SMB2_query_directory_free(struct smb_rqst *rqst);
-extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon,
-			u64 persistent_fid, u64 volatile_fid, u32 pid,
-			loff_t new_eof);
-extern int SMB2_set_info_init(struct cifs_tcon *tcon,
-			      struct TCP_Server_Info *server,
-			      struct smb_rqst *rqst,
-			      u64 persistent_fid, u64 volatile_fid, u32 pid,
-			      u8 info_class, u8 info_type, u32 additional_info,
-			      void **data, unsigned int *size);
-extern void SMB2_set_info_free(struct smb_rqst *rqst);
-extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
-			u64 persistent_fid, u64 volatile_fid,
-			struct smb_ntsd *pnntsd, int pacllen, int aclflag);
-extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
-		       u64 persistent_fid, u64 volatile_fid,
-		       struct smb2_file_full_ea_info *buf, int len);
-extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
-				u64 persistent_fid, u64 volatile_fid);
-extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
-			     const u64 persistent_fid, const u64 volatile_fid,
-			     const __u8 oplock_level);
-extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon,
-				       __u64 persistent_fid,
-				       __u64 volatile_fid);
-extern int smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server);
+/*
+ * smb2misc.c
+ */
+int smb2_check_message(char *buf, 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);
+__le32 smb2_get_lease_state(struct cifsInodeInfo *cinode);
+bool smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server);
 void smb2_cancelled_close_fid(struct work_struct *work);
-extern int SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon,
-			 u64 persistent_file_id, u64 volatile_file_id,
-			 struct kstatfs *FSData);
-extern int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
-			 u64 persistent_file_id, u64 volatile_file_id, int lvl);
-extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
-		     const __u64 persist_fid, const __u64 volatile_fid,
-		     const __u32 pid, const __u64 length, const __u64 offset,
-		     const __u32 lockFlags, const bool wait);
-extern int smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
-		      const __u64 persist_fid, const __u64 volatile_fid,
-		      const __u32 pid, const __u32 num_lock,
-		      struct smb2_lock_element *buf);
-extern int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
-			    __u8 *lease_key, const __le32 lease_state);
-extern int smb3_validate_negotiate(const unsigned int, struct cifs_tcon *);
+int smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
+				__u64 volatile_fid);
+int smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server);
+void smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
+				struct kvec *iov, int nvec);
 
-extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
-					enum securityEnum);
+/*
+ * smb2ops.c
+ */
+int SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount);
+void smb2_set_replay(struct TCP_Server_Info *server, struct smb_rqst *rqst);
+void smb2_set_related(struct smb_rqst *rqst);
+void smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst);
+bool smb2_should_replay(struct cifs_tcon *tcon,
+			int *pretries,
+			int *pcur_sleep);
+int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
+			     const char *path, u32 desired_access,
+			     u32 class, u32 type, u32 output_len,
+			     struct kvec *rsp, int *buftype,
+			     struct cifs_sb_info *cifs_sb);
+void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst);
+int smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid);
+int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
+			 struct dentry *dentry, struct cifs_tcon *tcon,
+			 const char *full_path, umode_t mode, dev_t dev,
+			 const char *symname);
+int cifs_sfu_make_node(unsigned int xid, struct inode *inode,
+		       struct dentry *dentry, struct cifs_tcon *tcon,
+		       const char *full_path, umode_t mode, dev_t dev);
+
+/*
+ * smb2pdu.c
+ */
+int smb3_encryption_required(const struct cifs_tcon *tcon);
+int SMB2_negotiate(const unsigned int xid,
+		   struct cifs_ses *ses,
+		   struct TCP_Server_Info *server);
+int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon);
+enum securityEnum smb2_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested);
+int SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
+		    struct TCP_Server_Info *server,
+		    const struct nls_table *nls_cp);
+int SMB2_logoff(const unsigned int xid, struct cifs_ses *ses);
+int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
+	      struct cifs_tcon *tcon, const struct nls_table *cp);
+int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
 int smb2_parse_contexts(struct TCP_Server_Info *server,
 			struct kvec *rsp_iov,
 			__u16 *epoch,
 			char *lease_key, __u8 *oplock,
 			struct smb2_file_all_info *buf,
 			struct create_posix_rsp *posix);
-
-extern int smb3_encryption_required(const struct cifs_tcon *tcon);
-extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
-			     struct kvec *iov, unsigned int min_buf_size);
-extern int smb2_validate_and_copy_iov(unsigned int offset,
-				      unsigned int buffer_length,
-				      struct kvec *iov,
-				      unsigned int minbufsize, char *data);
-extern void smb2_copy_fs_info_to_kstatfs(
-	 struct smb2_fs_full_size_info *pfs_inf,
-	 struct kstatfs *kst);
-extern int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
-extern void smb311_update_preauth_hash(struct cifs_ses *ses,
-				       struct TCP_Server_Info *server,
-				       struct kvec *iov, int nvec);
-extern int smb2_query_info_compound(const unsigned int xid,
-				    struct cifs_tcon *tcon,
-				    const char *path, u32 desired_access,
-				    u32 class, u32 type, u32 output_len,
-				    struct kvec *rsp, int *buftype,
-				    struct cifs_sb_info *cifs_sb);
-/* query path info from the server using SMB311 POSIX extensions*/
-int smb311_posix_query_path_info(const unsigned int xid,
-				 struct cifs_tcon *tcon,
-				 struct cifs_sb_info *cifs_sb,
-				 const char *full_path,
-				 struct cifs_open_info_data *data);
+int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
+		       umode_t mode, struct cifs_tcon *tcon,
+		       const char *full_path,
+		       struct cifs_sb_info *cifs_sb);
+int SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
+		   struct smb_rqst *rqst, __u8 *oplock,
+		   struct cifs_open_parms *oparms, __le16 *path);
+void SMB2_open_free(struct smb_rqst *rqst);
+int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
+	      __u8 *oplock, struct smb2_file_all_info *buf,
+	      struct create_posix_rsp *posix,
+	      struct kvec *err_iov, int *buftype);
+int SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
+		    struct smb_rqst *rqst,
+		    u64 persistent_fid, u64 volatile_fid, u32 opcode,
+		    char *in_data, u32 indatalen,
+		    __u32 max_response_size);
+void SMB2_ioctl_free(struct smb_rqst *rqst);
+int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
+	       u64 volatile_fid, u32 opcode, char *in_data, u32 indatalen,
+	       u32 max_out_data_len, char **out_data,
+	       u32 *plen /* returned data len */);
+int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
+			 u64 persistent_fid, u64 volatile_fid);
+int SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
+		    struct smb_rqst *rqst,
+		    u64 persistent_fid, u64 volatile_fid, bool query_attrs);
+void SMB2_close_free(struct smb_rqst *rqst);
+int __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
+		 u64 persistent_fid, u64 volatile_fid,
+		 struct smb2_file_network_open_info *pbuf);
+int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
+	       u64 persistent_fid, u64 volatile_fid);
+int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
+		      struct kvec *iov, unsigned int min_buf_size);
+int smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
+			       struct kvec *iov, unsigned int minbufsize,
+			       char *data);
+int SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
+			 struct smb_rqst *rqst,
+			 u64 persistent_fid, u64 volatile_fid,
+			 u8 info_class, u8 info_type, u32 additional_info,
+			 size_t output_len, size_t input_len, void *input);
+void SMB2_query_info_free(struct smb_rqst *rqst);
+int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
+		    u64 persistent_fid, u64 volatile_fid, struct smb2_file_all_info *data);
+int SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
+			    u64 persistent_fid, u64 volatile_fid,
+			    struct smb311_posix_qinfo *data, u32 *plen);
+int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
+		   u64 persistent_fid, u64 volatile_fid,
+		   void **data, u32 *plen, u32 extra_info);
+int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
+		     u64 persistent_fid, u64 volatile_fid, __le64 *uniqueid);
+int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
+		       u64 persistent_fid, u64 volatile_fid, bool watch_tree,
+		       u32 completion_filter, u32 max_out_data_len, char **out_data,
+		       u32 *plen /* returned data len */);
+void smb2_reconnect_server(struct work_struct *work);
+int SMB2_echo(struct TCP_Server_Info *server);
+void SMB2_flush_free(struct smb_rqst *rqst);
+int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
+		    struct cifs_tcon *tcon, struct TCP_Server_Info *server,
+		    u64 persistent_fid, u64 volatile_fid);
+int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
+	       u64 volatile_fid);
+int smb2_async_readv(struct cifs_io_subrequest *rdata);
+int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
+	      unsigned int *nbytes, char **buf, int *buf_type);
+void smb2_async_writev(struct cifs_io_subrequest *wdata);
+int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
+	       unsigned int *nbytes, struct kvec *iov, int n_vec);
+int posix_info_sid_size(const void *beg, const void *end);
 int posix_info_parse(const void *beg, const void *end,
 		     struct smb2_posix_info_parsed *out);
-int posix_info_sid_size(const void *beg, const void *end);
-int smb2_make_nfs_node(unsigned int xid, struct inode *inode,
-		       struct dentry *dentry, struct cifs_tcon *tcon,
-		       const char *full_path, umode_t mode, dev_t dev);
-int smb2_rename_pending_delete(const char *full_path,
-			       struct dentry *dentry,
-			       const unsigned int xid);
+int SMB2_query_directory_init(const unsigned int xid,
+			      struct cifs_tcon *tcon,
+			      struct TCP_Server_Info *server,
+			      struct smb_rqst *rqst,
+			      u64 persistent_fid, u64 volatile_fid,
+			      int index, int info_level);
+void SMB2_query_directory_free(struct smb_rqst *rqst);
+int smb2_parse_query_directory(struct cifs_tcon *tcon,
+			       struct kvec *rsp_iov,
+			       int resp_buftype,
+			       struct cifs_search_info *srch_inf);
+int SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
+			 u64 persistent_fid, u64 volatile_fid, int index,
+			 struct cifs_search_info *srch_inf);
+int SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
+		       struct smb_rqst *rqst,
+		       u64 persistent_fid, u64 volatile_fid, u32 pid,
+		       u8 info_class, u8 info_type, u32 additional_info,
+		       void **data, unsigned int *size);
+void SMB2_set_info_free(struct smb_rqst *rqst);
+int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
+		 u64 volatile_fid, u32 pid, loff_t new_eof);
+int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon,
+		 u64 persistent_fid, u64 volatile_fid,
+		 struct smb_ntsd *pnntsd, int pacllen, int aclflag);
+int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
+		u64 persistent_fid, u64 volatile_fid,
+		struct smb2_file_full_ea_info *buf, int len);
+int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
+		      const u64 persistent_fid, const u64 volatile_fid,
+		      __u8 oplock_level);
+void smb2_copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf,
+				  struct kstatfs *kst);
+int SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon,
+			  u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata);
+int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
+		  u64 persistent_fid, u64 volatile_fid, int level);
+int smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
+	       const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
+	       const __u32 num_lock, struct smb2_lock_element *buf);
+int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon,
+	      const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
+	      const __u64 length, const __u64 offset, const __u32 lock_flags,
+	      const bool wait);
+int SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
+		     __u8 *lease_key, const __le32 lease_state);
+
+/*
+ * smb2transport.c
+ */
+int smb3_crypto_shash_allocate(struct TCP_Server_Info *server);
+struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32  tid);
+int generate_smb30signingkey(struct cifs_ses *ses,
+			     struct TCP_Server_Info *server);
+int generate_smb311signingkey(struct cifs_ses *ses,
+			      struct TCP_Server_Info *server);
+int smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server);
+int smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+		       bool log_error);
+struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
+				       struct smb_rqst *rqst);
+struct mid_q_entry *smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst);
+int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
+
+/*
+ * SMB2 Worker functions - most of protocol specific implementation details
+ * are contained within these calls.
+ */
+
+/* query path info from the server using SMB311 POSIX extensions*/
 
 #endif			/* _SMB2PROTO_H */
diff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h
index 73822800e36c..f600dc4a8eba 100644
--- a/fs/smb/client/smbdirect.h
+++ b/fs/smb/client/smbdirect.h
@@ -62,7 +62,6 @@ struct smbdirect_mr_io *smbd_register_mr(
 	bool writing, bool need_invalidate);
 void smbd_deregister_mr(struct smbdirect_mr_io *mr);
 
-/* PROTOTYPES */
 
 #else
 #define cifs_rdma_enabled(server)	0


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 04/11] cifs: Rename mid_q_entry to smb_message
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (2 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 03/11] cifs: Clean up declarations David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr David Howells
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Rename mid_q_entry to smb_message as future development that will allocate
it at a higher level in the marshalling code and then hand it down into the
transport layer.  It will also be used to pass parameters such as the send
and receive data buffers, credits and other things.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cifs_debug.c    |  43 +++---
 fs/smb/client/cifsfs.c        |  31 +++--
 fs/smb/client/cifsglob.h      |  70 +++++-----
 fs/smb/client/cifsproto.h     |  28 ++--
 fs/smb/client/cifssmb.c       |  82 ++++++------
 fs/smb/client/cifstransport.c | 168 ++++++++++++------------
 fs/smb/client/connect.c       | 152 +++++++++++-----------
 fs/smb/client/netmisc.c       |  14 +-
 fs/smb/client/smb1ops.c       |  46 +++----
 fs/smb/client/smb1proto.h     |   6 +-
 fs/smb/client/smb2misc.c      |   8 +-
 fs/smb/client/smb2ops.c       | 122 ++++++++---------
 fs/smb/client/smb2pdu.c       |  47 ++++---
 fs/smb/client/smb2proto.h     |  10 +-
 fs/smb/client/smb2transport.c |  62 ++++-----
 fs/smb/client/transport.c     | 238 +++++++++++++++++-----------------
 16 files changed, 564 insertions(+), 563 deletions(-)

diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 08538ad0f8dc..6d24d9cd6e09 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -55,33 +55,32 @@ void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
 void cifs_dump_mids(struct TCP_Server_Info *server)
 {
 #ifdef CONFIG_CIFS_DEBUG2
-	struct mid_q_entry *mid_entry;
+	struct smb_message *smb;
 
 	if (server == NULL)
 		return;
 
 	cifs_dbg(VFS, "Dump pending requests:\n");
 	spin_lock(&server->mid_queue_lock);
-	list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
+	list_for_each_entry(smb, &server->pending_mid_q, qhead) {
 		cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
-			 mid_entry->mid_state,
-			 le16_to_cpu(mid_entry->command),
-			 mid_entry->pid,
-			 mid_entry->callback_data,
-			 mid_entry->mid);
+			 smb->mid_state,
+			 le16_to_cpu(smb->command),
+			 smb->pid,
+			 smb->callback_data,
+			 smb->mid);
 #ifdef CONFIG_CIFS_STATS2
 		cifs_dbg(VFS, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n",
-			 mid_entry->large_buf,
-			 mid_entry->resp_buf,
-			 mid_entry->when_received,
+			 smb->large_buf,
+			 smb->resp_buf,
+			 smb->when_received,
 			 jiffies);
 #endif /* STATS2 */
 		cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n",
-			 mid_entry->multiRsp, mid_entry->multiEnd);
-		if (mid_entry->resp_buf) {
-			cifs_dump_detail(mid_entry->resp_buf, server);
-			cifs_dump_mem("existing buf: ",
-				mid_entry->resp_buf, 62);
+			 smb->multiRsp, smb->multiEnd);
+		if (smb->resp_buf) {
+			cifs_dump_detail(smb->resp_buf, server);
+			cifs_dump_mem("existing buf: ", smb->resp_buf, 62);
 		}
 	}
 	spin_unlock(&server->mid_queue_lock);
@@ -395,7 +394,7 @@ static __always_inline const char *cipher_alg_str(__le16 cipher)
 
 static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
 {
-	struct mid_q_entry *mid_entry;
+	struct smb_message *smb;
 	struct TCP_Server_Info *server;
 	struct TCP_Server_Info *chan_server;
 	struct cifs_ses *ses;
@@ -716,13 +715,13 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
 				seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
 					   chan_server->conn_id);
 				spin_lock(&chan_server->mid_queue_lock);
-				list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
+				list_for_each_entry(smb, &chan_server->pending_mid_q, qhead) {
 					seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
-						   mid_entry->mid_state,
-						   le16_to_cpu(mid_entry->command),
-						   mid_entry->pid,
-						   mid_entry->callback_data,
-						   mid_entry->mid);
+						   smb->mid_state,
+						   le16_to_cpu(smb->command),
+						   smb->pid,
+						   smb->callback_data,
+						   smb->mid);
 				}
 				spin_unlock(&chan_server->mid_queue_lock);
 			}
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index cbb34e3e2862..ab1f4bf3de92 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -437,13 +437,13 @@ static int cifs_permission(struct mnt_idmap *idmap,
 
 static struct kmem_cache *cifs_inode_cachep;
 static struct kmem_cache *cifs_req_cachep;
-static struct kmem_cache *cifs_mid_cachep;
+static struct kmem_cache *smb_message_cachep;
 static struct kmem_cache *cifs_sm_req_cachep;
 static struct kmem_cache *cifs_io_request_cachep;
 static struct kmem_cache *cifs_io_subrequest_cachep;
 mempool_t *cifs_sm_req_poolp;
 mempool_t *cifs_req_poolp;
-mempool_t *cifs_mid_poolp;
+mempool_t smb_message_pool;
 mempool_t cifs_io_request_pool;
 mempool_t cifs_io_subrequest_pool;
 
@@ -1836,28 +1836,27 @@ cifs_destroy_request_bufs(void)
 	kmem_cache_destroy(cifs_sm_req_cachep);
 }
 
-static int init_mids(void)
+static int init_smb_message(void)
 {
-	cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
-					    sizeof(struct mid_q_entry), 0,
-					    SLAB_HWCACHE_ALIGN, NULL);
-	if (cifs_mid_cachep == NULL)
+	smb_message_cachep = kmem_cache_create("cifs_smb_message",
+					       sizeof(struct smb_message), 0,
+					       SLAB_HWCACHE_ALIGN, NULL);
+	if (smb_message_cachep == NULL)
 		return -ENOMEM;
 
 	/* 3 is a reasonable minimum number of simultaneous operations */
-	cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
-	if (cifs_mid_poolp == NULL) {
-		kmem_cache_destroy(cifs_mid_cachep);
+	if (mempool_init_slab_pool(&smb_message_pool, 3, smb_message_cachep) < 0) {
+		kmem_cache_destroy(smb_message_cachep);
 		return -ENOMEM;
 	}
 
 	return 0;
 }
 
-static void destroy_mids(void)
+static void destroy_smb_message(void)
 {
-	mempool_destroy(cifs_mid_poolp);
-	kmem_cache_destroy(cifs_mid_cachep);
+	mempool_exit(&smb_message_pool);
+	kmem_cache_destroy(smb_message_cachep);
 }
 
 static int cifs_init_netfs(void)
@@ -2021,7 +2020,7 @@ init_cifs(void)
 	if (rc)
 		goto out_destroy_inodecache;
 
-	rc = init_mids();
+	rc = init_smb_message();
 	if (rc)
 		goto out_destroy_netfs;
 
@@ -2078,7 +2077,7 @@ init_cifs(void)
 #endif
 	cifs_destroy_request_bufs();
 out_destroy_mids:
-	destroy_mids();
+	destroy_smb_message();
 out_destroy_netfs:
 	cifs_destroy_netfs();
 out_destroy_inodecache:
@@ -2120,7 +2119,7 @@ exit_cifs(void)
 	dfs_cache_destroy();
 #endif
 	cifs_destroy_request_bufs();
-	destroy_mids();
+	destroy_smb_message();
 	cifs_destroy_netfs();
 	cifs_destroy_inodecache();
 	destroy_workqueue(deferredclose_wq);
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index c74df2260d6b..a4f396115e92 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -294,7 +294,7 @@ struct smb_rqst {
 	struct folio_queue *rq_buffer;	/* Buffer for encryption */
 };
 
-struct mid_q_entry;
+struct smb_message;
 struct TCP_Server_Info;
 struct cifsFileInfo;
 struct cifs_ses;
@@ -312,24 +312,24 @@ struct cifs_credits;
 
 struct smb_version_operations {
 	int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *,
-			   struct mid_q_entry *);
+			   struct smb_message *smb);
 	bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *);
 	/* setup request: allocate mid, sign message */
-	struct mid_q_entry *(*setup_request)(struct cifs_ses *,
-					     struct TCP_Server_Info *,
-					     struct smb_rqst *);
+	struct smb_message *(*setup_request)(struct cifs_ses *ses,
+					     struct TCP_Server_Info *server,
+					     struct smb_rqst *rqst);
 	/* setup async request: allocate mid, sign message */
-	struct mid_q_entry *(*setup_async_request)(struct TCP_Server_Info *,
-						struct smb_rqst *);
+	struct smb_message *(*setup_async_request)(struct TCP_Server_Info *server,
+						   struct smb_rqst *rqst);
 	/* check response: verify signature, map error */
-	int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
-			     bool);
+	int (*check_receive)(struct smb_message *mid, struct TCP_Server_Info *server,
+			     bool log_error);
 	void (*add_credits)(struct TCP_Server_Info *server,
 			    struct cifs_credits *credits,
 			    const int optype);
 	void (*set_credits)(struct TCP_Server_Info *, const int);
 	int * (*get_credits_field)(struct TCP_Server_Info *, const int);
-	unsigned int (*get_credits)(struct mid_q_entry *);
+	unsigned int (*get_credits)(struct smb_message *smb);
 	__u64 (*get_next_mid)(struct TCP_Server_Info *);
 	void (*revert_current_mid)(struct TCP_Server_Info *server,
 				   const unsigned int val);
@@ -346,7 +346,7 @@ struct smb_version_operations {
 	/* map smb to linux error */
 	int (*map_error)(char *, bool);
 	/* find mid corresponding to the response message */
-	struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *);
+	struct smb_message * (*find_mid)(struct TCP_Server_Info *server, char *buf);
 	void (*dump_detail)(void *buf, struct TCP_Server_Info *ptcp_info);
 	void (*clear_stats)(struct cifs_tcon *);
 	void (*print_stats)(struct seq_file *m, struct cifs_tcon *);
@@ -354,13 +354,13 @@ struct smb_version_operations {
 	/* verify the message */
 	int (*check_message)(char *, unsigned int, struct TCP_Server_Info *);
 	bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
-	int (*handle_cancelled_mid)(struct mid_q_entry *, 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,
 				 struct cifsInodeInfo *cinode, __u32 oplock,
 				 __u16 epoch, bool *purge_cache);
 	/* process transaction2 response */
-	bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
-			     char *, int);
+	bool (*check_trans2)(struct smb_message *smb, struct TCP_Server_Info *server,
+			     char *buf, int malformed);
 	/* check if we need to negotiate */
 	bool (*need_neg)(struct TCP_Server_Info *);
 	/* negotiate to the server */
@@ -594,7 +594,7 @@ struct smb_version_operations {
 				 struct smb_rqst *, struct smb_rqst *);
 	int (*is_transform_hdr)(void *buf);
 	int (*receive_transform)(struct TCP_Server_Info *,
-				 struct mid_q_entry **, char **, int *);
+				 struct smb_message **smb, char **, int *);
 	enum securityEnum (*select_sectype)(struct TCP_Server_Info *,
 			    enum securityEnum);
 	int (*next_header)(struct TCP_Server_Info *server, char *buf,
@@ -1642,8 +1642,8 @@ static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
  * Returns zero on a successful receive, or an error. The receive state in
  * the TCP_Server_Info will also be updated.
  */
-typedef int (mid_receive_t)(struct TCP_Server_Info *server,
-			    struct mid_q_entry *mid);
+typedef int (*mid_receive_t)(struct TCP_Server_Info *server,
+			     struct smb_message *msg);
 
 /*
  * This is the prototype for the mid callback function. This is called once the
@@ -1653,17 +1653,17 @@ typedef int (mid_receive_t)(struct TCP_Server_Info *server,
  * - it will be called by cifsd, with no locks held
  * - the mid will be removed from any lists
  */
-typedef void (mid_callback_t)(struct mid_q_entry *mid);
+typedef void (*mid_callback_t)(struct smb_message *smb);
 
 /*
  * This is the protopyte for mid handle function. This is called once the mid
  * has been recognized after decryption of the message.
  */
-typedef int (mid_handle_t)(struct TCP_Server_Info *server,
-			    struct mid_q_entry *mid);
+typedef int (*mid_handle_t)(struct TCP_Server_Info *server,
+			    struct smb_message *smb);
 
 /* one of these for every pending CIFS request to the server */
-struct mid_q_entry {
+struct smb_message {
 	struct list_head qhead;	/* mids waiting on reply from this server */
 	struct kref refcount;
 	struct TCP_Server_Info *server;	/* server corresponding to this mid */
@@ -1677,9 +1677,9 @@ struct mid_q_entry {
 	unsigned long when_sent; /* time when smb send finished */
 	unsigned long when_received; /* when demux complete (taken off wire) */
 #endif
-	mid_receive_t *receive; /* call receive callback */
-	mid_callback_t *callback; /* call completion callback */
-	mid_handle_t *handle; /* call handle mid callback */
+	mid_receive_t receive; /* call receive callback */
+	mid_callback_t callback; /* call completion callback */
+	mid_handle_t handle; /* call handle mid callback */
 	void *callback_data;	  /* general purpose pointer for callback */
 	struct task_struct *creator;
 	void *resp_buf;		/* pointer to received SMB header */
@@ -1728,12 +1728,12 @@ static inline void cifs_num_waiters_dec(struct TCP_Server_Info *server)
 }
 
 #ifdef CONFIG_CIFS_STATS2
-static inline void cifs_save_when_sent(struct mid_q_entry *mid)
+static inline void cifs_save_when_sent(struct smb_message *smb)
 {
-	mid->when_sent = jiffies;
+	smb->when_sent = jiffies;
 }
 #else
-static inline void cifs_save_when_sent(struct mid_q_entry *mid)
+static inline void cifs_save_when_sent(struct smb_message *smb)
 {
 }
 #endif
@@ -2082,7 +2082,7 @@ extern __u32 cifs_lock_secret;
 
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
-extern mempool_t *cifs_mid_poolp;
+extern mempool_t smb_message_pool;
 extern mempool_t cifs_io_request_pool;
 extern mempool_t cifs_io_subrequest_pool;
 
@@ -2329,17 +2329,17 @@ static inline bool cifs_netbios_name(const char *name, size_t namelen)
  * Execute mid callback atomically - ensures callback runs exactly once
  * and prevents sleeping in atomic context.
  */
-static inline void mid_execute_callback(struct mid_q_entry *mid)
+static inline void mid_execute_callback(struct smb_message *smb)
 {
-	void (*callback)(struct mid_q_entry *mid);
+	mid_callback_t callback;
 
-	spin_lock(&mid->mid_lock);
-	callback = mid->callback;
-	mid->callback = NULL;  /* Mark as executed, */
-	spin_unlock(&mid->mid_lock);
+	spin_lock(&smb->mid_lock);
+	callback = smb->callback;
+	smb->callback = NULL;  /* Mark as executed, */
+	spin_unlock(&smb->mid_lock);
 
 	if (callback)
-		callback(mid);
+		callback(smb);
 }
 
 #define CIFS_REPARSE_SUPPORT(tcon) \
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 16b9ad555793..8d95efbad712 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -137,9 +137,9 @@ int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
 ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read);
 int cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter,
 			       unsigned int to_read);
-void dequeue_mid(struct mid_q_entry *mid, bool malformed);
+void dequeue_mid(struct smb_message *mid, bool malformed);
 int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
-int cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid);
+int cifs_handle_standard(struct TCP_Server_Info *server, struct smb_message *mid);
 int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs);
 bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
 struct TCP_Server_Info *cifs_find_tcp_session(struct smb3_fs_context *ctx);
@@ -438,7 +438,7 @@ struct vfsmount *cifs_d_automount(struct path *path);
 int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
 void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
 int map_smb_to_linux_error(char *buf, bool logErr);
-int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr);
+int map_and_check_smb_error(struct smb_message *mid, bool logErr);
 unsigned int smbCalcSize(void *buf);
 struct timespec64 cifs_NTtimeToUnix(__le64 ntutc);
 u64 cifs_UnixTimeToNT(struct timespec64 t);
@@ -526,9 +526,9 @@ int E_md4hash(const unsigned char *passwd, unsigned char *p16,
 /*
  * transport.c
  */
-void cifs_wake_up_task(struct mid_q_entry *mid);
+void cifs_wake_up_task(struct smb_message *mid);
 void __release_mid(struct kref *refcount);
-void delete_mid(struct mid_q_entry *mid);
+void delete_mid(struct smb_message *mid);
 int smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
 		  size_t *sent);
 unsigned long smb_rqst_len(struct TCP_Server_Info *server, struct smb_rqst *rqst);
@@ -538,12 +538,12 @@ int wait_for_free_request(struct TCP_Server_Info *server, const int flags,
 			  unsigned int *instance);
 int cifs_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
 			  size_t *num, struct cifs_credits *credits);
-int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ);
+int wait_for_response(struct TCP_Server_Info *server, struct smb_message *midQ);
 int cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-		    mid_receive_t *receive, mid_callback_t *callback,
-		    mid_handle_t *handle, void *cbdata, const int flags,
+		    mid_receive_t receive, mid_callback_t callback,
+		    mid_handle_t handle, void *cbdata, const int flags,
 		    const struct cifs_credits *exist_credits);
-int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server);
+int cifs_sync_mid_result(struct smb_message *mid, struct TCP_Server_Info *server);
 struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
 int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 		       struct TCP_Server_Info *server,
@@ -554,7 +554,7 @@ int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
 		   struct smb_rqst *rqst, int *resp_buf_type, const int flags,
 		   struct kvec *resp_iov);
 int cifs_discard_remaining_data(struct TCP_Server_Info *server);
-int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
+int cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *mid);
 
 /*
  * unc.c
@@ -608,10 +608,10 @@ static inline void free_dentry_path(void *page)
 
 static inline int
 send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-	    struct mid_q_entry *mid)
+	    struct smb_message *smb)
 {
 	return server->ops->send_cancel ?
-				server->ops->send_cancel(server, rqst, mid) : 0;
+				server->ops->send_cancel(server, rqst, smb) : 0;
 }
 
 struct cifs_unix_set_info_args {
@@ -690,9 +690,9 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
 	return true;
 }
 
-static inline void release_mid(struct mid_q_entry *mid)
+static inline void release_mid(struct smb_message *smb)
 {
-	kref_put(&mid->refcount, __release_mid);
+	kref_put(&smb->refcount, __release_mid);
 }
 
 static inline void cifs_free_open_info(struct cifs_open_info_data *data)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 85a9fa3b3768..884eb53618e6 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -578,12 +578,12 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
  * FIXME: maybe we should consider checking that the reply matches request?
  */
 static void
-cifs_echo_callback(struct mid_q_entry *mid)
+cifs_echo_callback(struct smb_message *smb)
 {
-	struct TCP_Server_Info *server = mid->callback_data;
+	struct TCP_Server_Info *server = smb->callback_data;
 	struct cifs_credits credits = { .value = 1, .instance = 0 };
 
-	release_mid(mid);
+	release_mid(smb);
 	add_credits(server, &credits, CIFS_ECHO_OP);
 }
 
@@ -1297,9 +1297,9 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
 }
 
 static void
-cifs_readv_callback(struct mid_q_entry *mid)
+cifs_readv_callback(struct smb_message *smb)
 {
-	struct cifs_io_subrequest *rdata = mid->callback_data;
+	struct cifs_io_subrequest *rdata = smb->callback_data;
 	struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
 	struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
 	struct TCP_Server_Info *server = tcon->ses->server;
@@ -1316,10 +1316,10 @@ cifs_readv_callback(struct mid_q_entry *mid)
 	unsigned int subreq_debug_index = rdata->subreq.debug_index;
 
 	cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
-		 __func__, mid->mid, mid->mid_state, rdata->result,
+		 __func__, smb->mid, smb->mid_state, rdata->result,
 		 rdata->subreq.len);
 
-	switch (mid->mid_state) {
+	switch (smb->mid_state) {
 	case MID_RESPONSE_RECEIVED:
 		/* result already set, check signature */
 		if (server->sign) {
@@ -1327,7 +1327,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
 
 			iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
 			rc = cifs_verify_signature(&rqst, server,
-						  mid->sequence_number);
+						  smb->sequence_number);
 			if (rc)
 				cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
 					 rc);
@@ -1400,7 +1400,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
 	rdata->subreq.transferred += rdata->got_bytes;
 	trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
 	netfs_read_subreq_terminated(&rdata->subreq);
-	release_mid(mid);
+	release_mid(smb);
 	add_credits(server, &credits, 0);
 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
 			      server->credits, server->in_flight,
@@ -1713,12 +1713,12 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
  * workqueue completion task.
  */
 static void
-cifs_writev_callback(struct mid_q_entry *mid)
+cifs_writev_callback(struct smb_message *smb)
 {
-	struct cifs_io_subrequest *wdata = mid->callback_data;
+	struct cifs_io_subrequest *wdata = smb->callback_data;
 	struct TCP_Server_Info *server = wdata->server;
 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
-	WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
+	WRITE_RSP *rsp = (WRITE_RSP *)smb->resp_buf;
 	struct cifs_credits credits = {
 		.value = 1,
 		.instance = 0,
@@ -1728,15 +1728,15 @@ cifs_writev_callback(struct mid_q_entry *mid)
 	ssize_t result;
 	size_t written;
 
-	switch (mid->mid_state) {
+	switch (smb->mid_state) {
 	case MID_RESPONSE_RECEIVED:
-		result = cifs_check_receive(mid, tcon->ses->server, 0);
+		result = cifs_check_receive(smb, tcon->ses->server, 0);
 		if (result != 0)
 			break;
 
-		written = le16_to_cpu(smb->CountHigh);
+		written = le16_to_cpu(rsp->CountHigh);
 		written <<= 16;
-		written += le16_to_cpu(smb->Count);
+		written += le16_to_cpu(rsp->Count);
 		/*
 		 * Mask off high 16 bits when bytes written as returned
 		 * by the server is greater than bytes requested by the
@@ -1780,7 +1780,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
 			      0, cifs_trace_rw_credits_write_response_clear);
 	wdata->credits.value = 0;
 	cifs_write_subrequest_terminated(wdata, result);
-	release_mid(mid);
+	release_mid(smb);
 	trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
 			      server->credits, server->in_flight,
 			      credits.value, cifs_trace_rw_credits_write_response_add);
@@ -1792,7 +1792,7 @@ void
 cifs_async_writev(struct cifs_io_subrequest *wdata)
 {
 	int rc = -EACCES;
-	WRITE_REQ *smb = NULL;
+	WRITE_REQ *req = NULL;
 	int wct;
 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
 	struct kvec iov[2];
@@ -1809,30 +1809,30 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
 		}
 	}
 
-	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
+	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&req);
 	if (rc)
 		goto async_writev_out;
 
-	smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid);
-	smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16));
+	req->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid);
+	req->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16));
 
-	smb->AndXCommand = 0xFF;	/* none */
-	smb->Fid = wdata->req->cfile->fid.netfid;
-	smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
+	req->AndXCommand = 0xFF;	/* none */
+	req->Fid = wdata->req->cfile->fid.netfid;
+	req->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
 	if (wct == 14)
-		smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
-	smb->Reserved = 0xFFFFFFFF;
-	smb->WriteMode = 0;
-	smb->Remaining = 0;
+		req->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
+	req->Reserved = 0xFFFFFFFF;
+	req->WriteMode = 0;
+	req->Remaining = 0;
 
-	smb->DataOffset =
+	req->DataOffset =
 	    cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
 
 	/* 4 for RFC1001 length + 1 for BCC */
 	iov[0].iov_len = 4;
-	iov[0].iov_base = smb;
-	iov[1].iov_len = get_rfc1002_len(smb) + 1;
-	iov[1].iov_base = (char *)smb + 4;
+	iov[0].iov_base = req;
+	iov[1].iov_len = get_rfc1002_len(req) + 1;
+	iov[1].iov_base = (char *)req + 4;
 
 	rqst.rq_iov = iov;
 	rqst.rq_nvec = 2;
@@ -1841,18 +1841,18 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
 	cifs_dbg(FYI, "async write at %llu %zu bytes\n",
 		 wdata->subreq.start, wdata->subreq.len);
 
-	smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
-	smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
+	req->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
+	req->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
 
 	if (wct == 14) {
-		inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1);
-		put_bcc(wdata->subreq.len + 1, &smb->hdr);
+		inc_rfc1001_len(&req->hdr, wdata->subreq.len + 1);
+		put_bcc(wdata->subreq.len + 1, &req->hdr);
 	} else {
 		/* wct == 12 */
-		struct smb_com_writex_req *smbw =
-				(struct smb_com_writex_req *)smb;
-		inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5);
-		put_bcc(wdata->subreq.len + 5, &smbw->hdr);
+		struct smb_com_writex_req *reqw =
+				(struct smb_com_writex_req *)req;
+		inc_rfc1001_len(&reqw->hdr, wdata->subreq.len + 5);
+		put_bcc(wdata->subreq.len + 5, &reqw->hdr);
 		iov[1].iov_len += 4; /* pad bigger by four bytes */
 	}
 
@@ -1863,7 +1863,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
 		cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
 
 async_writev_out:
-	cifs_small_buf_release(smb);
+	cifs_small_buf_release(req);
 out:
 	if (rc) {
 		add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 9b3711af6038..2ec25e2cc8ec 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -34,41 +34,41 @@
 /* Max number of iovectors we can use off the stack when sending requests. */
 #define CIFS_MAX_IOV_SIZE 8
 
-static struct mid_q_entry *
+static struct smb_message *
 alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
 {
-	struct mid_q_entry *temp;
+	struct smb_message *smb;
 
 	if (server == NULL) {
 		cifs_dbg(VFS, "%s: null TCP session\n", __func__);
 		return NULL;
 	}
 
-	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
-	memset(temp, 0, sizeof(struct mid_q_entry));
-	kref_init(&temp->refcount);
-	spin_lock_init(&temp->mid_lock);
-	temp->mid = get_mid(smb_buffer);
-	temp->pid = current->pid;
-	temp->command = cpu_to_le16(smb_buffer->Command);
+	smb = mempool_alloc(&smb_message_pool, GFP_NOFS);
+	memset(smb, 0, sizeof(struct smb_message));
+	kref_init(&smb->refcount);
+	spin_lock_init(&smb->mid_lock);
+	smb->mid = get_mid(smb_buffer);
+	smb->pid = current->pid;
+	smb->command = cpu_to_le16(smb_buffer->Command);
 	cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command);
 	/* easier to use jiffies */
 	/* when mid allocated can be before when sent */
-	temp->when_alloc = jiffies;
-	temp->server = server;
+	smb->when_alloc = jiffies;
+	smb->server = server;
 
 	/*
 	 * The default is for the mid to be synchronous, so the
 	 * default callback just wakes up the current task.
 	 */
 	get_task_struct(current);
-	temp->creator = current;
-	temp->callback = cifs_wake_up_task;
-	temp->callback_data = current;
+	smb->creator = current;
+	smb->callback = cifs_wake_up_task;
+	smb->callback_data = current;
 
 	atomic_inc(&mid_count);
-	temp->mid_state = MID_REQUEST_ALLOCATED;
-	return temp;
+	smb->mid_state = MID_REQUEST_ALLOCATED;
+	return smb;
 }
 
 int
@@ -88,7 +88,7 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
 }
 
 static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
-			struct mid_q_entry **ppmidQ)
+			struct smb_message **ppmidQ)
 {
 	spin_lock(&ses->ses_lock);
 	if (ses->ses_status == SES_NEW) {
@@ -119,12 +119,12 @@ static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
 	return 0;
 }
 
-struct mid_q_entry *
+struct smb_message *
 cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 {
 	int rc;
 	struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
-	struct mid_q_entry *mid;
+	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)
@@ -134,17 +134,17 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 	if (server->sign)
 		hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
-	mid = alloc_mid(hdr, server);
-	if (mid == NULL)
+	smb = alloc_mid(hdr, server);
+	if (smb == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
+	rc = cifs_sign_rqst(rqst, server, &smb->sequence_number);
 	if (rc) {
-		release_mid(mid);
+		release_mid(smb);
 		return ERR_PTR(rc);
 	}
 
-	return mid;
+	return smb;
 }
 
 /*
@@ -175,12 +175,12 @@ SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
 }
 
 int
-cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+cifs_check_receive(struct smb_message *smb, struct TCP_Server_Info *server,
 		   bool log_error)
 {
-	unsigned int len = get_rfc1002_len(mid->resp_buf) + 4;
+	unsigned int len = get_rfc1002_len(smb->resp_buf) + 4;
 
-	dump_smb(mid->resp_buf, min_t(u32, 92, len));
+	dump_smb(smb->resp_buf, min_t(u32, 92, len));
 
 	/* convert the length into a more usable form */
 	if (server->sign) {
@@ -189,43 +189,43 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 		struct smb_rqst rqst = { .rq_iov = iov,
 					 .rq_nvec = 2 };
 
-		iov[0].iov_base = mid->resp_buf;
+		iov[0].iov_base = smb->resp_buf;
 		iov[0].iov_len = 4;
-		iov[1].iov_base = (char *)mid->resp_buf + 4;
+		iov[1].iov_base = (char *)smb->resp_buf + 4;
 		iov[1].iov_len = len - 4;
 		/* FIXME: add code to kill session */
 		rc = cifs_verify_signature(&rqst, server,
-					   mid->sequence_number);
+					   smb->sequence_number);
 		if (rc)
 			cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n",
 				 rc);
 	}
 
 	/* BB special case reconnect tid and uid here? */
-	return map_and_check_smb_error(mid, log_error);
+	return map_and_check_smb_error(smb, log_error);
 }
 
-struct mid_q_entry *
+struct smb_message *
 cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
 		   struct smb_rqst *rqst)
 {
 	int rc;
 	struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
-	struct mid_q_entry *mid;
+	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, &mid);
+	rc = allocate_mid(ses, hdr, &smb);
 	if (rc)
 		return ERR_PTR(rc);
-	rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
+	rc = cifs_sign_rqst(rqst, ses->server, &smb->sequence_number);
 	if (rc) {
-		delete_mid(mid);
+		delete_mid(smb);
 		return ERR_PTR(rc);
 	}
-	return mid;
+	return smb;
 }
 
 int
@@ -273,7 +273,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 	    int *pbytes_returned, const int flags)
 {
 	int rc = 0;
-	struct mid_q_entry *midQ;
+	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 smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
@@ -317,7 +317,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 
 	cifs_server_lock(server);
 
-	rc = allocate_mid(ses, in_buf, &midQ);
+	rc = allocate_mid(ses, in_buf, &smb);
 	if (rc) {
 		cifs_server_unlock(server);
 		/* Update # of requests on wire to server */
@@ -325,16 +325,16 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 		return rc;
 	}
 
-	rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number);
+	rc = cifs_sign_smb(in_buf, server, &smb->sequence_number);
 	if (rc) {
 		cifs_server_unlock(server);
 		goto out;
 	}
 
-	midQ->mid_state = MID_REQUEST_SUBMITTED;
+	smb->mid_state = MID_REQUEST_SUBMITTED;
 
 	rc = smb_send(server, in_buf, len);
-	cifs_save_when_sent(midQ);
+	cifs_save_when_sent(smb);
 
 	if (rc < 0)
 		server->sequence_number -= 2;
@@ -344,38 +344,39 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 	if (rc < 0)
 		goto out;
 
-	rc = wait_for_response(server, midQ);
+	rc = wait_for_response(server, smb);
 	if (rc != 0) {
-		send_cancel(server, &rqst, midQ);
-		spin_lock(&midQ->mid_lock);
-		if (midQ->callback) {
+		send_cancel(server, &rqst, smb);
+		spin_lock(&smb->mid_lock);
+		if (smb->mid_state == MID_REQUEST_SUBMITTED ||
+		    smb->mid_state == MID_RESPONSE_RECEIVED) {
 			/* no longer considered to be "in-flight" */
-			midQ->callback = release_mid;
-			spin_unlock(&midQ->mid_lock);
+			smb->callback = release_mid;
+			spin_unlock(&smb->mid_lock);
 			add_credits(server, &credits, 0);
 			return rc;
 		}
-		spin_unlock(&midQ->mid_lock);
+		spin_unlock(&smb->mid_lock);
 	}
 
-	rc = cifs_sync_mid_result(midQ, server);
+	rc = cifs_sync_mid_result(smb, server);
 	if (rc != 0) {
 		add_credits(server, &credits, 0);
 		return rc;
 	}
 
-	if (!midQ->resp_buf || !out_buf ||
-	    midQ->mid_state != MID_RESPONSE_READY) {
+	if (!smb->resp_buf || !out_buf ||
+	    smb->mid_state != MID_RESPONSE_READY) {
 		rc = -EIO;
 		cifs_server_dbg(VFS, "Bad MID state?\n");
 		goto out;
 	}
 
-	*pbytes_returned = get_rfc1002_len(midQ->resp_buf);
-	memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
-	rc = cifs_check_receive(midQ, server, 0);
+	*pbytes_returned = get_rfc1002_len(smb->resp_buf);
+	memcpy(out_buf, smb->resp_buf, *pbytes_returned + 4);
+	rc = cifs_check_receive(smb, server, 0);
 out:
-	delete_mid(midQ);
+	delete_mid(smb);
 	add_credits(server, &credits, 0);
 
 	return rc;
@@ -413,7 +414,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 {
 	int rc = 0;
 	int rstart = 0;
-	struct mid_q_entry *midQ;
+	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 };
@@ -460,22 +461,22 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 
 	cifs_server_lock(server);
 
-	rc = allocate_mid(ses, in_buf, &midQ);
+	rc = allocate_mid(ses, in_buf, &smb);
 	if (rc) {
 		cifs_server_unlock(server);
 		return rc;
 	}
 
-	rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number);
+	rc = cifs_sign_smb(in_buf, server, &smb->sequence_number);
 	if (rc) {
-		delete_mid(midQ);
+		delete_mid(smb);
 		cifs_server_unlock(server);
 		return rc;
 	}
 
-	midQ->mid_state = MID_REQUEST_SUBMITTED;
+	smb->mid_state = MID_REQUEST_SUBMITTED;
 	rc = smb_send(server, in_buf, len);
-	cifs_save_when_sent(midQ);
+	cifs_save_when_sent(smb);
 
 	if (rc < 0)
 		server->sequence_number -= 2;
@@ -483,22 +484,22 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 	cifs_server_unlock(server);
 
 	if (rc < 0) {
-		delete_mid(midQ);
+		delete_mid(smb);
 		return rc;
 	}
 
 	/* Wait for a reply - allow signals to interrupt. */
 	rc = wait_event_interruptible(server->response_q,
-		(!(midQ->mid_state == MID_REQUEST_SUBMITTED ||
-		   midQ->mid_state == MID_RESPONSE_RECEIVED)) ||
+		(!(smb->mid_state == MID_REQUEST_SUBMITTED ||
+		   smb->mid_state == MID_RESPONSE_RECEIVED)) ||
 		((server->tcpStatus != CifsGood) &&
 		 (server->tcpStatus != CifsNew)));
 
 	/* Were we interrupted by a signal ? */
 	spin_lock(&server->srv_lock);
 	if ((rc == -ERESTARTSYS) &&
-		(midQ->mid_state == MID_REQUEST_SUBMITTED ||
-		 midQ->mid_state == MID_RESPONSE_RECEIVED) &&
+		(smb->mid_state == MID_REQUEST_SUBMITTED ||
+		 smb->mid_state == MID_RESPONSE_RECEIVED) &&
 		((server->tcpStatus == CifsGood) ||
 		 (server->tcpStatus == CifsNew))) {
 		spin_unlock(&server->srv_lock);
@@ -506,9 +507,9 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 		if (in_buf->Command == SMB_COM_TRANSACTION2) {
 			/* POSIX lock. We send a NT_CANCEL SMB to cause the
 			   blocking lock to return. */
-			rc = send_cancel(server, &rqst, midQ);
+			rc = send_cancel(server, &rqst, smb);
 			if (rc) {
-				delete_mid(midQ);
+				delete_mid(smb);
 				return rc;
 			}
 		} else {
@@ -520,22 +521,23 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 			/* If we get -ENOLCK back the lock may have
 			   already been removed. Don't exit in this case. */
 			if (rc && rc != -ENOLCK) {
-				delete_mid(midQ);
+				delete_mid(smb);
 				return rc;
 			}
 		}
 
-		rc = wait_for_response(server, midQ);
+		rc = wait_for_response(server, smb);
 		if (rc) {
-			send_cancel(server, &rqst, midQ);
-			spin_lock(&midQ->mid_lock);
-			if (midQ->callback) {
+			send_cancel(server, &rqst, smb);
+			spin_lock(&smb->mid_lock);
+			if (smb->mid_state == MID_REQUEST_SUBMITTED ||
+			    smb->mid_state == MID_RESPONSE_RECEIVED) {
 				/* no longer considered to be "in-flight" */
-				midQ->callback = release_mid;
-				spin_unlock(&midQ->mid_lock);
+				smb->callback = release_mid;
+				spin_unlock(&smb->mid_lock);
 				return rc;
 			}
-			spin_unlock(&midQ->mid_lock);
+			spin_unlock(&smb->mid_lock);
 		}
 
 		/* We got the response - restart system call. */
@@ -544,22 +546,22 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 	}
 	spin_unlock(&server->srv_lock);
 
-	rc = cifs_sync_mid_result(midQ, server);
+	rc = cifs_sync_mid_result(smb, server);
 	if (rc != 0)
 		return rc;
 
 	/* rcvd frame is ok */
-	if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) {
+	if (out_buf == NULL || smb->mid_state != MID_RESPONSE_READY) {
 		rc = -EIO;
 		cifs_tcon_dbg(VFS, "Bad MID state?\n");
 		goto out;
 	}
 
-	*pbytes_returned = get_rfc1002_len(midQ->resp_buf);
-	memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
-	rc = cifs_check_receive(midQ, server, 0);
+	*pbytes_returned = get_rfc1002_len(smb->resp_buf);
+	memcpy(out_buf, smb->resp_buf, *pbytes_returned + 4);
+	rc = cifs_check_receive(smb, server, 0);
 out:
-	delete_mid(midQ);
+	delete_mid(smb);
 	if (rstart && rc == -EACCES)
 		return -ERESTARTSYS;
 	return rc;
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 338f11a9e4ad..ee61eb8d909f 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -294,7 +294,7 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
 static void
 cifs_abort_connection(struct TCP_Server_Info *server)
 {
-	struct mid_q_entry *mid, *nmid;
+	struct smb_message *smb, *nsmb;
 	struct list_head retry_list;
 
 	server->maxBuf = 0;
@@ -325,21 +325,21 @@ cifs_abort_connection(struct TCP_Server_Info *server)
 	INIT_LIST_HEAD(&retry_list);
 	cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
 	spin_lock(&server->mid_queue_lock);
-	list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {
-		kref_get(&mid->refcount);
-		if (mid->mid_state == MID_REQUEST_SUBMITTED)
-			mid->mid_state = MID_RETRY_NEEDED;
-		list_move(&mid->qhead, &retry_list);
-		mid->deleted_from_q = true;
+	list_for_each_entry_safe(smb, nsmb, &server->pending_mid_q, qhead) {
+		kref_get(&smb->refcount);
+		if (smb->mid_state == MID_REQUEST_SUBMITTED)
+			smb->mid_state = MID_RETRY_NEEDED;
+		list_move(&smb->qhead, &retry_list);
+		smb->deleted_from_q = true;
 	}
 	spin_unlock(&server->mid_queue_lock);
 	cifs_server_unlock(server);
 
 	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
-	list_for_each_entry_safe(mid, nmid, &retry_list, qhead) {
-		list_del_init(&mid->qhead);
-		mid_execute_callback(mid);
-		release_mid(mid);
+	list_for_each_entry_safe(smb, nsmb, &retry_list, qhead) {
+		list_del_init(&smb->qhead);
+		mid_execute_callback(smb);
+		release_mid(smb);
 	}
 }
 
@@ -869,7 +869,7 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 		    !server->with_rfc1001 &&
 		    server->rfc1001_sessinit != 0) {
 			int rc, mid_rc;
-			struct mid_q_entry *mid, *nmid;
+			struct smb_message *smb, *nsmb;
 			LIST_HEAD(dispose_list);
 
 			cifs_dbg(FYI, "RFC 1002 negative session response during SMB Negotiate, retrying with NetBIOS session\n");
@@ -882,10 +882,10 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 			 * corresponding to SMB1/SMB2 Negotiate packet.
 			 */
 			spin_lock(&server->mid_queue_lock);
-			list_for_each_entry_safe(mid, nmid, &server->pending_mid_q, qhead) {
-				kref_get(&mid->refcount);
-				list_move(&mid->qhead, &dispose_list);
-				mid->deleted_from_q = true;
+			list_for_each_entry_safe(smb, nsmb, &server->pending_mid_q, qhead) {
+				kref_get(&smb->refcount);
+				list_move(&smb->qhead, &dispose_list);
+				smb->deleted_from_q = true;
 			}
 			spin_unlock(&server->mid_queue_lock);
 
@@ -912,12 +912,12 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 			 * callback. Use MID_RC state which indicates that the
 			 * return code should be read from mid_rc member.
 			 */
-			list_for_each_entry_safe(mid, nmid, &dispose_list, qhead) {
-				list_del_init(&mid->qhead);
-				mid->mid_rc = mid_rc;
-				mid->mid_state = MID_RC;
-				mid_execute_callback(mid);
-				release_mid(mid);
+			list_for_each_entry_safe(smb, nsmb, &dispose_list, qhead) {
+				list_del_init(&smb->qhead);
+				smb->mid_rc = mid_rc;
+				smb->mid_state = MID_RC;
+				mid_execute_callback(smb);
+				release_mid(smb);
 			}
 
 			/*
@@ -949,27 +949,27 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 }
 
 void
-dequeue_mid(struct mid_q_entry *mid, bool malformed)
+dequeue_mid(struct smb_message *smb, bool malformed)
 {
 #ifdef CONFIG_CIFS_STATS2
-	mid->when_received = jiffies;
+	smb->when_received = jiffies;
 #endif
-	spin_lock(&mid->server->mid_queue_lock);
+	spin_lock(&smb->server->mid_queue_lock);
 	if (!malformed)
-		mid->mid_state = MID_RESPONSE_RECEIVED;
+		smb->mid_state = MID_RESPONSE_RECEIVED;
 	else
-		mid->mid_state = MID_RESPONSE_MALFORMED;
+		smb->mid_state = MID_RESPONSE_MALFORMED;
 	/*
 	 * Trying to handle/dequeue a mid after the send_recv()
 	 * function has finished processing it is a bug.
 	 */
-	if (mid->deleted_from_q == true) {
-		spin_unlock(&mid->server->mid_queue_lock);
+	if (smb->deleted_from_q) {
+		spin_unlock(&smb->server->mid_queue_lock);
 		pr_warn_once("trying to dequeue a deleted mid\n");
 	} else {
-		list_del_init(&mid->qhead);
-		mid->deleted_from_q = true;
-		spin_unlock(&mid->server->mid_queue_lock);
+		list_del_init(&smb->qhead);
+		smb->deleted_from_q = true;
+		spin_unlock(&smb->server->mid_queue_lock);
 	}
 }
 
@@ -988,24 +988,24 @@ smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
 }
 
 static void
-handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+handle_mid(struct smb_message *smb, struct TCP_Server_Info *server,
 	   char *buf, int malformed)
 {
 	if (server->ops->check_trans2 &&
-	    server->ops->check_trans2(mid, server, buf, malformed))
+	    server->ops->check_trans2(smb, server, buf, malformed))
 		return;
-	mid->credits_received = smb2_get_credits_from_hdr(buf, server);
-	mid->resp_buf = buf;
-	mid->large_buf = server->large_buf;
+	smb->credits_received = smb2_get_credits_from_hdr(buf, server);
+	smb->resp_buf = buf;
+	smb->large_buf = server->large_buf;
 	/* Was previous buf put in mpx struct for multi-rsp? */
-	if (!mid->multiRsp) {
+	if (!smb->multiRsp) {
 		/* smb buffer will be freed by user thread */
 		if (server->large_buf)
 			server->bigbuf = NULL;
 		else
 			server->smallbuf = NULL;
 	}
-	dequeue_mid(mid, malformed);
+	dequeue_mid(smb, malformed);
 }
 
 int
@@ -1094,28 +1094,28 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
 	}
 
 	if (!list_empty(&server->pending_mid_q)) {
-		struct mid_q_entry *mid_entry;
+		struct smb_message *smb;
 		struct list_head *tmp, *tmp2;
 		LIST_HEAD(dispose_list);
 
 		spin_lock(&server->mid_queue_lock);
 		list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
-			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-			cifs_dbg(FYI, "Clearing mid %llu\n", mid_entry->mid);
-			kref_get(&mid_entry->refcount);
-			mid_entry->mid_state = MID_SHUTDOWN;
-			list_move(&mid_entry->qhead, &dispose_list);
-			mid_entry->deleted_from_q = true;
+			smb = list_entry(tmp, struct smb_message, qhead);
+			cifs_dbg(FYI, "Clearing mid %llu\n", smb->mid);
+			kref_get(&smb->refcount);
+			smb->mid_state = MID_SHUTDOWN;
+			list_move(&smb->qhead, &dispose_list);
+			smb->deleted_from_q = true;
 		}
 		spin_unlock(&server->mid_queue_lock);
 
 		/* now walk dispose list and issue callbacks */
 		list_for_each_safe(tmp, tmp2, &dispose_list) {
-			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-			cifs_dbg(FYI, "Callback mid %llu\n", mid_entry->mid);
-			list_del_init(&mid_entry->qhead);
-			mid_execute_callback(mid_entry);
-			release_mid(mid_entry);
+			smb = list_entry(tmp, struct smb_message, qhead);
+			cifs_dbg(FYI, "Callback mid %llu\n", smb->mid);
+			list_del_init(&smb->qhead);
+			mid_execute_callback(smb);
+			release_mid(smb);
 		}
 		/* 1/8th of sec is more than enough time for them to exit */
 		msleep(125);
@@ -1149,7 +1149,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
 }
 
 static int
-standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+standard_receive3(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	int length;
 	char *buf = server->smallbuf;
@@ -1180,11 +1180,11 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 
 	dump_smb(buf, server->total_read);
 
-	return cifs_handle_standard(server, mid);
+	return cifs_handle_standard(server, smb);
 }
 
 int
-cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+cifs_handle_standard(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
 	int rc;
@@ -1212,10 +1212,10 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 	    server->ops->is_status_pending(buf, server))
 		return -1;
 
-	if (!mid)
+	if (!smb)
 		return rc;
 
-	handle_mid(mid, server, buf, rc);
+	handle_mid(smb, server, buf, rc);
 	return 0;
 }
 
@@ -1252,13 +1252,13 @@ smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
 static int
 cifs_demultiplex_thread(void *p)
 {
-	int i, num_mids, length;
+	int i, num_smbs, length;
 	struct TCP_Server_Info *server = p;
 	unsigned int pdu_length;
 	unsigned int next_offset;
 	char *buf = NULL;
 	struct task_struct *task_to_wake = NULL;
-	struct mid_q_entry *mids[MAX_COMPOUND];
+	struct smb_message *smbs[MAX_COMPOUND];
 	char *bufs[MAX_COMPOUND];
 	unsigned int noreclaim_flag, num_io_timeout = 0;
 	bool pending_reconnect = false;
@@ -1333,32 +1333,32 @@ cifs_demultiplex_thread(void *p)
 				server->pdu_size = next_offset;
 		}
 
-		memset(mids, 0, sizeof(mids));
+		memset(smbs, 0, sizeof(smbs));
 		memset(bufs, 0, sizeof(bufs));
-		num_mids = 0;
+		num_smbs = 0;
 
 		if (server->ops->is_transform_hdr &&
 		    server->ops->receive_transform &&
 		    server->ops->is_transform_hdr(buf)) {
 			length = server->ops->receive_transform(server,
-								mids,
+								smbs,
 								bufs,
-								&num_mids);
+								&num_smbs);
 		} else {
-			mids[0] = server->ops->find_mid(server, buf);
+			smbs[0] = server->ops->find_mid(server, buf);
 			bufs[0] = buf;
-			num_mids = 1;
+			num_smbs = 1;
 
-			if (!mids[0] || !mids[0]->receive)
-				length = standard_receive3(server, mids[0]);
+			if (!smbs[0] || !smbs[0]->receive)
+				length = standard_receive3(server, smbs[0]);
 			else
-				length = mids[0]->receive(server, mids[0]);
+				length = smbs[0]->receive(server, smbs[0]);
 		}
 
 		if (length < 0) {
-			for (i = 0; i < num_mids; i++)
-				if (mids[i])
-					release_mid(mids[i]);
+			for (i = 0; i < num_smbs; i++)
+				if (smbs[i])
+					release_mid(smbs[i]);
 			continue;
 		}
 
@@ -1377,9 +1377,9 @@ cifs_demultiplex_thread(void *p)
 
 		server->lstrp = jiffies;
 
-		for (i = 0; i < num_mids; i++) {
-			if (mids[i] != NULL) {
-				mids[i]->resp_buf_size = server->pdu_size;
+		for (i = 0; i < num_smbs; i++) {
+			if (smbs[i] != NULL) {
+				smbs[i]->resp_buf_size = server->pdu_size;
 
 				if (bufs[i] != NULL) {
 					if (server->ops->is_network_name_deleted &&
@@ -1390,10 +1390,10 @@ cifs_demultiplex_thread(void *p)
 					}
 				}
 
-				if (!mids[i]->multiRsp || mids[i]->multiEnd)
-					mid_execute_callback(mids[i]);
+				if (!smbs[i]->multiRsp || smbs[i]->multiEnd)
+					mid_execute_callback(smbs[i]);
 
-				release_mid(mids[i]);
+				release_mid(smbs[i]);
 			} else if (server->ops->is_oplock_break &&
 				   server->ops->is_oplock_break(bufs[i],
 								server)) {
diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
index 4e0bb1920eae..fa994fae048b 100644
--- a/fs/smb/client/netmisc.c
+++ b/fs/smb/client/netmisc.c
@@ -889,22 +889,22 @@ map_smb_to_linux_error(char *buf, bool logErr)
 }
 
 int
-map_and_check_smb_error(struct mid_q_entry *mid, bool logErr)
+map_and_check_smb_error(struct smb_message *smb, bool logErr)
 {
 	int rc;
-	struct smb_hdr *smb = (struct smb_hdr *)mid->resp_buf;
+	struct smb_hdr *rhdr = (struct smb_hdr *)smb->resp_buf;
 
-	rc = map_smb_to_linux_error((char *)smb, logErr);
-	if (rc == -EACCES && !(smb->Flags2 & SMBFLG2_ERR_STATUS)) {
+	rc = map_smb_to_linux_error((char *)rhdr, logErr);
+	if (rc == -EACCES && !(rhdr->Flags2 & SMBFLG2_ERR_STATUS)) {
 		/* possible ERRBaduid */
-		__u8 class = smb->Status.DosError.ErrorClass;
-		__u16 code = le16_to_cpu(smb->Status.DosError.Error);
+		__u8 class = rhdr->Status.DosError.ErrorClass;
+		__u16 code = le16_to_cpu(rhdr->Status.DosError.Error);
 
 		/* switch can be used to handle different errors */
 		if (class == ERRSRV && code == ERRbaduid) {
 			cifs_dbg(FYI, "Server returned 0x%x, reconnecting session...\n",
 				code);
-			cifs_signal_cifsd_for_reconnect(mid->server, false);
+			cifs_signal_cifsd_for_reconnect(smb->server, false);
 		}
 	}
 
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 3af1e19e6a80..e22a09ac9e53 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -32,7 +32,7 @@
  */
 static int
 send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-	       struct mid_q_entry *mid)
+	       struct smb_message *smb)
 {
 	int rc = 0;
 	struct smb_hdr *in_buf = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
@@ -44,7 +44,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 	put_bcc(0, in_buf);
 
 	cifs_server_lock(server);
-	rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
+	rc = cifs_sign_smb(in_buf, server, &smb->sequence_number);
 	if (rc) {
 		cifs_server_unlock(server);
 		return rc;
@@ -91,20 +91,20 @@ cifs_read_data_length(char *buf, bool in_remaining)
 	       le16_to_cpu(rsp->DataLength);
 }
 
-static struct mid_q_entry *
+static struct smb_message *
 cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
 {
 	struct smb_hdr *buf = (struct smb_hdr *)buffer;
-	struct mid_q_entry *mid;
+	struct smb_message *smb;
 
 	spin_lock(&server->mid_queue_lock);
-	list_for_each_entry(mid, &server->pending_mid_q, qhead) {
-		if (compare_mid(mid->mid, buf) &&
-		    mid->mid_state == MID_REQUEST_SUBMITTED &&
-		    le16_to_cpu(mid->command) == buf->Command) {
-			kref_get(&mid->refcount);
+	list_for_each_entry(smb, &server->pending_mid_q, qhead) {
+		if (compare_mid(smb->mid, buf) &&
+		    smb->mid_state == MID_REQUEST_SUBMITTED &&
+		    le16_to_cpu(smb->command) == buf->Command) {
+			kref_get(&smb->refcount);
 			spin_unlock(&server->mid_queue_lock);
-			return mid;
+			return smb;
 		}
 	}
 	spin_unlock(&server->mid_queue_lock);
@@ -138,7 +138,7 @@ cifs_get_credits_field(struct TCP_Server_Info *server, const int optype)
 }
 
 static unsigned int
-cifs_get_credits(struct mid_q_entry *mid)
+cifs_get_credits(struct smb_message *smb)
 {
 	return 1;
 }
@@ -191,7 +191,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server)
 	 * did not time out).
 	 */
 	while (cur_mid != last_mid) {
-		struct mid_q_entry *mid_entry;
+		struct smb_message *smb;
 		unsigned int num_mids;
 
 		collision = false;
@@ -200,10 +200,10 @@ cifs_get_next_mid(struct TCP_Server_Info *server)
 
 		num_mids = 0;
 		spin_lock(&server->mid_queue_lock);
-		list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
+		list_for_each_entry(smb, &server->pending_mid_q, qhead) {
 			++num_mids;
-			if (mid_entry->mid == cur_mid &&
-			    mid_entry->mid_state == MID_REQUEST_SUBMITTED) {
+			if (smb->mid == cur_mid &&
+			    smb->mid_state == MID_REQUEST_SUBMITTED) {
 				/* This mid is in use, try a different one */
 				collision = true;
 				break;
@@ -389,22 +389,22 @@ cifs_downgrade_oplock(struct TCP_Server_Info *server,
 }
 
 static bool
-cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+cifs_check_trans2(struct smb_message *smb, struct TCP_Server_Info *server,
 		  char *buf, int malformed)
 {
 	if (malformed)
 		return false;
 	if (check2ndT2(buf) <= 0)
 		return false;
-	mid->multiRsp = true;
-	if (mid->resp_buf) {
+	smb->multiRsp = true;
+	if (smb->resp_buf) {
 		/* merge response - fix up 1st*/
-		malformed = coalesce_t2(buf, mid->resp_buf);
+		malformed = coalesce_t2(buf, smb->resp_buf);
 		if (malformed > 0)
 			return true;
 		/* All parts received or packet is malformed. */
-		mid->multiEnd = true;
-		dequeue_mid(mid, malformed);
+		smb->multiEnd = true;
+		dequeue_mid(smb, malformed);
 		return true;
 	}
 	if (!server->large_buf) {
@@ -412,8 +412,8 @@ cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 		cifs_dbg(VFS, "1st trans2 resp needs bigbuf\n");
 	} else {
 		/* Have first buffer */
-		mid->resp_buf = buf;
-		mid->large_buf = true;
+		smb->resp_buf = buf;
+		smb->large_buf = true;
 		server->bigbuf = NULL;
 	}
 	return true;
diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
index 496be436dcea..d06617f62d3b 100644
--- a/fs/smb/client/smb1proto.h
+++ b/fs/smb/client/smb1proto.h
@@ -210,12 +210,12 @@ int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
  */
 int smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
 	     unsigned int smb_buf_length);
-struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst);
+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);
-int cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+int cifs_check_receive(struct smb_message *mid, struct TCP_Server_Info *server,
 		       bool log_error);
-struct mid_q_entry *cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
+struct smb_message *cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
 				       struct smb_rqst *rqst);
 int SendReceive2(const unsigned int xid, struct cifs_ses *ses,
 		 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index 96bfe4c63ccf..f0eb25033d72 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -851,14 +851,14 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
 }
 
 int
-smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server)
+smb2_handle_cancelled_mid(struct smb_message *smb, struct TCP_Server_Info *server)
 {
-	struct smb2_hdr *hdr = mid->resp_buf;
-	struct smb2_create_rsp *rsp = mid->resp_buf;
+	struct smb2_hdr *hdr = smb->resp_buf;
+	struct smb2_create_rsp *rsp = smb->resp_buf;
 	struct cifs_tcon *tcon;
 	int rc;
 
-	if ((mid->optype & CIFS_CP_CREATE_CLOSE_OP) || hdr->Command != SMB2_CREATE ||
+	if ((smb->optype & CIFS_CP_CREATE_CLOSE_OP) || hdr->Command != SMB2_CREATE ||
 	    hdr->Status != STATUS_SUCCESS)
 		return 0;
 
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 24cdae973d13..bf401c686686 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -226,9 +226,9 @@ smb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
 }
 
 static unsigned int
-smb2_get_credits(struct mid_q_entry *mid)
+smb2_get_credits(struct smb_message *smb)
 {
-	return mid->credits_received;
+	return smb->credits_received;
 }
 
 static int
@@ -389,10 +389,10 @@ smb2_revert_current_mid(struct TCP_Server_Info *server, const unsigned int val)
 	spin_unlock(&server->mid_counter_lock);
 }
 
-static struct mid_q_entry *
+static struct smb_message *
 __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
 {
-	struct mid_q_entry *mid;
+	struct smb_message *smb;
 	struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
 	__u64 wire_mid = le64_to_cpu(shdr->MessageId);
 
@@ -402,30 +402,30 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
 	}
 
 	spin_lock(&server->mid_queue_lock);
-	list_for_each_entry(mid, &server->pending_mid_q, qhead) {
-		if ((mid->mid == wire_mid) &&
-		    (mid->mid_state == MID_REQUEST_SUBMITTED) &&
-		    (mid->command == shdr->Command)) {
-			kref_get(&mid->refcount);
+	list_for_each_entry(smb, &server->pending_mid_q, qhead) {
+		if ((smb->mid == wire_mid) &&
+		    (smb->mid_state == MID_REQUEST_SUBMITTED) &&
+		    (smb->command == shdr->Command)) {
+			kref_get(&smb->refcount);
 			if (dequeue) {
-				list_del_init(&mid->qhead);
-				mid->deleted_from_q = true;
+				list_del_init(&smb->qhead);
+				smb->deleted_from_q = true;
 			}
 			spin_unlock(&server->mid_queue_lock);
-			return mid;
+			return smb;
 		}
 	}
 	spin_unlock(&server->mid_queue_lock);
 	return NULL;
 }
 
-static struct mid_q_entry *
+static struct smb_message *
 smb2_find_mid(struct TCP_Server_Info *server, char *buf)
 {
 	return __smb2_find_mid(server, buf, false);
 }
 
-static struct mid_q_entry *
+static struct smb_message *
 smb2_find_dequeue_mid(struct TCP_Server_Info *server, char *buf)
 {
 	return __smb2_find_mid(server, buf, true);
@@ -4668,7 +4668,7 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size,
 }
 
 static int
-handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
+handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 		 char *buf, unsigned int buf_len, struct folio_queue *buffer,
 		 unsigned int buffer_len, bool is_offloaded)
 {
@@ -4677,7 +4677,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 	unsigned int cur_off;
 	unsigned int cur_page_idx;
 	unsigned int pad_len;
-	struct cifs_io_subrequest *rdata = mid->callback_data;
+	struct cifs_io_subrequest *rdata = smb->callback_data;
 	struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
 	size_t copied;
 	bool use_rdma_mr = false;
@@ -4715,9 +4715,9 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 			 __func__, rdata->result);
 		/* normal error on read response */
 		if (is_offloaded)
-			mid->mid_state = MID_RESPONSE_RECEIVED;
+			smb->mid_state = MID_RESPONSE_RECEIVED;
 		else
-			dequeue_mid(mid, false);
+			dequeue_mid(smb, false);
 		return 0;
 	}
 
@@ -4742,9 +4742,9 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 			 __func__, data_offset);
 		rdata->result = -EIO;
 		if (is_offloaded)
-			mid->mid_state = MID_RESPONSE_MALFORMED;
+			smb->mid_state = MID_RESPONSE_MALFORMED;
 		else
-			dequeue_mid(mid, rdata->result);
+			dequeue_mid(smb, rdata->result);
 		return 0;
 	}
 
@@ -4761,9 +4761,9 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 				 __func__, data_offset);
 			rdata->result = -EIO;
 			if (is_offloaded)
-				mid->mid_state = MID_RESPONSE_MALFORMED;
+				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
-				dequeue_mid(mid, rdata->result);
+				dequeue_mid(smb, rdata->result);
 			return 0;
 		}
 
@@ -4771,9 +4771,9 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 			/* data_len is corrupt -- discard frame */
 			rdata->result = -EIO;
 			if (is_offloaded)
-				mid->mid_state = MID_RESPONSE_MALFORMED;
+				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
-				dequeue_mid(mid, rdata->result);
+				dequeue_mid(smb, rdata->result);
 			return 0;
 		}
 
@@ -4782,9 +4782,9 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 							 cur_off, &rdata->subreq.io_iter);
 		if (rdata->result != 0) {
 			if (is_offloaded)
-				mid->mid_state = MID_RESPONSE_MALFORMED;
+				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
-				dequeue_mid(mid, rdata->result);
+				dequeue_mid(smb, rdata->result);
 			return 0;
 		}
 		rdata->got_bytes = buffer_len;
@@ -4801,16 +4801,16 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 		WARN_ONCE(1, "buf can not contain only a part of read data");
 		rdata->result = -EIO;
 		if (is_offloaded)
-			mid->mid_state = MID_RESPONSE_MALFORMED;
+			smb->mid_state = MID_RESPONSE_MALFORMED;
 		else
-			dequeue_mid(mid, rdata->result);
+			dequeue_mid(smb, rdata->result);
 		return 0;
 	}
 
 	if (is_offloaded)
-		mid->mid_state = MID_RESPONSE_RECEIVED;
+		smb->mid_state = MID_RESPONSE_RECEIVED;
 	else
-		dequeue_mid(mid, false);
+		dequeue_mid(smb, false);
 	return 0;
 }
 
@@ -4828,7 +4828,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
 	struct smb2_decrypt_work *dw = container_of(work,
 				struct smb2_decrypt_work, decrypt);
 	int rc;
-	struct mid_q_entry *mid;
+	struct smb_message *smb;
 	struct iov_iter iter;
 
 	iov_iter_folio_queue(&iter, ITER_DEST, dw->buffer, 0, 0, dw->len);
@@ -4840,43 +4840,43 @@ static void smb2_decrypt_offload(struct work_struct *work)
 	}
 
 	dw->server->lstrp = jiffies;
-	mid = smb2_find_dequeue_mid(dw->server, dw->buf);
-	if (mid == NULL)
+	smb = smb2_find_dequeue_mid(dw->server, dw->buf);
+	if (smb == NULL)
 		cifs_dbg(FYI, "mid not found\n");
 	else {
-		mid->decrypted = true;
-		rc = handle_read_data(dw->server, mid, dw->buf,
+		smb->decrypted = true;
+		rc = handle_read_data(dw->server, smb, dw->buf,
 				      dw->server->vals->read_rsp_size,
 				      dw->buffer, dw->len,
 				      true);
 		if (rc >= 0) {
 #ifdef CONFIG_CIFS_STATS2
-			mid->when_received = jiffies;
+			smb->when_received = jiffies;
 #endif
 			if (dw->server->ops->is_network_name_deleted)
 				dw->server->ops->is_network_name_deleted(dw->buf,
 									 dw->server);
 
-			mid_execute_callback(mid);
+			mid_execute_callback(smb);
 		} else {
 			spin_lock(&dw->server->srv_lock);
 			if (dw->server->tcpStatus == CifsNeedReconnect) {
 				spin_lock(&dw->server->mid_queue_lock);
-				mid->mid_state = MID_RETRY_NEEDED;
+				smb->mid_state = MID_RETRY_NEEDED;
 				spin_unlock(&dw->server->mid_queue_lock);
 				spin_unlock(&dw->server->srv_lock);
-				mid_execute_callback(mid);
+				mid_execute_callback(smb);
 			} else {
 				spin_lock(&dw->server->mid_queue_lock);
-				mid->mid_state = MID_REQUEST_SUBMITTED;
-				mid->deleted_from_q = false;
-				list_add_tail(&mid->qhead,
+				smb->mid_state = MID_REQUEST_SUBMITTED;
+				smb->deleted_from_q = false;
+				list_add_tail(&smb->qhead,
 					&dw->server->pending_mid_q);
 				spin_unlock(&dw->server->mid_queue_lock);
 				spin_unlock(&dw->server->srv_lock);
 			}
 		}
-		release_mid(mid);
+		release_mid(smb);
 	}
 
 free_pages:
@@ -4887,7 +4887,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
 
 
 static int
-receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
+receive_encrypted_read(struct TCP_Server_Info *server, struct smb_message **smb,
 		       int *num_mids)
 {
 	char *buf = server->smallbuf;
@@ -4964,13 +4964,13 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
 	if (rc)
 		goto free_pages;
 
-	*mid = smb2_find_mid(server, buf);
-	if (*mid == NULL) {
+	*smb = smb2_find_mid(server, buf);
+	if (*smb == NULL) {
 		cifs_dbg(FYI, "mid not found\n");
 	} else {
 		cifs_dbg(FYI, "mid found\n");
-		(*mid)->decrypted = true;
-		rc = handle_read_data(server, *mid, buf,
+		(*smb)->decrypted = true;
+		rc = handle_read_data(server, *smb, buf,
 				      server->vals->read_rsp_size,
 				      dw->buffer, dw->len, false);
 		if (rc >= 0) {
@@ -4993,7 +4993,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
 
 static int
 receive_encrypted_standard(struct TCP_Server_Info *server,
-			   struct mid_q_entry **mids, char **bufs,
+			   struct smb_message **mids, char **bufs,
 			   int *num_mids)
 {
 	int ret, length;
@@ -5002,7 +5002,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 	unsigned int pdu_length = server->pdu_size;
 	unsigned int buf_size;
 	unsigned int next_cmd;
-	struct mid_q_entry *mid_entry;
+	struct smb_message *smb;
 	int next_is_large;
 	char *next_buffer = NULL;
 
@@ -5045,13 +5045,13 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 		memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd);
 	}
 
-	mid_entry = smb2_find_mid(server, buf);
-	if (mid_entry == NULL)
+	smb = smb2_find_mid(server, buf);
+	if (smb == NULL)
 		cifs_dbg(FYI, "mid not found\n");
 	else {
 		cifs_dbg(FYI, "mid found\n");
-		mid_entry->decrypted = true;
-		mid_entry->resp_buf_size = server->pdu_size;
+		smb->decrypted = true;
+		smb->resp_buf_size = server->pdu_size;
 	}
 
 	if (*num_mids >= MAX_COMPOUND) {
@@ -5059,12 +5059,12 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 		return -1;
 	}
 	bufs[*num_mids] = buf;
-	mids[(*num_mids)++] = mid_entry;
+	mids[(*num_mids)++] = smb;
 
-	if (mid_entry && mid_entry->handle)
-		ret = mid_entry->handle(server, mid_entry);
+	if (smb && smb->handle)
+		ret = smb->handle(server, smb);
 	else
-		ret = cifs_handle_standard(server, mid_entry);
+		ret = cifs_handle_standard(server, smb);
 
 	if (ret == 0 && next_cmd) {
 		pdu_length -= next_cmd;
@@ -5092,7 +5092,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
 
 static int
 smb3_receive_transform(struct TCP_Server_Info *server,
-		       struct mid_q_entry **mids, char **bufs, int *num_mids)
+		       struct smb_message **mids, char **bufs, int *num_mids)
 {
 	char *buf = server->smallbuf;
 	unsigned int pdu_length = server->pdu_size;
@@ -5122,11 +5122,11 @@ smb3_receive_transform(struct TCP_Server_Info *server,
 }
 
 int
-smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+smb3_handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
 
-	return handle_read_data(server, mid, buf, server->pdu_size,
+	return handle_read_data(server, smb, buf, server->pdu_size,
 				NULL, 0, false);
 }
 
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 5921bfe00161..d8a88f62dcac 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -4092,19 +4092,19 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
  * FIXME: maybe we should consider checking that the reply matches request?
  */
 static void
-smb2_echo_callback(struct mid_q_entry *mid)
+smb2_echo_callback(struct smb_message *smb)
 {
-	struct TCP_Server_Info *server = mid->callback_data;
-	struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
+	struct TCP_Server_Info *server = smb->callback_data;
+	struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)smb->resp_buf;
 	struct cifs_credits credits = { .value = 0, .instance = 0 };
 
-	if (mid->mid_state == MID_RESPONSE_RECEIVED
-	    || mid->mid_state == MID_RESPONSE_MALFORMED) {
+	if (smb->mid_state == MID_RESPONSE_RECEIVED
+	    || smb->mid_state == MID_RESPONSE_MALFORMED) {
 		credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
 		credits.instance = server->reconnect_instance;
 	}
 
-	release_mid(mid);
+	release_mid(smb);
 	add_credits(server, &credits, CIFS_ECHO_OP);
 }
 
@@ -4519,14 +4519,13 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
 }
 
 static void
-smb2_readv_callback(struct mid_q_entry *mid)
+smb2_readv_callback(struct smb_message *smb)
 {
-	struct cifs_io_subrequest *rdata = mid->callback_data;
+	struct cifs_io_subrequest *rdata = smb->callback_data;
 	struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
 	struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
 	struct TCP_Server_Info *server = rdata->server;
-	struct smb2_hdr *shdr =
-				(struct smb2_hdr *)rdata->iov[0].iov_base;
+	struct smb2_hdr *shdr = (struct smb2_hdr *)rdata->iov[0].iov_base;
 	struct cifs_credits credits = {
 		.value = 0,
 		.instance = 0,
@@ -4541,20 +4540,20 @@ smb2_readv_callback(struct mid_q_entry *mid)
 		rqst.rq_iter	  = rdata->subreq.io_iter;
 	}
 
-	WARN_ONCE(rdata->server != mid->server,
+	WARN_ONCE(rdata->server != smb->server,
 		  "rdata server %p != mid server %p",
-		  rdata->server, mid->server);
+		  rdata->server, smb->server);
 
 	cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu/%zu\n",
-		 __func__, mid->mid, mid->mid_state, rdata->result,
+		 __func__, smb->mid, smb->mid_state, rdata->result,
 		 rdata->got_bytes, rdata->subreq.len - rdata->subreq.transferred);
 
-	switch (mid->mid_state) {
+	switch (smb->mid_state) {
 	case MID_RESPONSE_RECEIVED:
 		credits.value = le16_to_cpu(shdr->CreditRequest);
 		credits.instance = server->reconnect_instance;
 		/* result already set, check signature */
-		if (server->sign && !mid->decrypted) {
+		if (server->sign && !smb->decrypted) {
 			int rc;
 
 			iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
@@ -4644,7 +4643,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
 	rdata->subreq.transferred += rdata->got_bytes;
 	trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
 	netfs_read_subreq_terminated(&rdata->subreq);
-	release_mid(mid);
+	release_mid(smb);
 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
 			      server->credits, server->in_flight,
 			      credits.value, cifs_trace_rw_credits_read_response_add);
@@ -4821,12 +4820,12 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
  * workqueue completion task.
  */
 static void
-smb2_writev_callback(struct mid_q_entry *mid)
+smb2_writev_callback(struct smb_message *smb)
 {
-	struct cifs_io_subrequest *wdata = mid->callback_data;
+	struct cifs_io_subrequest *wdata = smb->callback_data;
 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
 	struct TCP_Server_Info *server = wdata->server;
-	struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
+	struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)smb->resp_buf;
 	struct cifs_credits credits = {
 		.value = 0,
 		.instance = 0,
@@ -4838,16 +4837,16 @@ smb2_writev_callback(struct mid_q_entry *mid)
 	ssize_t result = 0;
 	size_t written;
 
-	WARN_ONCE(wdata->server != mid->server,
+	WARN_ONCE(wdata->server != smb->server,
 		  "wdata server %p != mid server %p",
-		  wdata->server, mid->server);
+		  wdata->server, smb->server);
 
-	switch (mid->mid_state) {
+	switch (smb->mid_state) {
 	case MID_RESPONSE_RECEIVED:
 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_progress);
 		credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
 		credits.instance = server->reconnect_instance;
-		result = smb2_check_receive(mid, server, 0);
+		result = smb2_check_receive(smb, server, 0);
 		if (result != 0) {
 			trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_bad);
 			break;
@@ -4930,7 +4929,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
 			      0, cifs_trace_rw_credits_write_response_clear);
 	wdata->credits.value = 0;
 	cifs_write_subrequest_terminated(wdata, result ?: written);
-	release_mid(mid);
+	release_mid(smb);
 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
 			      server->credits, server->in_flight,
 			      credits.value, cifs_trace_rw_credits_write_response_add);
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 01cde09d98ac..ffc6e8cf9e47 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -99,7 +99,7 @@ bool smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server);
 void smb2_cancelled_close_fid(struct work_struct *work);
 int smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
 				__u64 volatile_fid);
-int smb2_handle_cancelled_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server);
+int smb2_handle_cancelled_mid(struct smb_message *mid, struct TCP_Server_Info *server);
 void smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
 				struct kvec *iov, int nvec);
 
@@ -119,7 +119,7 @@ int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 			     struct kvec *rsp, int *buftype,
 			     struct cifs_sb_info *cifs_sb);
 void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst);
-int smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid);
+int smb3_handle_read_data(struct TCP_Server_Info *server, struct smb_message *mid);
 int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
 			 struct dentry *dentry, struct cifs_tcon *tcon,
 			 const char *full_path, umode_t mode, dev_t dev,
@@ -282,11 +282,11 @@ int generate_smb30signingkey(struct cifs_ses *ses,
 int generate_smb311signingkey(struct cifs_ses *ses,
 			      struct TCP_Server_Info *server);
 int smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server);
-int smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+int smb2_check_receive(struct smb_message *mid, struct TCP_Server_Info *server,
 		       bool log_error);
-struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
+struct smb_message *smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
 				       struct smb_rqst *rqst);
-struct mid_q_entry *smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst);
+struct smb_message *smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst);
 int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
 
 /*
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 6a9b80385b86..21b027040643 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -641,11 +641,11 @@ smb2_seq_num_into_buf(struct TCP_Server_Info *server,
 		get_next_mid(server);
 }
 
-static struct mid_q_entry *
+static struct smb_message *
 smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
 		     struct TCP_Server_Info *server)
 {
-	struct mid_q_entry *temp;
+	struct smb_message *smb;
 	unsigned int credits = le16_to_cpu(shdr->CreditCharge);
 
 	if (server == NULL) {
@@ -653,37 +653,37 @@ smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
 		return NULL;
 	}
 
-	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
-	memset(temp, 0, sizeof(struct mid_q_entry));
-	kref_init(&temp->refcount);
-	spin_lock_init(&temp->mid_lock);
-	temp->mid = le64_to_cpu(shdr->MessageId);
-	temp->credits = credits > 0 ? credits : 1;
-	temp->pid = current->pid;
-	temp->command = shdr->Command; /* Always LE */
-	temp->when_alloc = jiffies;
-	temp->server = server;
+	smb = mempool_alloc(&smb_message_pool, GFP_NOFS);
+	memset(smb, 0, sizeof(*smb));
+	kref_init(&smb->refcount);
+	spin_lock_init(&smb->mid_lock);
+	smb->mid = le64_to_cpu(shdr->MessageId);
+	smb->credits = credits > 0 ? credits : 1;
+	smb->pid = current->pid;
+	smb->command = shdr->Command; /* Always LE */
+	smb->when_alloc = jiffies;
+	smb->server = server;
 
 	/*
 	 * The default is for the mid to be synchronous, so the
 	 * default callback just wakes up the current task.
 	 */
 	get_task_struct(current);
-	temp->creator = current;
-	temp->callback = cifs_wake_up_task;
-	temp->callback_data = current;
+	smb->creator = current;
+	smb->callback = cifs_wake_up_task;
+	smb->callback_data = current;
 
 	atomic_inc(&mid_count);
-	temp->mid_state = MID_REQUEST_ALLOCATED;
+	smb->mid_state = MID_REQUEST_ALLOCATED;
 	trace_smb3_cmd_enter(le32_to_cpu(shdr->Id.SyncId.TreeId),
 			     le64_to_cpu(shdr->SessionId),
-			     le16_to_cpu(shdr->Command), temp->mid);
-	return temp;
+			     le16_to_cpu(shdr->Command), smb->mid);
+	return smb;
 }
 
 static int
 smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
-		   struct smb2_hdr *shdr, struct mid_q_entry **mid)
+		   struct smb2_hdr *shdr, struct smb_message **smb)
 {
 	spin_lock(&server->srv_lock);
 	if (server->tcpStatus == CifsExiting) {
@@ -723,18 +723,18 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
 	}
 	spin_unlock(&ses->ses_lock);
 
-	*mid = smb2_mid_entry_alloc(shdr, server);
-	if (*mid == NULL)
+	*smb = smb2_mid_entry_alloc(shdr, server);
+	if (*smb == NULL)
 		return -ENOMEM;
 	spin_lock(&server->mid_queue_lock);
-	list_add_tail(&(*mid)->qhead, &server->pending_mid_q);
+	list_add_tail(&(*smb)->qhead, &server->pending_mid_q);
 	spin_unlock(&server->mid_queue_lock);
 
 	return 0;
 }
 
 int
-smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+smb2_check_receive(struct smb_message *mid, struct TCP_Server_Info *server,
 		   bool log_error)
 {
 	unsigned int len = mid->resp_buf_size;
@@ -759,14 +759,14 @@ smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
 	return map_smb2_to_linux_error(mid->resp_buf, log_error);
 }
 
-struct mid_q_entry *
+struct smb_message *
 smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
 		   struct smb_rqst *rqst)
 {
 	int rc;
 	struct smb2_hdr *shdr =
 			(struct smb2_hdr *)rqst->rq_iov[0].iov_base;
-	struct mid_q_entry *mid;
+	struct smb_message *mid;
 
 	smb2_seq_num_into_buf(server, shdr);
 
@@ -786,13 +786,13 @@ smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
 	return mid;
 }
 
-struct mid_q_entry *
+struct smb_message *
 smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 {
 	int rc;
 	struct smb2_hdr *shdr =
 			(struct smb2_hdr *)rqst->rq_iov[0].iov_base;
-	struct mid_q_entry *mid;
+	struct smb_message *smb;
 
 	spin_lock(&server->srv_lock);
 	if (server->tcpStatus == CifsNeedNegotiate &&
@@ -804,8 +804,8 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 
 	smb2_seq_num_into_buf(server, shdr);
 
-	mid = smb2_mid_entry_alloc(shdr, server);
-	if (mid == NULL) {
+	smb = smb2_mid_entry_alloc(shdr, server);
+	if (smb == NULL) {
 		revert_current_mid_from_hdr(server, shdr);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -813,11 +813,11 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 	rc = smb2_sign_rqst(rqst, server);
 	if (rc) {
 		revert_current_mid_from_hdr(server, shdr);
-		release_mid(mid);
+		release_mid(smb);
 		return ERR_PTR(rc);
 	}
 
-	return mid;
+	return smb;
 }
 
 int
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index 915cedde5d66..52083b79609b 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -32,42 +32,42 @@
 #include "compress.h"
 
 void
-cifs_wake_up_task(struct mid_q_entry *mid)
+cifs_wake_up_task(struct smb_message *smb)
 {
-	if (mid->mid_state == MID_RESPONSE_RECEIVED)
-		mid->mid_state = MID_RESPONSE_READY;
-	wake_up_process(mid->callback_data);
+	if (smb->mid_state == MID_RESPONSE_RECEIVED)
+		smb->mid_state = MID_RESPONSE_READY;
+	wake_up_process(smb->callback_data);
 }
 
 void __release_mid(struct kref *refcount)
 {
-	struct mid_q_entry *midEntry =
-			container_of(refcount, struct mid_q_entry, refcount);
+	struct smb_message *smb =
+			container_of(refcount, struct smb_message, refcount);
 #ifdef CONFIG_CIFS_STATS2
-	__le16 command = midEntry->server->vals->lock_cmd;
-	__u16 smb_cmd = le16_to_cpu(midEntry->command);
+	__le16 command = smb->server->vals->lock_cmd;
+	__u16 smb_cmd = le16_to_cpu(smb->command);
 	unsigned long now;
 	unsigned long roundtrip_time;
 #endif
-	struct TCP_Server_Info *server = midEntry->server;
+	struct TCP_Server_Info *server = smb->server;
 
-	if (midEntry->resp_buf && (midEntry->wait_cancelled) &&
-	    (midEntry->mid_state == MID_RESPONSE_RECEIVED ||
-	     midEntry->mid_state == MID_RESPONSE_READY) &&
+	if (smb->resp_buf && smb->wait_cancelled &&
+	    (smb->mid_state == MID_RESPONSE_RECEIVED ||
+	     smb->mid_state == MID_RESPONSE_READY) &&
 	    server->ops->handle_cancelled_mid)
-		server->ops->handle_cancelled_mid(midEntry, server);
+		server->ops->handle_cancelled_mid(smb, server);
 
-	midEntry->mid_state = MID_FREE;
+	smb->mid_state = MID_FREE;
 	atomic_dec(&mid_count);
-	if (midEntry->large_buf)
-		cifs_buf_release(midEntry->resp_buf);
+	if (smb->large_buf)
+		cifs_buf_release(smb->resp_buf);
 	else
-		cifs_small_buf_release(midEntry->resp_buf);
+		cifs_small_buf_release(smb->resp_buf);
 #ifdef CONFIG_CIFS_STATS2
 	now = jiffies;
-	if (now < midEntry->when_alloc)
+	if (now < smb->when_alloc)
 		cifs_server_dbg(VFS, "Invalid mid allocation time\n");
-	roundtrip_time = now - midEntry->when_alloc;
+	roundtrip_time = now - smb->when_alloc;
 
 	if (smb_cmd < NUMBER_OF_SMB2_COMMANDS) {
 		if (atomic_read(&server->num_cmds[smb_cmd]) == 0) {
@@ -93,8 +93,8 @@ void __release_mid(struct kref *refcount)
 	 * checks
 	 */
 	if ((slow_rsp_threshold != 0) &&
-	    time_after(now, midEntry->when_alloc + (slow_rsp_threshold * HZ)) &&
-	    (midEntry->command != command)) {
+	    time_after(now, smb->when_alloc + (slow_rsp_threshold * HZ)) &&
+	    (smb->command != command)) {
 		/*
 		 * smb2slowcmd[NUMBER_OF_SMB2_COMMANDS] counts by command
 		 * NB: le16_to_cpu returns unsigned so can not be negative below
@@ -102,34 +102,35 @@ void __release_mid(struct kref *refcount)
 		if (smb_cmd < NUMBER_OF_SMB2_COMMANDS)
 			cifs_stats_inc(&server->smb2slowcmd[smb_cmd]);
 
-		trace_smb3_slow_rsp(smb_cmd, midEntry->mid, midEntry->pid,
-			       midEntry->when_sent, midEntry->when_received);
+		trace_smb3_slow_rsp(smb_cmd, smb->mid, smb->pid,
+				    smb->when_sent, smb->when_received);
 		if (cifsFYI & CIFS_TIMER) {
 			pr_debug("slow rsp: cmd %d mid %llu",
-				 midEntry->command, midEntry->mid);
+				 smb->command, smb->mid);
 			cifs_info("A: 0x%lx S: 0x%lx R: 0x%lx\n",
-				  now - midEntry->when_alloc,
-				  now - midEntry->when_sent,
-				  now - midEntry->when_received);
+				  now - smb->when_alloc,
+				  now - smb->when_sent,
+				  now - smb->when_received);
 		}
 	}
 #endif
-	put_task_struct(midEntry->creator);
+	put_task_struct(smb->creator);
 
-	mempool_free(midEntry, cifs_mid_poolp);
+	mempool_free(smb, &smb_message_pool);
 }
 
 void
-delete_mid(struct mid_q_entry *mid)
+delete_mid(struct smb_message *smb)
 {
-	spin_lock(&mid->server->mid_queue_lock);
-	if (mid->deleted_from_q == false) {
-		list_del_init(&mid->qhead);
-		mid->deleted_from_q = true;
+	spin_lock(&smb->server->mid_queue_lock);
+
+	if (!smb->deleted_from_q) {
+		list_del_init(&smb->qhead);
+		smb->deleted_from_q = true;
 	}
-	spin_unlock(&mid->server->mid_queue_lock);
+	spin_unlock(&smb->server->mid_queue_lock);
 
-	release_mid(mid);
+	release_mid(smb);
 }
 
 /*
@@ -640,13 +641,13 @@ cifs_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
 	return 0;
 }
 
-int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
+int wait_for_response(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	int error;
 
 	error = wait_event_state(server->response_q,
-				 midQ->mid_state != MID_REQUEST_SUBMITTED &&
-				 midQ->mid_state != MID_RESPONSE_RECEIVED,
+				 smb->mid_state != MID_REQUEST_SUBMITTED &&
+				 smb->mid_state != MID_RESPONSE_RECEIVED,
 				 (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE));
 	if (error < 0)
 		return -ERESTARTSYS;
@@ -660,12 +661,12 @@ int wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
  */
 int
 cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-		mid_receive_t *receive, mid_callback_t *callback,
-		mid_handle_t *handle, void *cbdata, const int flags,
+		mid_receive_t receive, mid_callback_t callback,
+		mid_handle_t handle, void *cbdata, const int flags,
 		const struct cifs_credits *exist_credits)
 {
 	int rc;
-	struct mid_q_entry *mid;
+	struct smb_message *smb;
 	struct cifs_credits credits = { .value = 0, .instance = 0 };
 	unsigned int instance;
 	int optype;
@@ -694,35 +695,35 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 		return -EAGAIN;
 	}
 
-	mid = server->ops->setup_async_request(server, rqst);
-	if (IS_ERR(mid)) {
+	smb = server->ops->setup_async_request(server, rqst);
+	if (IS_ERR(smb)) {
 		cifs_server_unlock(server);
 		add_credits_and_wake_if(server, &credits, optype);
-		return PTR_ERR(mid);
+		return PTR_ERR(smb);
 	}
 
-	mid->receive = receive;
-	mid->callback = callback;
-	mid->callback_data = cbdata;
-	mid->handle = handle;
-	mid->mid_state = MID_REQUEST_SUBMITTED;
+	smb->receive = receive;
+	smb->callback = callback;
+	smb->callback_data = cbdata;
+	smb->handle = handle;
+	smb->mid_state = MID_REQUEST_SUBMITTED;
 
 	/* put it on the pending_mid_q */
 	spin_lock(&server->mid_queue_lock);
-	list_add_tail(&mid->qhead, &server->pending_mid_q);
+	list_add_tail(&smb->qhead, &server->pending_mid_q);
 	spin_unlock(&server->mid_queue_lock);
 
 	/*
 	 * Need to store the time in mid before calling I/O. For call_async,
 	 * I/O response may come back and free the mid entry on another thread.
 	 */
-	cifs_save_when_sent(mid);
+	cifs_save_when_sent(smb);
 	rc = smb_send_rqst(server, 1, rqst, flags);
 
 	if (rc < 0) {
-		revert_current_mid(server, mid->credits);
+		revert_current_mid(server, smb->credits);
 		server->sequence_number -= 2;
-		delete_mid(mid);
+		delete_mid(smb);
 	}
 
 	cifs_server_unlock(server);
@@ -734,15 +735,15 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 	return rc;
 }
 
-int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
+int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server)
 {
 	int rc = 0;
 
 	cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
-		 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
+		 __func__, le16_to_cpu(smb->command), smb->mid, smb->mid_state);
 
 	spin_lock(&server->mid_queue_lock);
-	switch (mid->mid_state) {
+	switch (smb->mid_state) {
 	case MID_RESPONSE_READY:
 		spin_unlock(&server->mid_queue_lock);
 		return rc;
@@ -756,53 +757,53 @@ int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server
 		rc = -EHOSTDOWN;
 		break;
 	case MID_RC:
-		rc = mid->mid_rc;
+		rc = smb->mid_rc;
 		break;
 	default:
-		if (mid->deleted_from_q == false) {
-			list_del_init(&mid->qhead);
-			mid->deleted_from_q = true;
+		if (smb->deleted_from_q == false) {
+			list_del_init(&smb->qhead);
+			smb->deleted_from_q = true;
 		}
 		spin_unlock(&server->mid_queue_lock);
 		cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
-			 __func__, mid->mid, mid->mid_state);
+			 __func__, smb->mid, smb->mid_state);
 		rc = -EIO;
 		goto sync_mid_done;
 	}
 	spin_unlock(&server->mid_queue_lock);
 
 sync_mid_done:
-	release_mid(mid);
+	release_mid(smb);
 	return rc;
 }
 
 static void
-cifs_compound_callback(struct mid_q_entry *mid)
+cifs_compound_callback(struct smb_message *smb)
 {
-	struct TCP_Server_Info *server = mid->server;
+	struct TCP_Server_Info *server = smb->server;
 	struct cifs_credits credits = {
-		.value = server->ops->get_credits(mid),
+		.value = server->ops->get_credits(smb),
 		.instance = server->reconnect_instance,
 	};
 
-	add_credits(server, &credits, mid->optype);
+	add_credits(server, &credits, smb->optype);
 
-	if (mid->mid_state == MID_RESPONSE_RECEIVED)
-		mid->mid_state = MID_RESPONSE_READY;
+	if (smb->mid_state == MID_RESPONSE_RECEIVED)
+		smb->mid_state = MID_RESPONSE_READY;
 }
 
 static void
-cifs_compound_last_callback(struct mid_q_entry *mid)
+cifs_compound_last_callback(struct smb_message *smb)
 {
-	cifs_compound_callback(mid);
-	cifs_wake_up_task(mid);
+	cifs_compound_callback(smb);
+	cifs_wake_up_task(smb);
 }
 
 static void
-cifs_cancelled_callback(struct mid_q_entry *mid)
+cifs_cancelled_callback(struct smb_message *smb)
 {
-	cifs_compound_callback(mid);
-	release_mid(mid);
+	cifs_compound_callback(smb);
+	release_mid(smb);
 }
 
 /*
@@ -866,7 +867,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 		   int *resp_buf_type, struct kvec *resp_iov)
 {
 	int i, j, optype, rc = 0;
-	struct mid_q_entry *midQ[MAX_COMPOUND];
+	struct smb_message *smb[MAX_COMPOUND];
 	bool cancelled_mid[MAX_COMPOUND] = {false};
 	struct cifs_credits credits[MAX_COMPOUND] = {
 		{ .value = 0, .instance = 0 }
@@ -932,35 +933,35 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 	}
 
 	for (i = 0; i < num_rqst; i++) {
-		midQ[i] = server->ops->setup_request(ses, server, &rqst[i]);
-		if (IS_ERR(midQ[i])) {
+		smb[i] = server->ops->setup_request(ses, server, &rqst[i]);
+		if (IS_ERR(smb[i])) {
 			revert_current_mid(server, i);
 			for (j = 0; j < i; j++)
-				delete_mid(midQ[j]);
+				delete_mid(smb[j]);
 			cifs_server_unlock(server);
 
 			/* Update # of requests on wire to server */
 			for (j = 0; j < num_rqst; j++)
 				add_credits(server, &credits[j], optype);
-			return PTR_ERR(midQ[i]);
+			return PTR_ERR(smb[i]);
 		}
 
-		midQ[i]->mid_state = MID_REQUEST_SUBMITTED;
-		midQ[i]->optype = optype;
+		smb[i]->mid_state = MID_REQUEST_SUBMITTED;
+		smb[i]->optype = optype;
 		/*
 		 * Invoke callback for every part of the compound chain
 		 * to calculate credits properly. Wake up this thread only when
 		 * the last element is received.
 		 */
 		if (i < num_rqst - 1)
-			midQ[i]->callback = cifs_compound_callback;
+			smb[i]->callback = cifs_compound_callback;
 		else
-			midQ[i]->callback = cifs_compound_last_callback;
+			smb[i]->callback = cifs_compound_last_callback;
 	}
 	rc = smb_send_rqst(server, num_rqst, rqst, flags);
 
 	for (i = 0; i < num_rqst; i++)
-		cifs_save_when_sent(midQ[i]);
+		cifs_save_when_sent(smb[i]);
 
 	if (rc < 0) {
 		revert_current_mid(server, num_rqst);
@@ -1003,23 +1004,24 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 	spin_unlock(&ses->ses_lock);
 
 	for (i = 0; i < num_rqst; i++) {
-		rc = wait_for_response(server, midQ[i]);
+		rc = wait_for_response(server, smb[i]);
 		if (rc != 0)
 			break;
 	}
 	if (rc != 0) {
 		for (; i < num_rqst; i++) {
 			cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",
-				 midQ[i]->mid, le16_to_cpu(midQ[i]->command));
-			send_cancel(server, &rqst[i], midQ[i]);
-			spin_lock(&midQ[i]->mid_lock);
-			midQ[i]->wait_cancelled = true;
-			if (midQ[i]->callback) {
-				midQ[i]->callback = cifs_cancelled_callback;
+				 smb[i]->mid, le16_to_cpu(smb[i]->command));
+			send_cancel(server, &rqst[i], smb[i]);
+			spin_lock(&smb[i]->mid_lock);
+			smb[i]->wait_cancelled = true;
+			if (smb[i]->mid_state == MID_REQUEST_SUBMITTED ||
+			    smb[i]->mid_state == MID_RESPONSE_RECEIVED) {
+				smb[i]->callback = cifs_cancelled_callback;
 				cancelled_mid[i] = true;
 				credits[i].value = 0;
 			}
-			spin_unlock(&midQ[i]->mid_lock);
+			spin_unlock(&smb[i]->mid_lock);
 		}
 	}
 
@@ -1027,36 +1029,36 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 		if (rc < 0)
 			goto out;
 
-		rc = cifs_sync_mid_result(midQ[i], server);
+		rc = cifs_sync_mid_result(smb[i], server);
 		if (rc != 0) {
 			/* mark this mid as cancelled to not free it below */
 			cancelled_mid[i] = true;
 			goto out;
 		}
 
-		if (!midQ[i]->resp_buf ||
-		    midQ[i]->mid_state != MID_RESPONSE_READY) {
+		if (!smb[i]->resp_buf ||
+		    smb[i]->mid_state != MID_RESPONSE_READY) {
 			rc = -EIO;
 			cifs_dbg(FYI, "Bad MID state?\n");
 			goto out;
 		}
 
-		buf = (char *)midQ[i]->resp_buf;
+		buf = (char *)smb[i]->resp_buf;
 		resp_iov[i].iov_base = buf;
-		resp_iov[i].iov_len = midQ[i]->resp_buf_size +
+		resp_iov[i].iov_len = smb[i]->resp_buf_size +
 			HEADER_PREAMBLE_SIZE(server);
 
-		if (midQ[i]->large_buf)
+		if (smb[i]->large_buf)
 			resp_buf_type[i] = CIFS_LARGE_BUFFER;
 		else
 			resp_buf_type[i] = CIFS_SMALL_BUFFER;
 
-		rc = server->ops->check_receive(midQ[i], server,
+		rc = server->ops->check_receive(smb[i], server,
 						     flags & CIFS_LOG_ERROR);
 
 		/* mark it so buf will not be freed by delete_mid */
 		if ((flags & CIFS_NO_RSP_BUF) == 0)
-			midQ[i]->resp_buf = NULL;
+			smb[i]->resp_buf = NULL;
 
 	}
 
@@ -1086,7 +1088,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 	 */
 	for (i = 0; i < num_rqst; i++) {
 		if (!cancelled_mid[i])
-			delete_mid(midQ[i]);
+			delete_mid(smb[i]);
 	}
 
 	return rc;
@@ -1130,38 +1132,38 @@ cifs_discard_remaining_data(struct TCP_Server_Info *server)
 }
 
 static int
-__cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
+__cifs_readv_discard(struct TCP_Server_Info *server, struct smb_message *smb,
 		     bool malformed)
 {
 	int length;
 
 	length = cifs_discard_remaining_data(server);
-	dequeue_mid(mid, malformed);
-	mid->resp_buf = server->smallbuf;
+	dequeue_mid(smb, malformed);
+	smb->resp_buf = server->smallbuf;
 	server->smallbuf = NULL;
 	return length;
 }
 
 static int
-cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+cifs_readv_discard(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	struct cifs_io_subrequest *rdata = mid->callback_data;
+	struct cifs_io_subrequest *rdata = smb->callback_data;
 
-	return  __cifs_readv_discard(server, mid, rdata->result);
+	return  __cifs_readv_discard(server, smb, rdata->result);
 }
 
 int
-cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	int length, len;
 	unsigned int data_offset, data_len;
-	struct cifs_io_subrequest *rdata = mid->callback_data;
+	struct cifs_io_subrequest *rdata = smb->callback_data;
 	char *buf = server->smallbuf;
 	unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server);
 	bool use_rdma_mr = false;
 
 	cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%zu\n",
-		 __func__, mid->mid, rdata->subreq.start, rdata->subreq.len);
+		 __func__, smb->mid, rdata->subreq.start, rdata->subreq.len);
 
 	/*
 	 * read the rest of READ_RSP header (sans Data array), or whatever we
@@ -1206,7 +1208,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 		cifs_dbg(FYI, "%s: server returned error %d\n",
 			 __func__, rdata->result);
 		/* normal error on read response */
-		return __cifs_readv_discard(server, mid, false);
+		return __cifs_readv_discard(server, smb, false);
 	}
 
 	/* Is there enough to get to the rest of the READ_RSP header? */
@@ -1215,7 +1217,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 			 __func__, server->total_read,
 			 server->vals->read_rsp_size);
 		rdata->result = -EIO;
-		return cifs_readv_discard(server, mid);
+		return cifs_readv_discard(server, smb);
 	}
 
 	data_offset = server->ops->read_data_offset(buf) +
@@ -1234,7 +1236,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 		cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
 			 __func__, data_offset);
 		rdata->result = -EIO;
-		return cifs_readv_discard(server, mid);
+		return cifs_readv_discard(server, smb);
 	}
 
 	cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n",
@@ -1258,7 +1260,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 	if (!use_rdma_mr && (data_offset + data_len > buflen)) {
 		/* data_len is corrupt -- discard frame */
 		rdata->result = -EIO;
-		return cifs_readv_discard(server, mid);
+		return cifs_readv_discard(server, smb);
 	}
 
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -1277,10 +1279,10 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 
 	/* discard anything left over */
 	if (server->total_read < buflen)
-		return cifs_readv_discard(server, mid);
+		return cifs_readv_discard(server, smb);
 
-	dequeue_mid(mid, false);
-	mid->resp_buf = server->smallbuf;
+	dequeue_mid(smb, false);
+	smb->resp_buf = server->smallbuf;
 	server->smallbuf = NULL;
 	return length;
 }


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (3 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 04/11] cifs: Rename mid_q_entry to smb_message David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 17:27   ` Tom Talpey
  2025-11-24 19:56   ` David Howells
  2025-11-24 12:42 ` [PATCH v4 06/11] cifs: Make smb1's SendReceive() wrap cifs_send_recv() David Howells
                   ` (5 subsequent siblings)
  10 siblings, 2 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

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.

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@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.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;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 06/11] cifs: Make smb1's SendReceive() wrap cifs_send_recv()
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (4 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002 David Howells
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Make the smb1 transport's SendReceive() simply wrap cifs_send_recv() as
does SendReceive2().  This will then allow that to pick up the transport
changes there.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cifstransport.c | 83 +++++------------------------------
 1 file changed, 10 insertions(+), 73 deletions(-)

diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index d67b256a2ee7..1a0b80fc97d4 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -237,12 +237,12 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 	    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;
+	struct TCP_Server_Info *server;
+	struct kvec resp_iov = {};
 	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;
+	int resp_buf_type;
+	int rc = 0;
 
 	if (WARN_ON_ONCE(in_len > 0xffffff))
 		return -EIO;
@@ -273,78 +273,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 		return -EIO;
 	}
 
-	rc = wait_for_free_request(server, flags, &credits.instance);
-	if (rc)
-		return rc;
-
-	/* make sure that we sign in the same order that we send on this socket
-	   and avoid races inside tcp sendmsg code that could cause corruption
-	   of smb data */
-
-	cifs_server_lock(server);
-
-	rc = allocate_mid(ses, in_buf, &smb);
-	if (rc) {
-		cifs_server_unlock(server);
-		/* Update # of requests on wire to server */
-		add_credits(server, &credits, 0);
-		return rc;
-	}
-
-	rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
-	if (rc) {
-		cifs_server_unlock(server);
-		goto out;
-	}
-
-	smb->mid_state = MID_REQUEST_SUBMITTED;
-
-	rc = smb_send(server, in_buf, in_len);
-	cifs_save_when_sent(smb);
-
-	if (rc < 0)
-		server->sequence_number -= 2;
-
-	cifs_server_unlock(server);
-
+	rc = cifs_send_recv(xid, ses, ses->server,
+			    &rqst, &resp_buf_type, flags, &resp_iov);
 	if (rc < 0)
-		goto out;
-
-	rc = wait_for_response(server, smb);
-	if (rc != 0) {
-		send_cancel(server, &rqst, smb);
-		spin_lock(&smb->mid_lock);
-		if (smb->mid_state == MID_REQUEST_SUBMITTED ||
-		    smb->mid_state == MID_RESPONSE_RECEIVED) {
-			/* no longer considered to be "in-flight" */
-			smb->callback = release_mid;
-			spin_unlock(&smb->mid_lock);
-			add_credits(server, &credits, 0);
-			return rc;
-		}
-		spin_unlock(&smb->mid_lock);
-	}
-
-	rc = cifs_sync_mid_result(smb, server);
-	if (rc != 0) {
-		add_credits(server, &credits, 0);
 		return rc;
-	}
-
-	if (!smb->resp_buf || !out_buf ||
-	    smb->mid_state != MID_RESPONSE_READY) {
-		rc = -EIO;
-		cifs_server_dbg(VFS, "Bad MID state?\n");
-		goto out;
-	}
-
-	*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);
-	add_credits(server, &credits, 0);
 
+	*pbytes_returned = resp_iov.iov_len;
+	if (resp_iov.iov_len)
+		memcpy(out_buf, resp_iov.iov_base, resp_iov.iov_len);
+	free_rsp_buf(resp_buf_type, resp_iov.iov_base);
 	return rc;
 }
 


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (5 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 06/11] cifs: Make smb1's SendReceive() wrap cifs_send_recv() David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 14:20   ` Stefan Metzmacher
  2025-11-24 14:36   ` David Howells
  2025-11-24 12:42 ` [PATCH v4 08/11] cifs: Replace SendReceiveBlockingLock() with SendReceive() plus flags David Howells
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Clean up some places where previously an extra element in the kvec array
was being used to hold an rfc1002 header for SMB1 (a previous patch removed
this and generated it on the fly as for SMB2/3).

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cifsencrypt.c   | 52 ++++++++---------------------------
 fs/smb/client/cifsproto.h     |  5 ----
 fs/smb/client/cifstransport.c | 20 ++------------
 fs/smb/client/smb1ops.c       | 12 +++++---
 fs/smb/client/transport.c     | 25 +++++++++--------
 5 files changed, 35 insertions(+), 79 deletions(-)

diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index 1e0ac87c6686..a9a57904c6b1 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -86,26 +86,21 @@ static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize,
 int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 			  char *signature, struct cifs_calc_sig_ctx *ctx)
 {
-	int i;
+	struct iov_iter iter;
 	ssize_t rc;
-	struct kvec *iov = rqst->rq_iov;
-	int n_vec = rqst->rq_nvec;
+	size_t size = 0;
 
-	for (i = 0; i < n_vec; i++) {
-		if (iov[i].iov_len == 0)
-			continue;
-		if (iov[i].iov_base == NULL) {
-			cifs_dbg(VFS, "null iovec entry\n");
-			return -EIO;
-		}
+	for (int i = 0; i < rqst->rq_nvec; i++)
+		size += rqst->rq_iov[i].iov_len;
 
-		rc = cifs_sig_update(ctx, iov[i].iov_base, iov[i].iov_len);
-		if (rc) {
-			cifs_dbg(VFS, "%s: Could not update with payload\n",
-				 __func__);
-			return rc;
-		}
-	}
+	iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size);
+
+	if (iov_iter_count(&iter) <= 4)
+		return -EIO;
+
+	rc = cifs_sig_iter(&iter, iov_iter_count(&iter), ctx);
+	if (rc < 0)
+		return rc;
 
 	rc = cifs_sig_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), ctx);
 	if (rc < 0)
@@ -186,29 +181,6 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 	return rc;
 }
 
-int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
-		   __u32 *pexpected_response_sequence)
-{
-	struct smb_rqst rqst = { .rq_iov = iov,
-				 .rq_nvec = n_vec };
-
-	return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
-}
-
-/* must be called with server->srv_mutex held */
-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[1] = {
-		[0].iov_base = (char *)cifs_pdu,
-		[0].iov_len = pdu_len,
-	};
-
-	return cifs_sign_smbv(iov, ARRAY_SIZE(iov), server,
-			      pexpected_response_sequence_number);
-}
-
 int cifs_verify_signature(struct smb_rqst *rqst,
 			  struct TCP_Server_Info *server,
 			  __u32 expected_sequence_number)
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 4af6ea8150c3..39586f2dfad5 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -68,11 +68,6 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 			  char *signature, struct cifs_calc_sig_ctx *ctx);
 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, 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,
 			  __u32 expected_sequence_number);
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 1a0b80fc97d4..6fa60de786e9 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -71,22 +71,6 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
 	return smb;
 }
 
-int
-smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
-	 unsigned int 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);
-}
-
 static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
 			struct smb_message **ppmidQ)
 {
@@ -370,7 +354,7 @@ int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 		return rc;
 	}
 
-	rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
+	rc = cifs_sign_rqst(&rqst, server, &smb->sequence_number);
 	if (rc) {
 		delete_mid(smb);
 		cifs_server_unlock(server);
@@ -378,7 +362,7 @@ int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
 	}
 
 	smb->mid_state = MID_REQUEST_SUBMITTED;
-	rc = smb_send(server, in_buf, in_len);
+	rc = __smb_send_rqst(server, 1, &rqst);
 	cifs_save_when_sent(smb);
 
 	if (rc < 0)
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 91205685057c..6b0d0b511b9f 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -34,17 +34,21 @@ static int
 send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 	       struct smb_message *smb)
 {
-	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;
+	struct kvec iov[1];
+	struct smb_rqst crqst = { .rq_iov = iov, .rq_nvec = 1 };
+	int rc = 0;
 
 	/* +2 for BCC field */
 	in_buf->Command = SMB_COM_NT_CANCEL;
 	in_buf->WordCount = 0;
 	put_bcc(0, in_buf);
 
+	iov[0].iov_base = in_buf;
+	iov[0].iov_len  = sizeof(struct smb_hdr) + 2;
+
 	cifs_server_lock(server);
-	rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
+	rc = cifs_sign_rqst(&crqst, server, &smb->sequence_number);
 	if (rc) {
 		cifs_server_unlock(server);
 		return rc;
@@ -56,7 +60,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, in_len);
+	rc = __smb_send_rqst(server, 1, &crqst);
 	if (rc < 0)
 		server->sequence_number--;
 
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index 2e338e186809..c023c9873c88 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -1043,22 +1043,23 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 			goto out;
 		}
 
-		buf = (char *)smb[i]->resp_buf;
-		resp_iov[i].iov_base = buf;
-		resp_iov[i].iov_len = smb[i]->resp_buf_size;
-
-		if (smb[i]->large_buf)
-			resp_buf_type[i] = CIFS_LARGE_BUFFER;
-		else
-			resp_buf_type[i] = CIFS_SMALL_BUFFER;
-
 		rc = server->ops->check_receive(smb[i], server,
 						     flags & CIFS_LOG_ERROR);
 
-		/* mark it so buf will not be freed by delete_mid */
-		if ((flags & CIFS_NO_RSP_BUF) == 0)
-			smb[i]->resp_buf = NULL;
+		if (resp_iov) {
+			buf = (char *)smb[i]->resp_buf;
+			resp_iov[i].iov_base = buf;
+			resp_iov[i].iov_len = smb[i]->resp_buf_size;
 
+			if (smb[i]->large_buf)
+				resp_buf_type[i] = CIFS_LARGE_BUFFER;
+			else
+				resp_buf_type[i] = CIFS_SMALL_BUFFER;
+
+			/* mark it so buf will not be freed by delete_mid */
+			if ((flags & CIFS_NO_RSP_BUF) == 0)
+				smb[i]->resp_buf = NULL;
+		}
 	}
 
 	/*


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 08/11] cifs: Replace SendReceiveBlockingLock() with SendReceive() plus flags
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (6 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002 David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 09/11] cifs: Remove the server pointer from smb_message David Howells
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Replace the smb1 transport's SendReceiveBlockingLock() with SendReceive()
plus a couple of flags.  This will then allow that to pick up the transport
changes there.

The first flag, CIFS_INTERRUPTIBLE_WAIT, is added to indicate that the wait
should be interruptible and the second, CIFS_WINDOWS_LOCK, indicates that
we need to send a Lock command with unlock type rather than a Cancel.

send_lock_cancel() is then called from cifs_lock_cancel() which is called
from the main transport loop in compound_send_recv().

[!] I *think* the error code handling is probably right.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cifsglob.h      |   8 +-
 fs/smb/client/cifsproto.h     |   7 +-
 fs/smb/client/cifssmb.c       |  18 +--
 fs/smb/client/cifstransport.c | 200 +---------------------------------
 fs/smb/client/smb1ops.c       |  47 +++++++-
 fs/smb/client/smb1proto.h     |   3 -
 fs/smb/client/transport.c     |  10 +-
 7 files changed, 77 insertions(+), 216 deletions(-)

diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 1e9770910e2b..f1df282640c1 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -311,8 +311,9 @@ struct cifs_open_parms;
 struct cifs_credits;
 
 struct smb_version_operations {
-	int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *,
-			   struct smb_message *smb);
+	int (*send_cancel)(struct cifs_ses *ses, struct TCP_Server_Info *server,
+			   struct smb_rqst *rqst, struct smb_message *smb,
+			   unsigned int xid);
 	bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *);
 	/* setup request: allocate mid, sign message */
 	struct smb_message *(*setup_request)(struct cifs_ses *ses,
@@ -1672,6 +1673,7 @@ struct smb_message {
 	__u16 credits_received;	/* number of credits from the response */
 	__u32 pid;		/* process id */
 	__u32 sequence_number;  /* for CIFS signing */
+	unsigned int sr_flags;	/* Flags passed to send_recv() */
 	unsigned long when_alloc;  /* when mid was created */
 #ifdef CONFIG_CIFS_STATS2
 	unsigned long when_sent; /* time when smb send finished */
@@ -1882,6 +1884,8 @@ enum cifs_writable_file_flags {
 #define   CIFS_TRANSFORM_REQ      0x0800 /* transform request before sending */
 #define   CIFS_NO_SRV_RSP         0x1000 /* there is no server response */
 #define   CIFS_COMPRESS_REQ       0x4000 /* compress request before sending */
+#define   CIFS_INTERRUPTIBLE_WAIT 0x8000 /* Interruptible wait (e.g. lock request) */
+#define   CIFS_WINDOWS_LOCK       0x10000 /* We're trying to get a Windows lock */
 
 /* Security Flags: indicate type of session setup needed */
 #define   CIFSSEC_MAY_SIGN	0x00001
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 39586f2dfad5..4676268bd621 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -604,11 +604,12 @@ static inline void free_dentry_path(void *page)
 }
 
 static inline int
-send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-	    struct smb_message *smb)
+send_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server,
+	    struct smb_rqst *rqst, struct smb_message *smb,
+	    unsigned int xid)
 {
 	return server->ops->send_cancel ?
-				server->ops->send_cancel(server, rqst, smb) : 0;
+		server->ops->send_cancel(ses, server, rqst, smb, xid) : 0;
 }
 
 struct cifs_unix_set_info_args {
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 65e517aaa40f..1460c0daf71f 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -2060,7 +2060,7 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
 /*	LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
 	unsigned int in_len;
 	int bytes_returned;
-	int flags = 0;
+	int flags = CIFS_WINDOWS_LOCK | CIFS_INTERRUPTIBLE_WAIT;
 	__u16 count;
 
 	cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n",
@@ -2105,8 +2105,9 @@ CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon,
 	pSMB->ByteCount = cpu_to_le16(count);
 
 	if (waitFlag)
-		rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_len,
-			(struct smb_hdr *) pSMB, &bytes_returned);
+		rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
+				 (struct smb_hdr *) pSMB, &bytes_returned,
+				 flags);
 	else
 		rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, in_len, flags);
 	cifs_small_buf_release(pSMB);
@@ -2131,7 +2132,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
 	struct cifs_posix_lock *parm_data;
 	unsigned int in_len;
 	int rc = 0;
-	int timeout = 0;
+	int sr_flags = CIFS_INTERRUPTIBLE_WAIT;
 	int bytes_returned = 0;
 	int resp_buf_type = 0;
 	__u16 params, param_offset, offset, byte_count, count;
@@ -2174,7 +2175,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
 
 	parm_data->lock_type = cpu_to_le16(lock_type);
 	if (waitFlag) {
-		timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
+		sr_flags |= CIFS_BLOCKING_OP; /* blocking operation, no timeout */
 		parm_data->lock_flags = cpu_to_le16(1);
 		pSMB->Timeout = cpu_to_le32(-1);
 	} else
@@ -2191,13 +2192,14 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
 	in_len += byte_count;
 	pSMB->ByteCount = cpu_to_le16(byte_count);
 	if (waitFlag) {
-		rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, in_len,
-			(struct smb_hdr *) pSMBr, &bytes_returned);
+		rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, in_len,
+				 (struct smb_hdr *) pSMBr, &bytes_returned,
+				 sr_flags);
 	} else {
 		iov[0].iov_base = (char *)pSMB;
 		iov[0].iov_len = in_len;
 		rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
-				&resp_buf_type, timeout, &rsp_iov);
+				&resp_buf_type, sr_flags, &rsp_iov);
 		pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base;
 	}
 	cifs_small_buf_release(pSMB);
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 6fa60de786e9..4bb673d9b56b 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -240,13 +240,6 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 		return -EIO;
 	}
 
-	spin_lock(&server->srv_lock);
-	if (server->tcpStatus == CifsExiting) {
-		spin_unlock(&server->srv_lock);
-		return -ENOENT;
-	}
-	spin_unlock(&server->srv_lock);
-
 	/* Ensure that we do not send more than 50 overlapping requests
 	   to the same server. We may make this configurable later or
 	   use ses->maxReq */
@@ -262,194 +255,11 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 	if (rc < 0)
 		return rc;
 
-	*pbytes_returned = resp_iov.iov_len;
-	if (resp_iov.iov_len)
-		memcpy(out_buf, resp_iov.iov_base, resp_iov.iov_len);
-	free_rsp_buf(resp_buf_type, resp_iov.iov_base);
-	return rc;
-}
-
-/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
-   blocking lock to return. */
-
-static int
-send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
-		 struct smb_hdr *in_buf, unsigned int in_len,
-		 struct smb_hdr *out_buf)
-{
-	int bytes_returned;
-	struct cifs_ses *ses = tcon->ses;
-	LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
-
-	/* We just modify the current in_buf to change
-	   the type of lock from LOCKING_ANDX_SHARED_LOCK
-	   or LOCKING_ANDX_EXCLUSIVE_LOCK to
-	   LOCKING_ANDX_CANCEL_LOCK. */
-
-	pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
-	pSMB->Timeout = 0;
-	pSMB->hdr.Mid = get_next_mid(ses->server);
-
-	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, 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;
-	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;
-	}
-	ses = tcon->ses;
-	server = ses->server;
-
-	if (server == NULL) {
-		cifs_dbg(VFS, "Null tcp session\n");
-		return -EIO;
-	}
-
-	spin_lock(&server->srv_lock);
-	if (server->tcpStatus == CifsExiting) {
-		spin_unlock(&server->srv_lock);
-		return -ENOENT;
-	}
-	spin_unlock(&server->srv_lock);
-
-	/* Ensure that we do not send more than 50 overlapping requests
-	   to the same server. We may make this configurable later or
-	   use ses->maxReq */
-
-	if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-		cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
-			      in_len);
-		return -EIO;
-	}
-
-	rc = wait_for_free_request(server, CIFS_BLOCKING_OP, &instance);
-	if (rc)
-		return rc;
-
-	/* make sure that we sign in the same order that we send on this socket
-	   and avoid races inside tcp sendmsg code that could cause corruption
-	   of smb data */
-
-	cifs_server_lock(server);
-
-	rc = allocate_mid(ses, in_buf, &smb);
-	if (rc) {
-		cifs_server_unlock(server);
-		return rc;
-	}
-
-	rc = cifs_sign_rqst(&rqst, server, &smb->sequence_number);
-	if (rc) {
-		delete_mid(smb);
-		cifs_server_unlock(server);
-		return rc;
-	}
-
-	smb->mid_state = MID_REQUEST_SUBMITTED;
-	rc = __smb_send_rqst(server, 1, &rqst);
-	cifs_save_when_sent(smb);
-
-	if (rc < 0)
-		server->sequence_number -= 2;
-
-	cifs_server_unlock(server);
-
-	if (rc < 0) {
-		delete_mid(smb);
-		return rc;
-	}
-
-	/* Wait for a reply - allow signals to interrupt. */
-	rc = wait_event_interruptible(server->response_q,
-		(!(smb->mid_state == MID_REQUEST_SUBMITTED ||
-		   smb->mid_state == MID_RESPONSE_RECEIVED)) ||
-		((server->tcpStatus != CifsGood) &&
-		 (server->tcpStatus != CifsNew)));
-
-	/* Were we interrupted by a signal ? */
-	spin_lock(&server->srv_lock);
-	if ((rc == -ERESTARTSYS) &&
-		(smb->mid_state == MID_REQUEST_SUBMITTED ||
-		 smb->mid_state == MID_RESPONSE_RECEIVED) &&
-		((server->tcpStatus == CifsGood) ||
-		 (server->tcpStatus == CifsNew))) {
-		spin_unlock(&server->srv_lock);
-
-		if (in_buf->Command == SMB_COM_TRANSACTION2) {
-			/* POSIX lock. We send a NT_CANCEL SMB to cause the
-			   blocking lock to return. */
-			rc = send_cancel(server, &rqst, smb);
-			if (rc) {
-				delete_mid(smb);
-				return rc;
-			}
-		} else {
-			/* Windows lock. We send a LOCKINGX_CANCEL_LOCK
-			   to cause the blocking lock to return. */
-
-			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. */
-			if (rc && rc != -ENOLCK) {
-				delete_mid(smb);
-				return rc;
-			}
-		}
-
-		rc = wait_for_response(server, smb);
-		if (rc) {
-			send_cancel(server, &rqst, smb);
-			spin_lock(&smb->mid_lock);
-			if (smb->mid_state == MID_REQUEST_SUBMITTED ||
-			    smb->mid_state == MID_RESPONSE_RECEIVED) {
-				/* no longer considered to be "in-flight" */
-				smb->callback = release_mid;
-				spin_unlock(&smb->mid_lock);
-				return rc;
-			}
-			spin_unlock(&smb->mid_lock);
-		}
-
-		/* We got the response - restart system call. */
-		rstart = 1;
-		spin_lock(&server->srv_lock);
-	}
-	spin_unlock(&server->srv_lock);
-
-	rc = cifs_sync_mid_result(smb, server);
-	if (rc != 0)
-		return rc;
-
-	/* rcvd frame is ok */
-	if (out_buf == NULL || smb->mid_state != MID_RESPONSE_READY) {
-		rc = -EIO;
-		cifs_tcon_dbg(VFS, "Bad MID state?\n");
-		goto out;
+	if (out_buf) {
+		*pbytes_returned = resp_iov.iov_len;
+		if (resp_iov.iov_len)
+			memcpy(out_buf, resp_iov.iov_base, resp_iov.iov_len);
 	}
-
-	*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);
-	if (rstart && rc == -EACCES)
-		return -ERESTARTSYS;
+	free_rsp_buf(resp_buf_type, resp_iov.iov_base);
 	return rc;
 }
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 6b0d0b511b9f..5754427a4d30 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -31,8 +31,9 @@
  * SMB_COM_NT_CANCEL request and then sends it.
  */
 static int
-send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-	       struct smb_message *smb)
+send_nt_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server,
+	       struct smb_rqst *rqst, struct smb_message *smb,
+	       unsigned int xid)
 {
 	struct smb_hdr *in_buf = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 	struct kvec iov[1];
@@ -72,6 +73,46 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 	return rc;
 }
 
+/*
+ * Send a LOCKINGX_CANCEL_LOCK to cause the Windows blocking lock to
+ * return.
+ */
+static int
+send_lock_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server,
+		 struct smb_rqst *rqst, struct smb_message *smb,
+		 unsigned int xid)
+{
+	struct smb_hdr *in_buf = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
+	unsigned int in_len = rqst->rq_iov[0].iov_len;
+	LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
+	int rc;
+
+	/* We just modify the current in_buf to change
+	 * the type of lock from LOCKING_ANDX_SHARED_LOCK
+	 * or LOCKING_ANDX_EXCLUSIVE_LOCK to
+	 * LOCKING_ANDX_CANCEL_LOCK.
+	 */
+	pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
+	pSMB->Timeout = 0;
+	pSMB->hdr.Mid = get_next_mid(ses->server);
+
+	rc = SendReceive(xid, ses, in_buf, in_len, NULL, NULL, 0);
+	if (rc == -ENOLCK)
+		rc = 0; /* If we get back -ENOLCK, it probably means we managed
+			 * to cancel the lock command before it took effect.
+			 */
+	return rc;
+}
+
+static int cifs_send_cancel(struct cifs_ses *ses, struct TCP_Server_Info *server,
+			    struct smb_rqst *rqst, struct smb_message *smb,
+			    unsigned int xid)
+{
+	if (smb->sr_flags & CIFS_WINDOWS_LOCK)
+		return send_lock_cancel(ses, server, rqst, smb, xid);
+	return send_nt_cancel(ses, server, rqst, smb, xid);
+}
+
 static bool
 cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
 {
@@ -1398,7 +1439,7 @@ cifs_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
 }
 
 struct smb_version_operations smb1_operations = {
-	.send_cancel = send_nt_cancel,
+	.send_cancel = cifs_send_cancel,
 	.compare_fids = cifs_compare_fids,
 	.setup_request = cifs_setup_request,
 	.setup_async_request = cifs_setup_async_request,
diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
index fc278c1dacbb..1588bdf8ba29 100644
--- a/fs/smb/client/smb1proto.h
+++ b/fs/smb/client/smb1proto.h
@@ -223,8 +223,5 @@ int SendReceive2(const unsigned int xid, struct cifs_ses *ses,
 int SendReceive(const unsigned int xid, struct cifs_ses *ses,
 		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, unsigned int in_len,
-			    struct smb_hdr *out_buf, int *pbytes_returned);
 
 #endif /* _SMB1PROTO_H */
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index c023c9873c88..d347febc821a 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -643,12 +643,16 @@ cifs_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
 
 int wait_for_response(struct TCP_Server_Info *server, struct smb_message *smb)
 {
+	unsigned int sleep_state = TASK_KILLABLE;
 	int error;
 
+	if (smb->sr_flags & CIFS_INTERRUPTIBLE_WAIT)
+		sleep_state = TASK_INTERRUPTIBLE;
+
 	error = wait_event_state(server->response_q,
 				 smb->mid_state != MID_REQUEST_SUBMITTED &&
 				 smb->mid_state != MID_RESPONSE_RECEIVED,
-				 (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE));
+				 (sleep_state | TASK_FREEZABLE_UNSAFE));
 	if (error < 0)
 		return -ERESTARTSYS;
 
@@ -702,6 +706,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 		return PTR_ERR(smb);
 	}
 
+	smb->sr_flags = flags;
 	smb->receive = receive;
 	smb->callback = callback;
 	smb->callback_data = cbdata;
@@ -946,6 +951,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 			return PTR_ERR(smb[i]);
 		}
 
+		smb[i]->sr_flags = flags;
 		smb[i]->mid_state = MID_REQUEST_SUBMITTED;
 		smb[i]->optype = optype;
 		/*
@@ -1012,7 +1018,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 		for (; i < num_rqst; i++) {
 			cifs_server_dbg(FYI, "Cancelling wait for mid %llu cmd: %d\n",
 				 smb[i]->mid, le16_to_cpu(smb[i]->command));
-			send_cancel(server, &rqst[i], smb[i]);
+			send_cancel(ses, server, &rqst[i], smb[i], xid);
 			spin_lock(&smb[i]->mid_lock);
 			smb[i]->wait_cancelled = true;
 			if (smb[i]->mid_state == MID_REQUEST_SUBMITTED ||


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 09/11] cifs: Remove the server pointer from smb_message
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (7 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 08/11] cifs: Replace SendReceiveBlockingLock() with SendReceive() plus flags David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 10/11] cifs: Don't need state locking in smb2_get_mid_entry() David Howells
  2025-11-24 12:42 ` [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors David Howells
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Remove the server pointer from smb_message and instead pass it down to all
the things that access it.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com> (RDMA, smbdirect)
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cifsglob.h      | 10 ++++----
 fs/smb/client/cifsproto.h     | 21 +++++++++++------
 fs/smb/client/cifssmb.c       | 15 +++++-------
 fs/smb/client/cifstransport.c | 13 +++++------
 fs/smb/client/connect.c       | 34 +++++++++++++--------------
 fs/smb/client/netmisc.c       |  5 ++--
 fs/smb/client/smb1ops.c       |  4 ++--
 fs/smb/client/smb2ops.c       | 22 +++++++++---------
 fs/smb/client/smb2pdu.c       | 23 ++++++++----------
 fs/smb/client/smb2transport.c |  7 +++---
 fs/smb/client/transport.c     | 44 ++++++++++++++++-------------------
 11 files changed, 97 insertions(+), 101 deletions(-)

diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index f1df282640c1..33e8ecec0067 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1654,7 +1654,7 @@ typedef int (*mid_receive_t)(struct TCP_Server_Info *server,
  * - it will be called by cifsd, with no locks held
  * - the mid will be removed from any lists
  */
-typedef void (*mid_callback_t)(struct smb_message *smb);
+typedef void (*mid_callback_t)(struct TCP_Server_Info *srv, struct smb_message *smb);
 
 /*
  * This is the protopyte for mid handle function. This is called once the mid
@@ -1666,8 +1666,7 @@ typedef int (*mid_handle_t)(struct TCP_Server_Info *server,
 /* one of these for every pending CIFS request to the server */
 struct smb_message {
 	struct list_head qhead;	/* mids waiting on reply from this server */
-	struct kref refcount;
-	struct TCP_Server_Info *server;	/* server corresponding to this mid */
+	refcount_t refcount;
 	__u64 mid;		/* multiplex id */
 	__u16 credits;		/* number of credits consumed by this mid */
 	__u16 credits_received;	/* number of credits from the response */
@@ -2334,7 +2333,8 @@ static inline bool cifs_netbios_name(const char *name, size_t namelen)
  * Execute mid callback atomically - ensures callback runs exactly once
  * and prevents sleeping in atomic context.
  */
-static inline void mid_execute_callback(struct smb_message *smb)
+static inline void mid_execute_callback(struct TCP_Server_Info *server,
+					struct smb_message *smb)
 {
 	mid_callback_t callback;
 
@@ -2344,7 +2344,7 @@ static inline void mid_execute_callback(struct smb_message *smb)
 	spin_unlock(&smb->mid_lock);
 
 	if (callback)
-		callback(smb);
+		callback(server, smb);
 }
 
 #define CIFS_REPARSE_SUPPORT(tcon) \
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 4676268bd621..df7e86e0471c 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -133,7 +133,7 @@ int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
 ssize_t cifs_discard_from_socket(struct TCP_Server_Info *server, size_t to_read);
 int cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter,
 			       unsigned int to_read);
-void dequeue_mid(struct smb_message *mid, bool malformed);
+void dequeue_mid(struct TCP_Server_Info *server, struct smb_message *mid, bool malformed);
 int cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required);
 int cifs_handle_standard(struct TCP_Server_Info *server, struct smb_message *mid);
 int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs);
@@ -435,7 +435,8 @@ struct vfsmount *cifs_d_automount(struct path *path);
 int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
 void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
 int map_smb_to_linux_error(char *buf, bool logErr);
-int map_and_check_smb_error(struct smb_message *mid, bool logErr);
+int map_and_check_smb_error(struct TCP_Server_Info *server,
+			    struct smb_message *mid, bool logErr);
 unsigned int smbCalcSize(void *buf);
 struct timespec64 cifs_NTtimeToUnix(__le64 ntutc);
 u64 cifs_UnixTimeToNT(struct timespec64 t);
@@ -523,9 +524,9 @@ int E_md4hash(const unsigned char *passwd, unsigned char *p16,
 /*
  * transport.c
  */
-void cifs_wake_up_task(struct smb_message *mid);
-void __release_mid(struct kref *refcount);
-void delete_mid(struct smb_message *mid);
+void cifs_wake_up_task(struct TCP_Server_Info *server, struct smb_message *mid);
+void __release_mid(struct TCP_Server_Info *server, struct smb_message *smb);
+void delete_mid(struct TCP_Server_Info *server, struct smb_message *mid);
 int smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
 		  size_t *sent);
 unsigned long smb_rqst_len(struct TCP_Server_Info *server, struct smb_rqst *rqst);
@@ -688,9 +689,15 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
 	return true;
 }
 
-static inline void release_mid(struct smb_message *smb)
+static inline void smb_get_mid(struct smb_message *smb)
 {
-	kref_put(&smb->refcount, __release_mid);
+	refcount_inc(&smb->refcount);
+}
+
+static inline void release_mid(struct TCP_Server_Info *server, struct smb_message *smb)
+{
+	if (refcount_dec_and_test(&smb->refcount))
+		__release_mid(server, smb);
 }
 
 static inline void cifs_free_open_info(struct cifs_open_info_data *data)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 1460c0daf71f..d28b1b113e79 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -585,12 +585,11 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
  * FIXME: maybe we should consider checking that the reply matches request?
  */
 static void
-cifs_echo_callback(struct smb_message *smb)
+cifs_echo_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	struct TCP_Server_Info *server = smb->callback_data;
 	struct cifs_credits credits = { .value = 1, .instance = 0 };
 
-	release_mid(smb);
+	release_mid(server, smb);
 	add_credits(server, &credits, CIFS_ECHO_OP);
 }
 
@@ -1318,12 +1317,11 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
 }
 
 static void
-cifs_readv_callback(struct smb_message *smb)
+cifs_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	struct cifs_io_subrequest *rdata = smb->callback_data;
 	struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
 	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 = 1,
 				 .rq_iter = rdata->subreq.io_iter };
@@ -1421,7 +1419,7 @@ cifs_readv_callback(struct smb_message *smb)
 	rdata->subreq.transferred += rdata->got_bytes;
 	trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
 	netfs_read_subreq_terminated(&rdata->subreq);
-	release_mid(smb);
+	release_mid(server, smb);
 	add_credits(server, &credits, 0);
 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
 			      server->credits, server->in_flight,
@@ -1737,10 +1735,9 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
  * workqueue completion task.
  */
 static void
-cifs_writev_callback(struct smb_message *smb)
+cifs_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	struct cifs_io_subrequest *wdata = smb->callback_data;
-	struct TCP_Server_Info *server = wdata->server;
 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
 	WRITE_RSP *rsp = (WRITE_RSP *)smb->resp_buf;
 	struct cifs_credits credits = {
@@ -1804,7 +1801,7 @@ cifs_writev_callback(struct smb_message *smb)
 			      0, cifs_trace_rw_credits_write_response_clear);
 	wdata->credits.value = 0;
 	cifs_write_subrequest_terminated(wdata, result);
-	release_mid(smb);
+	release_mid(server, smb);
 	trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0,
 			      server->credits, server->in_flight,
 			      credits.value, cifs_trace_rw_credits_write_response_add);
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 4bb673d9b56b..218c0fad901b 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -46,7 +46,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
 
 	smb = mempool_alloc(&smb_message_pool, GFP_NOFS);
 	memset(smb, 0, sizeof(struct smb_message));
-	kref_init(&smb->refcount);
+	refcount_set(&smb->refcount, 1);
 	spin_lock_init(&smb->mid_lock);
 	smb->mid = get_mid(smb_buffer);
 	smb->pid = current->pid;
@@ -55,7 +55,6 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
 	/* easier to use jiffies */
 	/* when mid allocated can be before when sent */
 	smb->when_alloc = jiffies;
-	smb->server = server;
 
 	/*
 	 * The default is for the mid to be synchronous, so the
@@ -120,7 +119,7 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 
 	rc = cifs_sign_rqst(rqst, server, &smb->sequence_number);
 	if (rc) {
-		release_mid(smb);
+		release_mid(server, smb);
 		return ERR_PTR(rc);
 	}
 
@@ -180,11 +179,11 @@ cifs_check_receive(struct smb_message *smb, struct TCP_Server_Info *server,
 	}
 
 	/* BB special case reconnect tid and uid here? */
-	return map_and_check_smb_error(smb, log_error);
+	return map_and_check_smb_error(server, smb, log_error);
 }
 
 struct smb_message *
-cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
+cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
 		   struct smb_rqst *rqst)
 {
 	int rc;
@@ -194,9 +193,9 @@ cifs_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *ignored,
 	rc = allocate_mid(ses, hdr, &smb);
 	if (rc)
 		return ERR_PTR(rc);
-	rc = cifs_sign_rqst(rqst, ses->server, &smb->sequence_number);
+	rc = cifs_sign_rqst(rqst, server, &smb->sequence_number);
 	if (rc) {
-		delete_mid(smb);
+		delete_mid(server, smb);
 		return ERR_PTR(rc);
 	}
 	return smb;
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 86a328b3615a..7a1112fae6ee 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -326,7 +326,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
 	cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
 	spin_lock(&server->mid_queue_lock);
 	list_for_each_entry_safe(smb, nsmb, &server->pending_mid_q, qhead) {
-		kref_get(&smb->refcount);
+		smb_get_mid(smb);
 		if (smb->mid_state == MID_REQUEST_SUBMITTED)
 			smb->mid_state = MID_RETRY_NEEDED;
 		list_move(&smb->qhead, &retry_list);
@@ -338,8 +338,8 @@ cifs_abort_connection(struct TCP_Server_Info *server)
 	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
 	list_for_each_entry_safe(smb, nsmb, &retry_list, qhead) {
 		list_del_init(&smb->qhead);
-		mid_execute_callback(smb);
-		release_mid(smb);
+		mid_execute_callback(server, smb);
+		release_mid(server, smb);
 	}
 }
 
@@ -883,7 +883,7 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 			 */
 			spin_lock(&server->mid_queue_lock);
 			list_for_each_entry_safe(smb, nsmb, &server->pending_mid_q, qhead) {
-				kref_get(&smb->refcount);
+				smb_get_mid(smb);
 				list_move(&smb->qhead, &dispose_list);
 				smb->deleted_from_q = true;
 			}
@@ -916,8 +916,8 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 				list_del_init(&smb->qhead);
 				smb->mid_rc = mid_rc;
 				smb->mid_state = MID_RC;
-				mid_execute_callback(smb);
-				release_mid(smb);
+				mid_execute_callback(server, smb);
+				release_mid(server, smb);
 			}
 
 			/*
@@ -949,12 +949,12 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
 }
 
 void
-dequeue_mid(struct smb_message *smb, bool malformed)
+dequeue_mid(struct TCP_Server_Info *server, struct smb_message *smb, bool malformed)
 {
 #ifdef CONFIG_CIFS_STATS2
 	smb->when_received = jiffies;
 #endif
-	spin_lock(&smb->server->mid_queue_lock);
+	spin_lock(&server->mid_queue_lock);
 	if (!malformed)
 		smb->mid_state = MID_RESPONSE_RECEIVED;
 	else
@@ -964,12 +964,12 @@ dequeue_mid(struct smb_message *smb, bool malformed)
 	 * function has finished processing it is a bug.
 	 */
 	if (smb->deleted_from_q) {
-		spin_unlock(&smb->server->mid_queue_lock);
+		spin_unlock(&server->mid_queue_lock);
 		pr_warn_once("trying to dequeue a deleted mid\n");
 	} else {
 		list_del_init(&smb->qhead);
 		smb->deleted_from_q = true;
-		spin_unlock(&smb->server->mid_queue_lock);
+		spin_unlock(&server->mid_queue_lock);
 	}
 }
 
@@ -1005,7 +1005,7 @@ handle_mid(struct smb_message *smb, struct TCP_Server_Info *server,
 		else
 			server->smallbuf = NULL;
 	}
-	dequeue_mid(smb, malformed);
+	dequeue_mid(server, smb, malformed);
 }
 
 int
@@ -1102,7 +1102,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
 		list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
 			smb = list_entry(tmp, struct smb_message, qhead);
 			cifs_dbg(FYI, "Clearing mid %llu\n", smb->mid);
-			kref_get(&smb->refcount);
+			smb_get_mid(smb);
 			smb->mid_state = MID_SHUTDOWN;
 			list_move(&smb->qhead, &dispose_list);
 			smb->deleted_from_q = true;
@@ -1114,8 +1114,8 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
 			smb = list_entry(tmp, struct smb_message, qhead);
 			cifs_dbg(FYI, "Callback mid %llu\n", smb->mid);
 			list_del_init(&smb->qhead);
-			mid_execute_callback(smb);
-			release_mid(smb);
+			mid_execute_callback(server, smb);
+			release_mid(server, smb);
 		}
 		/* 1/8th of sec is more than enough time for them to exit */
 		msleep(125);
@@ -1356,7 +1356,7 @@ cifs_demultiplex_thread(void *p)
 		if (length < 0) {
 			for (i = 0; i < num_smbs; i++)
 				if (smbs[i])
-					release_mid(smbs[i]);
+					release_mid(server, smbs[i]);
 			continue;
 		}
 
@@ -1389,9 +1389,9 @@ cifs_demultiplex_thread(void *p)
 				}
 
 				if (!smbs[i]->multiRsp || smbs[i]->multiEnd)
-					mid_execute_callback(smbs[i]);
+					mid_execute_callback(server, smbs[i]);
 
-				release_mid(smbs[i]);
+				release_mid(server, smbs[i]);
 			} else if (server->ops->is_oplock_break &&
 				   server->ops->is_oplock_break(bufs[i],
 								server)) {
diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
index fa994fae048b..7ad5a3cc05d1 100644
--- a/fs/smb/client/netmisc.c
+++ b/fs/smb/client/netmisc.c
@@ -889,7 +889,8 @@ map_smb_to_linux_error(char *buf, bool logErr)
 }
 
 int
-map_and_check_smb_error(struct smb_message *smb, bool logErr)
+map_and_check_smb_error(struct TCP_Server_Info *server,
+			struct smb_message *smb, bool logErr)
 {
 	int rc;
 	struct smb_hdr *rhdr = (struct smb_hdr *)smb->resp_buf;
@@ -904,7 +905,7 @@ map_and_check_smb_error(struct smb_message *smb, bool logErr)
 		if (class == ERRSRV && code == ERRbaduid) {
 			cifs_dbg(FYI, "Server returned 0x%x, reconnecting session...\n",
 				code);
-			cifs_signal_cifsd_for_reconnect(smb->server, false);
+			cifs_signal_cifsd_for_reconnect(server, false);
 		}
 	}
 
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 5754427a4d30..fb4c146b6cb3 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -147,7 +147,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
 		if (compare_mid(smb->mid, buf) &&
 		    smb->mid_state == MID_REQUEST_SUBMITTED &&
 		    le16_to_cpu(smb->command) == buf->Command) {
-			kref_get(&smb->refcount);
+			smb_get_mid(smb);
 			spin_unlock(&server->mid_queue_lock);
 			return smb;
 		}
@@ -449,7 +449,7 @@ cifs_check_trans2(struct smb_message *smb, struct TCP_Server_Info *server,
 			return true;
 		/* All parts received or packet is malformed. */
 		smb->multiEnd = true;
-		dequeue_mid(smb, malformed);
+		dequeue_mid(server, smb, malformed);
 		return true;
 	}
 	if (!server->large_buf) {
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 5c8ed852cf55..0bc2e4cc2617 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -406,7 +406,7 @@ __smb2_find_mid(struct TCP_Server_Info *server, char *buf, bool dequeue)
 		if ((smb->mid == wire_mid) &&
 		    (smb->mid_state == MID_REQUEST_SUBMITTED) &&
 		    (smb->command == shdr->Command)) {
-			kref_get(&smb->refcount);
+			smb_get_mid(smb);
 			if (dequeue) {
 				list_del_init(&smb->qhead);
 				smb->deleted_from_q = true;
@@ -4717,7 +4717,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 		if (is_offloaded)
 			smb->mid_state = MID_RESPONSE_RECEIVED;
 		else
-			dequeue_mid(smb, false);
+			dequeue_mid(server, smb, false);
 		return 0;
 	}
 
@@ -4744,7 +4744,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 		if (is_offloaded)
 			smb->mid_state = MID_RESPONSE_MALFORMED;
 		else
-			dequeue_mid(smb, rdata->result);
+			dequeue_mid(server, smb, rdata->result);
 		return 0;
 	}
 
@@ -4763,7 +4763,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 			if (is_offloaded)
 				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
-				dequeue_mid(smb, rdata->result);
+				dequeue_mid(server, smb, rdata->result);
 			return 0;
 		}
 
@@ -4773,7 +4773,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 			if (is_offloaded)
 				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
-				dequeue_mid(smb, rdata->result);
+				dequeue_mid(server, smb, rdata->result);
 			return 0;
 		}
 
@@ -4784,7 +4784,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 			if (is_offloaded)
 				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
-				dequeue_mid(smb, rdata->result);
+				dequeue_mid(server, smb, rdata->result);
 			return 0;
 		}
 		rdata->got_bytes = buffer_len;
@@ -4803,14 +4803,14 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 		if (is_offloaded)
 			smb->mid_state = MID_RESPONSE_MALFORMED;
 		else
-			dequeue_mid(smb, rdata->result);
+			dequeue_mid(server, smb, rdata->result);
 		return 0;
 	}
 
 	if (is_offloaded)
 		smb->mid_state = MID_RESPONSE_RECEIVED;
 	else
-		dequeue_mid(smb, false);
+		dequeue_mid(server, smb, false);
 	return 0;
 }
 
@@ -4857,7 +4857,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
 				dw->server->ops->is_network_name_deleted(dw->buf,
 									 dw->server);
 
-			mid_execute_callback(smb);
+			mid_execute_callback(dw->server, smb);
 		} else {
 			spin_lock(&dw->server->srv_lock);
 			if (dw->server->tcpStatus == CifsNeedReconnect) {
@@ -4865,7 +4865,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
 				smb->mid_state = MID_RETRY_NEEDED;
 				spin_unlock(&dw->server->mid_queue_lock);
 				spin_unlock(&dw->server->srv_lock);
-				mid_execute_callback(smb);
+				mid_execute_callback(dw->server, smb);
 			} else {
 				spin_lock(&dw->server->mid_queue_lock);
 				smb->mid_state = MID_REQUEST_SUBMITTED;
@@ -4876,7 +4876,7 @@ static void smb2_decrypt_offload(struct work_struct *work)
 				spin_unlock(&dw->server->srv_lock);
 			}
 		}
-		release_mid(smb);
+		release_mid(dw->server, smb);
 	}
 
 free_pages:
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index d8a88f62dcac..9c21521061a9 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -4092,9 +4092,8 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
  * FIXME: maybe we should consider checking that the reply matches request?
  */
 static void
-smb2_echo_callback(struct smb_message *smb)
+smb2_echo_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	struct TCP_Server_Info *server = smb->callback_data;
 	struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)smb->resp_buf;
 	struct cifs_credits credits = { .value = 0, .instance = 0 };
 
@@ -4104,7 +4103,7 @@ smb2_echo_callback(struct smb_message *smb)
 		credits.instance = server->reconnect_instance;
 	}
 
-	release_mid(smb);
+	release_mid(server, smb);
 	add_credits(server, &credits, CIFS_ECHO_OP);
 }
 
@@ -4519,12 +4518,11 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
 }
 
 static void
-smb2_readv_callback(struct smb_message *smb)
+smb2_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	struct cifs_io_subrequest *rdata = smb->callback_data;
 	struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode);
 	struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
-	struct TCP_Server_Info *server = rdata->server;
 	struct smb2_hdr *shdr = (struct smb2_hdr *)rdata->iov[0].iov_base;
 	struct cifs_credits credits = {
 		.value = 0,
@@ -4540,9 +4538,9 @@ smb2_readv_callback(struct smb_message *smb)
 		rqst.rq_iter	  = rdata->subreq.io_iter;
 	}
 
-	WARN_ONCE(rdata->server != smb->server,
+	WARN_ONCE(rdata->server != server,
 		  "rdata server %p != mid server %p",
-		  rdata->server, smb->server);
+		  rdata->server, server);
 
 	cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu/%zu\n",
 		 __func__, smb->mid, smb->mid_state, rdata->result,
@@ -4643,7 +4641,7 @@ smb2_readv_callback(struct smb_message *smb)
 	rdata->subreq.transferred += rdata->got_bytes;
 	trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress);
 	netfs_read_subreq_terminated(&rdata->subreq);
-	release_mid(smb);
+	release_mid(server, smb);
 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
 			      server->credits, server->in_flight,
 			      credits.value, cifs_trace_rw_credits_read_response_add);
@@ -4820,11 +4818,10 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
  * workqueue completion task.
  */
 static void
-smb2_writev_callback(struct smb_message *smb)
+smb2_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	struct cifs_io_subrequest *wdata = smb->callback_data;
 	struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
-	struct TCP_Server_Info *server = wdata->server;
 	struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)smb->resp_buf;
 	struct cifs_credits credits = {
 		.value = 0,
@@ -4837,9 +4834,9 @@ smb2_writev_callback(struct smb_message *smb)
 	ssize_t result = 0;
 	size_t written;
 
-	WARN_ONCE(wdata->server != smb->server,
+	WARN_ONCE(wdata->server != server,
 		  "wdata server %p != mid server %p",
-		  wdata->server, smb->server);
+		  wdata->server, server);
 
 	switch (smb->mid_state) {
 	case MID_RESPONSE_RECEIVED:
@@ -4929,7 +4926,7 @@ smb2_writev_callback(struct smb_message *smb)
 			      0, cifs_trace_rw_credits_write_response_clear);
 	wdata->credits.value = 0;
 	cifs_write_subrequest_terminated(wdata, result ?: written);
-	release_mid(smb);
+	release_mid(server, smb);
 	trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
 			      server->credits, server->in_flight,
 			      credits.value, cifs_trace_rw_credits_write_response_add);
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 21b027040643..6d76b0c6d73d 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -655,14 +655,13 @@ smb2_mid_entry_alloc(const struct smb2_hdr *shdr,
 
 	smb = mempool_alloc(&smb_message_pool, GFP_NOFS);
 	memset(smb, 0, sizeof(*smb));
-	kref_init(&smb->refcount);
+	refcount_set(&smb->refcount, 1);
 	spin_lock_init(&smb->mid_lock);
 	smb->mid = le64_to_cpu(shdr->MessageId);
 	smb->credits = credits > 0 ? credits : 1;
 	smb->pid = current->pid;
 	smb->command = shdr->Command; /* Always LE */
 	smb->when_alloc = jiffies;
-	smb->server = server;
 
 	/*
 	 * The default is for the mid to be synchronous, so the
@@ -779,7 +778,7 @@ smb2_setup_request(struct cifs_ses *ses, struct TCP_Server_Info *server,
 	rc = smb2_sign_rqst(rqst, server);
 	if (rc) {
 		revert_current_mid_from_hdr(server, shdr);
-		delete_mid(mid);
+		delete_mid(server, mid);
 		return ERR_PTR(rc);
 	}
 
@@ -813,7 +812,7 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
 	rc = smb2_sign_rqst(rqst, server);
 	if (rc) {
 		revert_current_mid_from_hdr(server, shdr);
-		release_mid(smb);
+		release_mid(server, smb);
 		return ERR_PTR(rc);
 	}
 
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index d347febc821a..362c5c6c91a4 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -32,24 +32,21 @@
 #include "compress.h"
 
 void
-cifs_wake_up_task(struct smb_message *smb)
+cifs_wake_up_task(struct TCP_Server_Info *server, struct smb_message *smb)
 {
 	if (smb->mid_state == MID_RESPONSE_RECEIVED)
 		smb->mid_state = MID_RESPONSE_READY;
 	wake_up_process(smb->callback_data);
 }
 
-void __release_mid(struct kref *refcount)
+void __release_mid(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	struct smb_message *smb =
-			container_of(refcount, struct smb_message, refcount);
 #ifdef CONFIG_CIFS_STATS2
-	__le16 command = smb->server->vals->lock_cmd;
+	__le16 command = server->vals->lock_cmd;
 	__u16 smb_cmd = le16_to_cpu(smb->command);
 	unsigned long now;
 	unsigned long roundtrip_time;
 #endif
-	struct TCP_Server_Info *server = smb->server;
 
 	if (smb->resp_buf && smb->wait_cancelled &&
 	    (smb->mid_state == MID_RESPONSE_RECEIVED ||
@@ -120,17 +117,17 @@ void __release_mid(struct kref *refcount)
 }
 
 void
-delete_mid(struct smb_message *smb)
+delete_mid(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	spin_lock(&smb->server->mid_queue_lock);
+	spin_lock(&server->mid_queue_lock);
 
 	if (!smb->deleted_from_q) {
 		list_del_init(&smb->qhead);
 		smb->deleted_from_q = true;
 	}
-	spin_unlock(&smb->server->mid_queue_lock);
+	spin_unlock(&server->mid_queue_lock);
 
-	release_mid(smb);
+	release_mid(server, smb);
 }
 
 /*
@@ -728,7 +725,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
 	if (rc < 0) {
 		revert_current_mid(server, smb->credits);
 		server->sequence_number -= 2;
-		delete_mid(smb);
+		delete_mid(server, smb);
 	}
 
 	cifs_server_unlock(server);
@@ -778,14 +775,13 @@ int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server
 	spin_unlock(&server->mid_queue_lock);
 
 sync_mid_done:
-	release_mid(smb);
+	release_mid(server, smb);
 	return rc;
 }
 
 static void
-cifs_compound_callback(struct smb_message *smb)
+cifs_compound_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	struct TCP_Server_Info *server = smb->server;
 	struct cifs_credits credits = {
 		.value = server->ops->get_credits(smb),
 		.instance = server->reconnect_instance,
@@ -798,17 +794,17 @@ cifs_compound_callback(struct smb_message *smb)
 }
 
 static void
-cifs_compound_last_callback(struct smb_message *smb)
+cifs_compound_last_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	cifs_compound_callback(smb);
-	cifs_wake_up_task(smb);
+	cifs_compound_callback(server, smb);
+	cifs_wake_up_task(server, smb);
 }
 
 static void
-cifs_cancelled_callback(struct smb_message *smb)
+cifs_cancelled_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 {
-	cifs_compound_callback(smb);
-	release_mid(smb);
+	cifs_compound_callback(server, smb);
+	release_mid(server, smb);
 }
 
 /*
@@ -942,7 +938,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 		if (IS_ERR(smb[i])) {
 			revert_current_mid(server, i);
 			for (j = 0; j < i; j++)
-				delete_mid(smb[j]);
+				delete_mid(server, smb[j]);
 			cifs_server_unlock(server);
 
 			/* Update # of requests on wire to server */
@@ -1094,7 +1090,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 	 */
 	for (i = 0; i < num_rqst; i++) {
 		if (!cancelled_mid[i])
-			delete_mid(smb[i]);
+			delete_mid(server, smb[i]);
 	}
 
 	return rc;
@@ -1143,7 +1139,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct smb_message *smb,
 	int length;
 
 	length = cifs_discard_remaining_data(server);
-	dequeue_mid(smb, malformed);
+	dequeue_mid(server, smb, malformed);
 	smb->resp_buf = server->smallbuf;
 	server->smallbuf = NULL;
 	return length;
@@ -1280,7 +1276,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
 	if (server->total_read < buflen)
 		return cifs_readv_discard(server, smb);
 
-	dequeue_mid(smb, false);
+	dequeue_mid(server, smb, false);
 	smb->resp_buf = server->smallbuf;
 	server->smallbuf = NULL;
 	return length;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 10/11] cifs: Don't need state locking in smb2_get_mid_entry()
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (8 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 09/11] cifs: Remove the server pointer from smb_message David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 12:42 ` [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors David Howells
  10 siblings, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

There's no need to get ->srv_lock or ->ses_lock in smb2_get_mid_entry() as
all that happens of relevance (to the lock) inside the locked sections is
the reading of one status value in each.

Replace the locking with READ_ONCE() and use a switch instead of a chain of
if-statements.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: Shyam Prasad N <sprasad@microsoft.com>
cc: Tom Talpey <tom@talpey.com>
cc: linux-cifs@vger.kernel.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/smb2transport.c | 48 +++++++++++++++--------------------
 1 file changed, 20 insertions(+), 28 deletions(-)

diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 6d76b0c6d73d..47eab3753c9e 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -684,43 +684,35 @@ static int
 smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server,
 		   struct smb2_hdr *shdr, struct smb_message **smb)
 {
-	spin_lock(&server->srv_lock);
-	if (server->tcpStatus == CifsExiting) {
-		spin_unlock(&server->srv_lock);
+	switch (READ_ONCE(server->tcpStatus)) {
+	case CifsExiting:
 		return -ENOENT;
-	}
-
-	if (server->tcpStatus == CifsNeedReconnect) {
-		spin_unlock(&server->srv_lock);
+	case CifsNeedReconnect:
 		cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
 		return -EAGAIN;
-	}
-
-	if (server->tcpStatus == CifsNeedNegotiate &&
-	   shdr->Command != SMB2_NEGOTIATE) {
-		spin_unlock(&server->srv_lock);
-		return -EAGAIN;
-	}
-	spin_unlock(&server->srv_lock);
-
-	spin_lock(&ses->ses_lock);
-	if (ses->ses_status == SES_NEW) {
-		if ((shdr->Command != SMB2_SESSION_SETUP) &&
-		    (shdr->Command != SMB2_NEGOTIATE)) {
-			spin_unlock(&ses->ses_lock);
+	case CifsNeedNegotiate:
+		if (shdr->Command != SMB2_NEGOTIATE)
 			return -EAGAIN;
-		}
-		/* else ok - we are setting up session */
+		break;
+	default:
+		break;
 	}
 
-	if (ses->ses_status == SES_EXITING) {
-		if (shdr->Command != SMB2_LOGOFF) {
-			spin_unlock(&ses->ses_lock);
+	switch (READ_ONCE(ses->ses_status)) {
+	case SES_NEW:
+		if (shdr->Command != SMB2_SESSION_SETUP &&
+		    shdr->Command != SMB2_NEGOTIATE)
+			return -EAGAIN;
+			/* else ok - we are setting up session */
+		break;
+	case SES_EXITING:
+		if (shdr->Command != SMB2_LOGOFF)
 			return -EAGAIN;
-		}
 		/* else ok - we are shutting down the session */
+		break;
+	default:
+		break;
 	}
-	spin_unlock(&ses->ses_lock);
 
 	*smb = smb2_mid_entry_alloc(shdr, server);
 	if (*smb == NULL)


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors
  2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
                   ` (9 preceding siblings ...)
  2025-11-24 12:42 ` [PATCH v4 10/11] cifs: Don't need state locking in smb2_get_mid_entry() David Howells
@ 2025-11-24 12:42 ` David Howells
  2025-11-24 14:22   ` Stefan Metzmacher
  2025-11-24 14:38   ` David Howells
  10 siblings, 2 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 12:42 UTC (permalink / raw)
  To: Steve French
  Cc: David Howells, Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher,
	linux-cifs, netfs, linux-fsdevel, linux-kernel

Add a tracepoint to log EIO errors and give it the capacity to convey up to
two integers of information.  This is then wrapped with three functions:

 int smb_EIO(enum smb_eio_trace trace)
 int smb_EIO1(enum smb_eio_trace trace, unsigned long info)
 int smb_EIO2(enum smb_eio_trace trace, unsigned long info,
	      unsigned long info2)

depending on how many bits of info are desired to be logged with any
particular trace.  The functions all return -EIO and can be used in place
of -EIO.

The trace argument is an enum value that gets translated to a string when
the trace is printed.

This makes is easier to log EIO instances when the client is under high
load than turning on a printk wrapper such as cifs_dbg().  Granted, EIO
could have its own separate EIO printing since EIO shouldn't happen.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
---
 fs/smb/client/cached_dir.c    |   2 +-
 fs/smb/client/cifsacl.c       |  10 +-
 fs/smb/client/cifsencrypt.c   |  13 ++-
 fs/smb/client/cifsglob.h      |  88 -----------------
 fs/smb/client/cifsproto.h     | 106 ++++++++++++++++++++
 fs/smb/client/cifssmb.c       | 147 ++++++++++++++++++----------
 fs/smb/client/cifstransport.c |   8 +-
 fs/smb/client/compress.c      |   2 +-
 fs/smb/client/connect.c       |  11 ++-
 fs/smb/client/dir.c           |   6 +-
 fs/smb/client/file.c          |   6 +-
 fs/smb/client/inode.c         |  14 +--
 fs/smb/client/link.c          |  10 +-
 fs/smb/client/misc.c          |  18 ++--
 fs/smb/client/netmisc.c       |   4 +
 fs/smb/client/readdir.c       |   2 +-
 fs/smb/client/reparse.c       |  53 ++++++----
 fs/smb/client/sess.c          |   8 +-
 fs/smb/client/smb2file.c      |   6 +-
 fs/smb/client/smb2inode.c     |  12 ++-
 fs/smb/client/smb2maperror.c  |   3 +
 fs/smb/client/smb2ops.c       |  41 +++++---
 fs/smb/client/smb2pdu.c       | 177 +++++++++++++++++++++-------------
 fs/smb/client/smb2transport.c |   2 +-
 fs/smb/client/smbdirect.c     |  18 ++--
 fs/smb/client/trace.h         | 153 +++++++++++++++++++++++++++++
 fs/smb/client/transport.c     |  21 ++--
 fs/smb/client/xattr.c         |   2 +-
 28 files changed, 622 insertions(+), 321 deletions(-)

diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index e3ea6fe7edb4..1db7ab6c2529 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -176,7 +176,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	server = cifs_pick_channel(ses);
 
 	if (!server->ops->new_lease_key)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_no_lease_key);
 
 	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
 	if (!utf16_path)
diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
index 7b88ef38bdf4..78a9d9bb9365 100644
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -301,7 +301,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
 			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
 		goto out_revert_creds;
 	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
 			 __func__, sidkey->datalen);
 		goto invalidate_key;
@@ -318,7 +318,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
 
 	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
 	if (ksid_size > sidkey->datalen) {
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
+			      ksid_size, sidkey->datalen);
 		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
 			 __func__, sidkey->datalen, ksid_size);
 		goto invalidate_key;
@@ -353,7 +354,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
 	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
 		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
 			 __func__, psid->num_subauth);
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_sid_too_many_auth,
+				psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
 	}
 
 	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
@@ -1228,7 +1230,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
 	__u32 dacloffset;
 
 	if (pntsd == NULL)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
 				le32_to_cpu(pntsd->osidoffset));
diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
index a9a57904c6b1..ca2a84e8673e 100644
--- a/fs/smb/client/cifsencrypt.c
+++ b/fs/smb/client/cifsencrypt.c
@@ -75,11 +75,13 @@ static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize,
 			 struct cifs_calc_sig_ctx *ctx)
 {
 	struct iov_iter tmp_iter = *iter;
-	int err = -EIO;
+	size_t did;
+	int err;
 
-	if (iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
-				       cifs_sig_step) != maxsize)
-		return err;
+	did = iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
+					 cifs_sig_step);
+	if (did != maxsize)
+		return smb_EIO2(smb_eio_trace_sig_iter, did, maxsize);
 	return 0;
 }
 
@@ -96,7 +98,8 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
 	iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size);
 
 	if (iov_iter_count(&iter) <= 4)
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_sig_data_too_small,
+				iov_iter_count(&iter), 4);
 
 	rc = cifs_sig_iter(&iter, iov_iter_count(&iter), ctx);
 	if (rc < 0)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 33e8ecec0067..92d8ff2065b3 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -2184,94 +2184,6 @@ static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const
 	dst->FileNameLength = src->FileNameLength;
 }
 
-static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
-				   int num_rqst,
-				   const u8 *sig)
-{
-	unsigned int len, skip;
-	unsigned int nents = 0;
-	unsigned long addr;
-	size_t data_size;
-	int i, j;
-
-	/*
-	 * The first rqst has a transform header where the first 20 bytes are
-	 * not part of the encrypted blob.
-	 */
-	skip = 20;
-
-	/* Assumes the first rqst has a transform header as the first iov.
-	 * I.e.
-	 * rqst[0].rq_iov[0]  is transform header
-	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
-	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
-	 */
-	for (i = 0; i < num_rqst; i++) {
-		data_size = iov_iter_count(&rqst[i].rq_iter);
-
-		/* We really don't want a mixture of pinned and unpinned pages
-		 * in the sglist.  It's hard to keep track of which is what.
-		 * Instead, we convert to a BVEC-type iterator higher up.
-		 */
-		if (data_size &&
-		    WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
-			return -EIO;
-
-		/* We also don't want to have any extra refs or pins to clean
-		 * up in the sglist.
-		 */
-		if (data_size &&
-		    WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
-			return -EIO;
-
-		for (j = 0; j < rqst[i].rq_nvec; j++) {
-			struct kvec *iov = &rqst[i].rq_iov[j];
-
-			addr = (unsigned long)iov->iov_base + skip;
-			if (is_vmalloc_or_module_addr((void *)addr)) {
-				len = iov->iov_len - skip;
-				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
-						      PAGE_SIZE);
-			} else {
-				nents++;
-			}
-			skip = 0;
-		}
-		if (data_size)
-			nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
-	}
-	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
-	return nents;
-}
-
-/* We can not use the normal sg_set_buf() as we will sometimes pass a
- * stack object as buf.
- */
-static inline void cifs_sg_set_buf(struct sg_table *sgtable,
-				   const void *buf,
-				   unsigned int buflen)
-{
-	unsigned long addr = (unsigned long)buf;
-	unsigned int off = offset_in_page(addr);
-
-	addr &= PAGE_MASK;
-	if (is_vmalloc_or_module_addr((void *)addr)) {
-		do {
-			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
-
-			sg_set_page(&sgtable->sgl[sgtable->nents++],
-				    vmalloc_to_page((void *)addr), len, off);
-
-			off = 0;
-			addr += PAGE_SIZE;
-			buflen -= len;
-		} while (buflen);
-	} else {
-		sg_set_page(&sgtable->sgl[sgtable->nents++],
-			    virt_to_page((void *)addr), buflen, off);
-	}
-}
-
 #define CIFS_OPARMS(_cifs_sb, _tcon, _path, _da, _cd, _co, _mode) \
 	((struct cifs_open_parms) { \
 		.tcon = _tcon, \
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index df7e86e0471c..6dbf2cec3859 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -707,4 +707,110 @@ static inline void cifs_free_open_info(struct cifs_open_info_data *data)
 	memset(data, 0, sizeof(*data));
 }
 
+static inline int smb_EIO(enum smb_eio_trace trace)
+{
+	trace_smb3_eio(trace, 0, 0);
+	return -EIO;
+}
+
+static inline int smb_EIO1(enum smb_eio_trace trace, unsigned long info)
+{
+	trace_smb3_eio(trace, info, 0);
+	return -EIO;
+}
+
+static inline int smb_EIO2(enum smb_eio_trace trace, unsigned long info, unsigned long info2)
+{
+	trace_smb3_eio(trace, info, info2);
+	return -EIO;
+}
+
+static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
+				   int num_rqst,
+				   const u8 *sig)
+{
+	unsigned int len, skip;
+	unsigned int nents = 0;
+	unsigned long addr;
+	size_t data_size;
+	int i, j;
+
+	/*
+	 * The first rqst has a transform header where the first 20 bytes are
+	 * not part of the encrypted blob.
+	 */
+	skip = 20;
+
+	/* Assumes the first rqst has a transform header as the first iov.
+	 * I.e.
+	 * rqst[0].rq_iov[0]  is transform header
+	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+	 */
+	for (i = 0; i < num_rqst; i++) {
+		data_size = iov_iter_count(&rqst[i].rq_iter);
+
+		/* We really don't want a mixture of pinned and unpinned pages
+		 * in the sglist.  It's hard to keep track of which is what.
+		 * Instead, we convert to a BVEC-type iterator higher up.
+		 */
+		if (data_size &&
+		    WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
+			return smb_EIO(smb_eio_trace_user_iter);
+
+		/* We also don't want to have any extra refs or pins to clean
+		 * up in the sglist.
+		 */
+		if (data_size &&
+		    WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
+			return smb_EIO(smb_eio_trace_extract_will_pin);
+
+		for (j = 0; j < rqst[i].rq_nvec; j++) {
+			struct kvec *iov = &rqst[i].rq_iov[j];
+
+			addr = (unsigned long)iov->iov_base + skip;
+			if (is_vmalloc_or_module_addr((void *)addr)) {
+				len = iov->iov_len - skip;
+				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
+						      PAGE_SIZE);
+			} else {
+				nents++;
+			}
+			skip = 0;
+		}
+		if (data_size)
+			nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
+	}
+	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
+	return nents;
+}
+
+/* We can not use the normal sg_set_buf() as we will sometimes pass a
+ * stack object as buf.
+ */
+static inline void cifs_sg_set_buf(struct sg_table *sgtable,
+				   const void *buf,
+				   unsigned int buflen)
+{
+	unsigned long addr = (unsigned long)buf;
+	unsigned int off = offset_in_page(addr);
+
+	addr &= PAGE_MASK;
+	if (is_vmalloc_or_module_addr((void *)addr)) {
+		do {
+			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
+
+			sg_set_page(&sgtable->sgl[sgtable->nents++],
+				    vmalloc_to_page((void *)addr), len, off);
+
+			off = 0;
+			addr += PAGE_SIZE;
+			buflen -= len;
+		} while (buflen);
+	} else {
+		sg_set_page(&sgtable->sgl[sgtable->nents++],
+			    virt_to_page((void *)addr), buflen, off);
+	}
+}
+
 #endif			/* _CIFSPROTO_H */
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index d28b1b113e79..d33c624b3356 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -374,7 +374,8 @@ decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE_RSP *pSMBr)
 
 	count = get_bcc(&pSMBr->hdr);
 	if (count < SMB1_CLIENT_GUID_SIZE)
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_neg_sec_blob_too_small,
+				count, SMB1_CLIENT_GUID_SIZE);
 
 	spin_lock(&cifs_tcp_ses_lock);
 	if (server->srv_count > 1) {
@@ -433,7 +434,7 @@ CIFSSMBNegotiate(const unsigned int xid,
 
 	if (!server) {
 		WARN(1, "%s: server is NULL!\n", __func__);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	}
 
 	rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
@@ -517,7 +518,8 @@ CIFSSMBNegotiate(const unsigned int xid,
 		server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
 		rc = decode_ext_sec_blob(ses, pSMBr);
 	} else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
-		rc = -EIO; /* no crypt key only if plain text pwd */
+		/* no crypt key only if plain text pwd */
+		rc = smb_EIO(smb_eio_trace_neg_no_crypt_key);
 	} else {
 		server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
 		server->capabilities &= ~CAP_EXTENDED_SECURITY;
@@ -543,7 +545,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
 
 	/* BB: do we need to check this? These should never be NULL. */
 	if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	/*
 	 * No need to return error on this operation if tid invalidated and
@@ -554,7 +556,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
 	spin_lock(&tcon->ses->chan_lock);
 	if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
 		spin_unlock(&tcon->ses->chan_lock);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_tdis_in_reconnect);
 	}
 	spin_unlock(&tcon->ses->chan_lock);
 
@@ -651,7 +653,7 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
 	 * should probably be a BUG()
 	 */
 	if (!ses || !ses->server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	mutex_lock(&ses->session_mutex);
 	spin_lock(&ses->chan_lock);
@@ -981,7 +983,8 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 	if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
-		rc = -EIO;	/* bad smb */
+		rc = smb_EIO2(smb_eio_trace_create_rsp_too_small,
+			      get_bcc(&pSMBr->hdr), sizeof(OPEN_PSX_RSP));
 		goto psx_create_err;
 	}
 
@@ -1372,11 +1375,12 @@ cifs_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 		break;
 	case MID_RESPONSE_MALFORMED:
 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
-		rdata->result = -EIO;
+		rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
 		break;
 	default:
 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
-		rdata->result = -EIO;
+		rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
+					 smb->mid_state);
 		break;
 	}
 
@@ -1447,7 +1451,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
 		wct = 10; /* old style read */
 		if ((rdata->subreq.start >> 32) > 0)  {
 			/* can not handle this big offset for old */
-			return -EIO;
+			return smb_EIO(smb_eio_trace_read_too_far);
 		}
 	}
 
@@ -1522,7 +1526,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
 		wct = 10; /* old style read */
 		if ((offset >> 32) > 0)  {
 			/* can not handle this big offset for old */
-			return -EIO;
+			return smb_EIO(smb_eio_trace_read_too_far);
 		}
 	}
 
@@ -1577,7 +1581,8 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
 				|| (data_length > count)) {
 			cifs_dbg(FYI, "bad length %d for count %d\n",
 				 data_length, count);
-			rc = -EIO;
+			rc = smb_EIO2(smb_eio_trace_read_overlarge,
+				      data_length, count);
 			*nbytes = 0;
 		} else {
 			pReadData = (char *) (&pSMBr->hdr.Protocol) +
@@ -1636,7 +1641,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
 		wct = 12;
 		if ((offset >> 32) > 0) {
 			/* can not handle big offset for old srv */
-			return -EIO;
+			return smb_EIO(smb_eio_trace_write_too_far);
 		}
 	}
 
@@ -1787,11 +1792,12 @@ cifs_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 		break;
 	case MID_RESPONSE_MALFORMED:
 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
-		result = -EIO;
+		result = smb_EIO(smb_eio_trace_write_rsp_malformed);
 		break;
 	default:
 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
-		result = -EIO;
+		result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
+				  smb->mid_state);
 		break;
 	}
 
@@ -1826,7 +1832,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
 		wct = 12;
 		if (wdata->subreq.start >> 32 > 0) {
 			/* can not handle big offset for old srv */
-			rc = -EIO;
+			rc = smb_EIO(smb_eio_trace_write_too_far);
 			goto out;
 		}
 	}
@@ -1918,7 +1924,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
 		wct = 12;
 		if ((offset >> 32) > 0) {
 			/* can not handle big offset for old srv */
-			return -EIO;
+			return smb_EIO(smb_eio_trace_write_too_far);
 		}
 	}
 	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
@@ -1974,7 +1980,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
 		cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
 	} else if (resp_buf_type == 0) {
 		/* presumably this can not happen, but best to be safe */
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_write_bad_buf_type, resp_buf_type);
 	} else {
 		WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
 		*nbytes = le16_to_cpu(pSMBr->CountHigh);
@@ -2210,13 +2216,15 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
-			rc = -EIO;      /* bad smb */
+			rc = smb_EIO2(smb_eio_trace_lock_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), sizeof(*parm_data));
 			goto plk_err_exit;
 		}
 		data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 		data_count  = le16_to_cpu(pSMBr->t2.DataCount);
 		if (data_count < sizeof(struct cifs_posix_lock)) {
-			rc = -EIO;
+			rc = smb_EIO2(smb_eio_trace_lock_data_too_small,
+				      data_count, sizeof(struct cifs_posix_lock));
 			goto plk_err_exit;
 		}
 		parm_data = (struct cifs_posix_lock *)
@@ -2775,7 +2783,8 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 		/* BB also check enough total bytes returned */
 		if (rc || get_bcc(&pSMBr->hdr) < 2)
-			rc = -EIO;
+			rc = smb_EIO2(smb_eio_trace_qsym_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 2);
 		else {
 			bool is_unicode;
 			u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -2877,13 +2886,15 @@ int cifs_query_reparse_point(const unsigned int xid,
 	data_count = le32_to_cpu(io_rsp->DataCount);
 	if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
 	    !data_count || data_count > 2048) {
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_qreparse_sizes_wrong,
+			      get_bcc(&io_rsp->hdr), data_count);
 		goto error;
 	}
 
 	/* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
 	if (io_rsp->SetupCount != 1) {
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_qreparse_setup_count,
+			      io_rsp->SetupCount, 1);
 		goto error;
 	}
 
@@ -2893,14 +2904,17 @@ int cifs_query_reparse_point(const unsigned int xid,
 	 * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
 	 */
 	if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_qreparse_ret_datalen,
+			      data_count, le16_to_cpu(io_rsp->ReturnedDataLen));
 		goto error;
 	}
 
 	end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
 	start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
 	if (start >= end) {
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_qreparse_data_area,
+			      (unsigned long)start - (unsigned long)io_rsp,
+			      (unsigned long)end - (unsigned long)io_rsp);
 		goto error;
 	}
 
@@ -2909,7 +2923,8 @@ int cifs_query_reparse_point(const unsigned int xid,
 	len = sizeof(*buf);
 	if (data_count < len ||
 	    data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_qreparse_rep_datalen,
+			      data_count, le16_to_cpu(buf->ReparseDataLength) + len);
 		goto error;
 	}
 
@@ -3353,7 +3368,8 @@ int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 		/* BB also check enough total bytes returned */
 		if (rc || get_bcc(&pSMBr->hdr) < 2)
-			rc = -EIO;      /* bad smb */
+			rc = smb_EIO2(smb_eio_trace_getacl_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 2);
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -3526,7 +3542,8 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
 		if (rc || get_bcc(&pSMBr->hdr) < 2)
 			/* If rc should we check for EOPNOSUPP and
 			   disable the srvino flag? or in caller? */
-			rc = -EIO;      /* bad smb */
+			rc = smb_EIO2(smb_eio_trace_getextattr_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 2);
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -3534,7 +3551,8 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
 
 			if (count != 16) {
 				cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
-				rc = -EIO;
+				rc = smb_EIO2(smb_eio_trace_getextattr_inv_size,
+					      count, 16);
 				goto GetExtAttrOut;
 			}
 			pfinfo = (struct file_chattr_info *)
@@ -3701,7 +3719,8 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
 			 pSMBr, parm, *acl_inf);
 
 		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
-			rc = -EIO;      /* bad smb */
+			rc = smb_EIO2(smb_eio_trace_getcifsacl_param_count,
+				      le32_to_cpu(pSMBr->ParameterCount), 4);
 			*pbuflen = 0;
 			goto qsec_out;
 		}
@@ -3859,8 +3878,10 @@ SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
 		data->EndOfFile = data->AllocationSize;
 		data->Attributes =
 			cpu_to_le32(le16_to_cpu(pSMBr->attr));
-	} else
-		rc = -EIO; /* bad buffer passed in */
+	} else {
+		/* bad buffer passed in */
+		rc = smb_EIO(smb_eio_trace_null_pointers);
+	}
 
 	cifs_buf_release(pSMB);
 
@@ -3922,9 +3943,11 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
-			rc = -EIO;
+			rc = smb_EIO2(smb_eio_trace_qfileinfo_invalid,
+				      get_bcc(&pSMBr->hdr), 40);
 		else if (get_bcc(&pSMBr->hdr) < 40)
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 40);
 		else if (pFindData) {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			memcpy((char *) pFindData,
@@ -4009,12 +4032,15 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc) /* BB add auto retry on EOPNOTSUPP? */
-			rc = -EIO;
+			rc = smb_EIO2(smb_eio_trace_qpathinfo_invalid,
+				      get_bcc(&pSMBr->hdr), 40);
 		else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 40);
 		else if (legacy && get_bcc(&pSMBr->hdr) < 24)
-			rc = -EIO;  /* 24 or 26 expected but we do not read
-					last field */
+			/* 24 or 26 expected but we do not read last field */
+			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 24);
 		else if (data) {
 			int size;
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4094,7 +4120,8 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
 
 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
 		} else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			memcpy((char *) pFindData,
@@ -4178,7 +4205,8 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
 
 		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
 			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
 		} else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			memcpy((char *) pFindData,
@@ -4581,7 +4609,8 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
 		if (rc || get_bcc(&pSMBr->hdr) < 2)
 			/* If rc should we check for EOPNOSUPP and
 			disable the srvino flag? or in caller? */
-			rc = -EIO;      /* bad smb */
+			rc = smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 2);
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -4589,7 +4618,8 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
 			/* BB Do we need a cast or hash here ? */
 			if (count < 8) {
 				cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
-				rc = -EIO;
+				rc = smb_EIO2(smb_eio_trace_getsrvinonum_size,
+					      count, 8);
 				goto GetInodeNumOut;
 			}
 			pfinfo = (struct file_internal_info *)
@@ -4698,7 +4728,8 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
 
 	/* BB Also check if enough total bytes returned? */
 	if (rc || get_bcc(&pSMBr->hdr) < 17) {
-		rc = -EIO;      /* bad smb */
+		rc = smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small,
+			      get_bcc(&pSMBr->hdr), 17);
 		goto GetDFSRefExit;
 	}
 
@@ -4774,7 +4805,8 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc || get_bcc(&pSMBr->hdr) < 18)
-			rc = -EIO;      /* bad smb */
+			rc = smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 18);
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
@@ -4863,7 +4895,8 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc || get_bcc(&pSMBr->hdr) < 24)
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 24);
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 
@@ -4953,7 +4986,8 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
 
 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
 			/* BB also check if enough bytes returned */
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 13);
 		} else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			response_data =
@@ -5026,7 +5060,9 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
 
 		if (rc || get_bcc(&pSMBr->hdr) <
 			  sizeof(FILE_SYSTEM_DEVICE_INFO))
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr),
+				      sizeof(FILE_SYSTEM_DEVICE_INFO));
 		else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			response_data =
@@ -5097,7 +5133,8 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 13);
 		} else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			response_data =
@@ -5245,7 +5282,8 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc || get_bcc(&pSMBr->hdr) < 13) {
-			rc = -EIO;	/* bad smb */
+			rc = smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small,
+				      get_bcc(&pSMBr->hdr), 13);
 		} else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 			response_data =
@@ -6045,7 +6083,8 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
 
 	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 	if (rc || get_bcc(&pSMBr->hdr) < 4) {
-		rc = -EIO;	/* bad smb */
+		rc = smb_EIO2(smb_eio_trace_qalleas_bcc_too_small,
+			      get_bcc(&pSMBr->hdr), 4);
 		goto QAllEAsOut;
 	}
 
@@ -6075,7 +6114,9 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
 	end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
 	if ((char *)ea_response_data + list_len > end_of_smb) {
 		cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
+			      (unsigned long)ea_response_data + list_len - (unsigned long)pSMBr,
+			      (unsigned long)end_of_smb - (unsigned long)pSMBr);
 		goto QAllEAsOut;
 	}
 
@@ -6092,7 +6133,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
 		/* make sure we can read name_len and value_len */
 		if (list_len < 0) {
 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
-			rc = -EIO;
+			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
 			goto QAllEAsOut;
 		}
 
@@ -6101,7 +6142,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
 		list_len -= name_len + 1 + value_len;
 		if (list_len < 0) {
 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
-			rc = -EIO;
+			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
 			goto QAllEAsOut;
 		}
 
diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
index 218c0fad901b..04d39b1de899 100644
--- a/fs/smb/client/cifstransport.c
+++ b/fs/smb/client/cifstransport.c
@@ -228,15 +228,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 	int rc = 0;
 
 	if (WARN_ON_ONCE(in_len > 0xffffff))
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_tx_too_long, in_len);
 	if (ses == NULL) {
 		cifs_dbg(VFS, "Null smb session\n");
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	}
 	server = ses->server;
 	if (server == NULL) {
 		cifs_dbg(VFS, "Null tcp session\n");
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	}
 
 	/* Ensure that we do not send more than 50 overlapping requests
@@ -246,7 +246,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
 	if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
 		cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
 				in_len);
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_tx_too_long, in_len);
 	}
 
 	rc = cifs_send_recv(xid, ses, ses->server,
diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c
index fb2a48f1d2ad..e0c44b46080e 100644
--- a/fs/smb/client/compress.c
+++ b/fs/smb/client/compress.c
@@ -325,7 +325,7 @@ int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_s
 	iter = rq->rq_iter;
 
 	if (!copy_from_iter_full(src, slen, &iter)) {
-		ret = -EIO;
+		ret = smb_EIO(smb_eio_trace_compress_copy);
 		goto err_free;
 	}
 
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 7a1112fae6ee..13426c2d3fad 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -3241,7 +3241,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
 		if (be16_to_cpu(resp.length) != 0) {
 			cifs_dbg(VFS, "RFC 1002 positive session response but with invalid non-zero length %u\n",
 				 be16_to_cpu(resp.length));
-			return -EIO;
+			return smb_EIO(smb_eio_trace_rx_pos_sess_resp);
 		}
 		cifs_dbg(FYI, "RFC 1002 positive session response");
 		break;
@@ -3280,17 +3280,18 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
 				break;
 			case RFC1002_INSUFFICIENT_RESOURCE:
 				/* remote server resource error */
+				smb_EIO(smb_eio_trace_rx_insuff_res);
 				rc = -EREMOTEIO;
 				break;
 			case RFC1002_UNSPECIFIED_ERROR:
 			default:
 				/* other/unknown error */
-				rc = -EIO;
+				rc = smb_EIO(smb_eio_trace_rx_unspec_error);
 				break;
 			}
 		} else {
 			cifs_dbg(VFS, "RFC 1002 negative session response\n");
-			rc = -EIO;
+			rc = smb_EIO(smb_eio_trace_rx_neg_sess_resp);
 		}
 		return rc;
 	case RFC1002_RETARGET_SESSION_RESPONSE:
@@ -3312,7 +3313,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
 		return -EMULTIHOP;
 	default:
 		cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", resp.type);
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_rx_unknown_resp, resp.type);
 	}
 
 	server->with_rfc1001 = true;
@@ -4002,7 +4003,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
 	__u16 bytes_left, count;
 
 	if (ses == NULL)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	smb_buffer = cifs_buf_get();
 	if (smb_buffer == NULL)
diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
index 2cf0c4f1746d..9a45578741fa 100644
--- a/fs/smb/client/dir.c
+++ b/fs/smb/client/dir.c
@@ -472,7 +472,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
 	struct cifs_open_info_data buf = {};
 
 	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	/*
 	 * Posix open is only called (at lookup time) for file create now. For
@@ -590,7 +590,7 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *inode,
 		 inode, direntry, direntry);
 
 	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_forced_shutdown);
 		goto out_free_xid;
 	}
 
@@ -632,7 +632,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode,
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 0939b91c5acc..f4b625ea2abe 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -118,7 +118,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
 	int rc;
 
 	if (cifs_forced_shutdown(sbi)) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_forced_shutdown);
 		goto fail;
 	}
 
@@ -286,7 +286,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file)
 			req->pid = req->cfile->pid;
 	} else if (rreq->origin != NETFS_WRITEBACK) {
 		WARN_ON_ONCE(1);
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_not_netfs_writeback, rreq->origin);
 	}
 
 	return 0;
@@ -1036,7 +1036,7 @@ int cifs_open(struct inode *inode, struct file *file)
 	cifs_sb = CIFS_SB(inode->i_sb);
 	if (unlikely(cifs_forced_shutdown(cifs_sb))) {
 		free_xid(xid);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 	}
 
 	tlink = cifs_sb_tlink(cifs_sb);
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index a6489517495d..d94203dc5131 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -1952,7 +1952,7 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
 	cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry);
 
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	/* Unhash dentry in advance to prevent any concurrent opens */
 	spin_lock(&dentry->d_lock);
@@ -2268,7 +2268,7 @@ struct dentry *cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return ERR_PTR(-EIO);
+		return ERR_PTR(smb_EIO(smb_eio_trace_forced_shutdown));
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
 		return ERR_CAST(tlink);
@@ -2354,7 +2354,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	if (unlikely(cifs_forced_shutdown(cifs_sb))) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_forced_shutdown);
 		goto rmdir_exit;
 	}
 
@@ -2516,7 +2516,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
 
 	cifs_sb = CIFS_SB(source_dir->i_sb);
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	/*
 	 * Prevent any concurrent opens on the target by unhashing the dentry.
@@ -2901,7 +2901,7 @@ int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,
 	int rc;
 
 	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	/*
 	 * We need to be sure that all dirty pages are written and the server
@@ -2976,7 +2976,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start,
 	int rc;
 
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	/*
 	 * We need to be sure that all dirty pages are written as they
@@ -3468,7 +3468,7 @@ cifs_setattr(struct mnt_idmap *idmap, struct dentry *direntry,
 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 	/*
 	 * Avoid setting [cm]time with O_TRUNC to prevent the server from
 	 * disabling automatic timestamp updates as specified in
diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
index d92eb14b97dd..a6e5a3d93077 100644
--- a/fs/smb/client/link.c
+++ b/fs/smb/client/link.c
@@ -161,7 +161,8 @@ create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 		goto out;
 
 	if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_symlink_file_size,
+			      bytes_written, CIFS_MF_SYMLINK_FILE_SIZE);
 out:
 	kfree(buf);
 	return rc;
@@ -425,7 +426,8 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
 
 	/* Make sure we wrote all of the symlink data */
 	if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_short_symlink_write,
+			      *pbytes_written, CIFS_MF_SYMLINK_FILE_SIZE);
 
 	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 
@@ -452,7 +454,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
 	struct cifsInodeInfo *cifsInode;
 
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	tlink = cifs_sb_tlink(cifs_sb);
 	if (IS_ERR(tlink))
@@ -554,7 +556,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
 	struct inode *newinode = NULL;
 
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	page = alloc_dentry_path();
 	if (!page)
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
index 6e59c79dbbc6..9529fa385938 100644
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -380,25 +380,29 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
 				return 0;
 			}
 			cifs_dbg(VFS, "rcvd invalid byte count (bcc)\n");
+			return smb_EIO1(smb_eio_trace_rx_inv_bcc, tmp[sizeof(struct smb_hdr)]);
 		} else {
 			cifs_dbg(VFS, "Length less than smb header size\n");
+			return smb_EIO2(smb_eio_trace_rx_too_short,
+					total_read, smb->WordCount);
 		}
-		return -EIO;
 	} else if (total_read < sizeof(*smb) + 2 * smb->WordCount) {
 		cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n",
 			 __func__, smb->WordCount);
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_rx_check_rsp,
+				total_read, 2 + sizeof(struct smb_hdr));
 	}
 
 	/* otherwise, there is enough to get to the BCC */
 	if (check_smb_hdr(smb))
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_rx_rfc1002_magic, *(u32 *)smb->Protocol);
 	clc_len = smbCalcSize(smb);
 
 	if (rfclen != total_read) {
 		cifs_dbg(VFS, "Length read does not match RFC1001 length %d/%d\n",
 			 rfclen, total_read);
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_rx_check_rsp,
+				total_read, rfclen);
 	}
 
 	if (rfclen != clc_len) {
@@ -415,7 +419,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
 		if (rfclen < clc_len) {
 			cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n",
 				 rfclen, mid);
-			return -EIO;
+			return smb_EIO2(smb_eio_trace_rx_calc_len_too_big,
+					rfclen, clc_len);
 		} else if (rfclen > clc_len + 512) {
 			/*
 			 * Some servers (Windows XP in particular) send more
@@ -428,7 +433,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
 			 */
 			cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for mid=%u\n",
 				 rfclen, mid);
-			return -EIO;
+			return smb_EIO2(smb_eio_trace_rx_overlong,
+					rfclen, clc_len + 512);
 		}
 	}
 	return 0;
diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
index 7ad5a3cc05d1..4a98b71288d6 100644
--- a/fs/smb/client/netmisc.c
+++ b/fs/smb/client/netmisc.c
@@ -885,6 +885,10 @@ map_smb_to_linux_error(char *buf, bool logErr)
 	/* generic corrective action e.g. reconnect SMB session on
 	 * ERRbaduid could be added */
 
+	if (rc == -EIO)
+		smb_EIO2(smb_eio_trace_smb1_received_error,
+			 le32_to_cpu(smb->Status.CifsError),
+			 le16_to_cpu(smb->Flags2));
 	return rc;
 }
 
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index 7ff728503ed1..6844f1dc3921 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -775,7 +775,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
 
 		if (cfile->srch_inf.ntwrk_buf_start == NULL) {
 			cifs_dbg(VFS, "ntwrk_buf_start is NULL during readdir\n");
-			return -EIO;
+			return smb_EIO(smb_eio_trace_null_pointers);
 		}
 
 		end_of_smb = cfile->srch_inf.ntwrk_buf_start +
diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
index 10c84c095fe7..ce9b923498b5 100644
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -732,7 +732,8 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
 	len = le16_to_cpu(buf->ReparseDataLength);
 	if (len < sizeof(buf->InodeType)) {
 		cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_reparse_nfs_too_short,
+				len, sizeof(buf->InodeType));
 	}
 
 	len -= sizeof(buf->InodeType);
@@ -741,7 +742,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
 	case NFS_SPECFILE_LNK:
 		if (len == 0 || (len % 2)) {
 			cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
-			return -EIO;
+			return smb_EIO1(smb_eio_trace_reparse_nfs_symbuf, len);
 		}
 		/*
 		 * Check that buffer does not contain UTF-16 null codepoint
@@ -749,7 +750,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
 		 */
 		if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
 			cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
-			return -EIO;
+			return smb_EIO1(smb_eio_trace_reparse_nfs_nul, len);
 		}
 		data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
 							       len, true,
@@ -764,7 +765,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
 		/* DataBuffer for block and char devices contains two 32-bit numbers */
 		if (len != 8) {
 			cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
-			return -EIO;
+			return smb_EIO1(smb_eio_trace_reparse_nfs_dev, len);
 		}
 		break;
 	case NFS_SPECFILE_FIFO:
@@ -772,7 +773,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
 		/* DataBuffer for fifos and sockets is empty */
 		if (len != 0) {
 			cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
-			return -EIO;
+			return smb_EIO1(smb_eio_trace_reparse_nfs_sockfifo, len);
 		}
 		break;
 	default:
@@ -796,13 +797,13 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
 	int abs_path_len;
 	char *abs_path;
 	int levels;
-	int rc;
+	int rc, ulen;
 	int i;
 
 	/* Check that length it valid */
 	if (!len || (len % 2)) {
 		cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_reparse_native_nul, len);
 		goto out;
 	}
 
@@ -810,9 +811,10 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
 	 * Check that buffer does not contain UTF-16 null codepoint
 	 * because Linux cannot process symlink with null byte.
 	 */
-	if (UniStrnlen((wchar_t *)buf, len/2) != len/2) {
+	ulen = UniStrnlen((wchar_t *)buf, len/2);
+	if (ulen != len/2) {
 		cifs_dbg(VFS, "srv returned null byte in native symlink target location\n");
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_reparse_native_nul, ulen, len);
 		goto out;
 	}
 
@@ -996,7 +998,8 @@ static int parse_reparse_native_symlink(struct reparse_symlink_data_buffer *sym,
 	len = le16_to_cpu(sym->SubstituteNameLength);
 	if (offs + 20 > plen || offs + len + 20 > plen) {
 		cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_reparse_native_sym_len,
+				offs << 16 | len, plen);
 	}
 
 	return smb2_parse_native_symlink(&data->symlink_target,
@@ -1019,13 +1022,16 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
 
 	if (len <= data_offset) {
 		cifs_dbg(VFS, "srv returned malformed wsl symlink buffer\n");
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_reparse_wsl_symbuf,
+				len, data_offset);
 	}
 
 	/* MS-FSCC 2.1.2.7 defines layout of the Target field only for Version 2. */
-	if (le32_to_cpu(buf->Version) != 2) {
-		cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", le32_to_cpu(buf->Version));
-		return -EIO;
+	u32 version = le32_to_cpu(buf->Version);
+
+	if (version != 2) {
+		cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", version);
+		return smb_EIO1(smb_eio_trace_reparse_wsl_ver, version);
 	}
 
 	/* Target for Version 2 is in UTF-8 but without trailing null-term byte */
@@ -1034,9 +1040,12 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
 	 * Check that buffer does not contain null byte
 	 * because Linux cannot process symlink with null byte.
 	 */
-	if (strnlen(buf->Target, symname_utf8_len) != symname_utf8_len) {
+	size_t ulen = strnlen(buf->Target, symname_utf8_len);
+
+	if (ulen != symname_utf8_len) {
 		cifs_dbg(VFS, "srv returned null byte in wsl symlink target location\n");
-		return -EIO;
+		return smb_EIO2(smb_eio_trace_reparse_wsl_ver,
+				ulen, symname_utf8_len);
 	}
 	symname_utf16 = kzalloc(symname_utf8_len * 2, GFP_KERNEL);
 	if (!symname_utf16)
@@ -1083,13 +1092,17 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
 	case IO_REPARSE_TAG_AF_UNIX:
 	case IO_REPARSE_TAG_LX_FIFO:
 	case IO_REPARSE_TAG_LX_CHR:
-	case IO_REPARSE_TAG_LX_BLK:
-		if (le16_to_cpu(buf->ReparseDataLength) != 0) {
+	case IO_REPARSE_TAG_LX_BLK: {
+		u16 dlen = le16_to_cpu(buf->ReparseDataLength);
+
+		if (dlen != 0) {
+			u32 rtag = le32_to_cpu(buf->ReparseTag);
 			cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\n",
-				 le32_to_cpu(buf->ReparseTag));
-			return -EIO;
+				 rtag);
+			return smb_EIO2(smb_eio_trace_reparse_data_len, dlen, rtag);
 		}
 		return 0;
+	}
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
index 4cec7d7b6d9c..ffbdb38f00c4 100644
--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -1504,7 +1504,7 @@ sess_auth_ntlmv2(struct sess_data *sess_data)
 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 
 	if (smb_buf->WordCount != 3) {
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_sess_nl2_wcc, smb_buf->WordCount);
 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 		goto out;
 	}
@@ -1630,7 +1630,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 
 	if (smb_buf->WordCount != 4) {
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_sess_krb_wcc, smb_buf->WordCount);
 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 		goto out_put_spnego_key;
 	}
@@ -1791,7 +1791,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
 	cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
 
 	if (smb_buf->WordCount != 4) {
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_sess_rawnl_neg_wcc, smb_buf->WordCount);
 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 		goto out_free_ntlmsspblob;
 	}
@@ -1881,7 +1881,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 	if (smb_buf->WordCount != 4) {
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_sess_rawnl_auth_wcc, smb_buf->WordCount);
 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 		goto out_free_ntlmsspblob;
 	}
diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
index 66e5d6f9e3b7..7f11ae6bb785 100644
--- a/fs/smb/client/smb2file.c
+++ b/fs/smb/client/smb2file.c
@@ -76,11 +76,11 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
 		return 0;
 
 	if (!*target)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	len = strlen(*target);
 	if (!len)
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_sym_target_len, len);
 
 	/*
 	 * If this is directory symlink and it does not have trailing slash then
@@ -104,7 +104,7 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
 	 * both Windows and Linux systems. So return an error for such symlink.
 	 */
 	if (!directory && (*target)[len-1] == '/')
-		return -EIO;
+		return smb_EIO(smb_eio_trace_sym_slash);
 
 	return 0;
 }
diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
index 8f86c05d0036..2ded3246600c 100644
--- a/fs/smb/client/smb2inode.c
+++ b/fs/smb/client/smb2inode.c
@@ -30,16 +30,20 @@ static struct reparse_data_buffer *reparse_buf_ptr(struct kvec *iov)
 	struct reparse_data_buffer *buf;
 	struct smb2_ioctl_rsp *io = iov->iov_base;
 	u32 off, count, len;
+	u16 rdlen;
 
 	count = le32_to_cpu(io->OutputCount);
 	off = le32_to_cpu(io->OutputOffset);
 	if (check_add_overflow(off, count, &len) || len > iov->iov_len)
-		return ERR_PTR(-EIO);
+		return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_overlong,
+					off, count));
 
 	buf = (struct reparse_data_buffer *)((u8 *)io + off);
 	len = sizeof(*buf);
-	if (count < len || count < le16_to_cpu(buf->ReparseDataLength) + len)
-		return ERR_PTR(-EIO);
+	rdlen = le16_to_cpu(buf->ReparseDataLength);
+
+	if (count < len || count < rdlen + len)
+		return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_rdlen, count, rdlen));
 	return buf;
 }
 
@@ -1634,7 +1638,7 @@ int smb2_rename_pending_delete(const char *full_path,
 	} else {
 		cifs_tcon_dbg(FYI, "%s: failed to rename '%s' to '%s': %d\n",
 			      __func__, full_path, to_name, rc);
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_pend_del_fail, rc);
 	}
 out:
 	cifs_put_tlink(tlink);
diff --git a/fs/smb/client/smb2maperror.c b/fs/smb/client/smb2maperror.c
index 29cf456dade9..4fc22456c39e 100644
--- a/fs/smb/client/smb2maperror.c
+++ b/fs/smb/client/smb2maperror.c
@@ -9,6 +9,7 @@
  */
 #include <linux/errno.h>
 #include "cifsglob.h"
+#include "cifsproto.h"
 #include "cifs_debug.h"
 #include "smb2proto.h"
 #include "smb2glob.h"
@@ -2476,5 +2477,7 @@ map_smb2_to_linux_error(char *buf, bool log_err)
 			   le16_to_cpu(shdr->Command),
 			   le64_to_cpu(shdr->MessageId),
 			   le32_to_cpu(smb2err), rc);
+	if (rc == -EIO)
+		smb_EIO1(smb_eio_trace_smb2_received_error, le32_to_cpu(smb2err));
 	return rc;
 }
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 0bc2e4cc2617..7cec987218e9 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -1046,7 +1046,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
 
 		if (src_size < 8 + name_len + 1 + value_len) {
 			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
-			rc = -EIO;
+			rc = smb_EIO2(smb_eio_trace_ea_overrun,
+				      src_size, 8 + name_len + 1 + value_len);
 			goto out;
 		}
 
@@ -1607,7 +1608,7 @@ smb2_ioctl_query_info(const unsigned int xid,
 	}
 
 	if (!ses || !server) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_null_pointers);
 		goto free_vars;
 	}
 
@@ -1942,7 +1943,7 @@ smb2_copychunk_range(const unsigned int xid,
 		if (unlikely(ret_data_len != sizeof(*cc_rsp))) {
 			cifs_tcon_dbg(VFS, "Copychunk invalid response: size %u/%zu\n",
 				      ret_data_len, sizeof(*cc_rsp));
-			rc = -EIO;
+			rc = smb_EIO1(smb_eio_trace_copychunk_inv_rsp, ret_data_len);
 			goto out;
 		}
 
@@ -1952,11 +1953,18 @@ smb2_copychunk_range(const unsigned int xid,
 
 		if (rc == 0) {
 			/* Check if server claimed to write more than we asked */
-			if (unlikely(!bytes_written || bytes_written > copy_bytes ||
-				     !chunks_written || chunks_written > chunks)) {
-				cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u, chunks written %u/%u\n",
-					      bytes_written, copy_bytes, chunks_written, chunks);
-				rc = -EIO;
+			if (unlikely(!bytes_written || bytes_written > copy_bytes)) {
+				cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u\n",
+					      bytes_written, copy_bytes);
+				rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_b,
+					      bytes_written, copy_bytes);
+				goto out;
+			}
+			if (unlikely(!chunks_written || chunks_written > chunks)) {
+				cifs_tcon_dbg(VFS, "Copychunk invalid response: chunks written %u/%u\n",
+					      chunks_written, chunks);
+				rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_c,
+					      chunks_written, chunks);
 				goto out;
 			}
 
@@ -3127,7 +3135,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
 	}
 
 	if (!rc && !dfs_rsp)
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_dfsref_no_rsp);
 	if (rc) {
 		if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP)
 			cifs_tcon_dbg(FYI, "%s: ioctl error: rc=%d\n", __func__, rc);
@@ -4556,7 +4564,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
 					     buffer, 0, 0, size);
 
 			if (!cifs_copy_iter_to_folioq(&old->rq_iter, size, buffer)) {
-				rc = -EIO;
+				rc = smb_EIO1(smb_eio_trace_tx_copy_iter_to_buf, size);
 				goto err_free;
 			}
 		}
@@ -4657,7 +4665,8 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size,
 			n = copy_folio_to_iter(folio, skip, len, iter);
 			if (n != len) {
 				cifs_dbg(VFS, "%s: something went wrong\n", __func__);
-				return -EIO;
+				return smb_EIO2(smb_eio_trace_rx_copy_to_iter,
+						n, len);
 			}
 			data_size -= n;
 			skip = 0;
@@ -4740,7 +4749,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 		/* data_offset is beyond the end of smallbuf */
 		cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
 			 __func__, data_offset);
-		rdata->result = -EIO;
+		rdata->result = smb_EIO1(smb_eio_trace_rx_overlong, data_offset);
 		if (is_offloaded)
 			smb->mid_state = MID_RESPONSE_MALFORMED;
 		else
@@ -4759,7 +4768,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 			/* data offset is beyond the 1st page of response */
 			cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n",
 				 __func__, data_offset);
-			rdata->result = -EIO;
+			rdata->result = smb_EIO1(smb_eio_trace_rx_overpage, data_offset);
 			if (is_offloaded)
 				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
@@ -4769,7 +4778,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 
 		if (data_len > buffer_len - pad_len) {
 			/* data_len is corrupt -- discard frame */
-			rdata->result = -EIO;
+			rdata->result = smb_EIO1(smb_eio_trace_rx_bad_datalen, data_len);
 			if (is_offloaded)
 				smb->mid_state = MID_RESPONSE_MALFORMED;
 			else
@@ -4794,12 +4803,12 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
 		WARN_ONCE(buffer, "read data can be either in buf or in buffer");
 		copied = copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_iter);
 		if (copied == 0)
-			return -EIO;
+			return smb_EIO2(smb_eio_trace_rx_copy_to_iter, copied, data_len);
 		rdata->got_bytes = copied;
 	} else {
 		/* read response payload cannot be in both buf and pages */
 		WARN_ONCE(1, "buf can not contain only a part of read data");
-		rdata->result = -EIO;
+		rdata->result = smb_EIO(smb_eio_trace_rx_both_buf);
 		if (is_offloaded)
 			smb->mid_state = MID_RESPONSE_MALFORMED;
 		else
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 9c21521061a9..ce56237928a0 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -249,15 +249,15 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
 
 	ses = tcon->ses;
 	if (!ses)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	spin_lock(&ses->ses_lock);
 	if (ses->ses_status == SES_EXITING) {
 		spin_unlock(&ses->ses_lock);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_sess_exiting);
 	}
 	spin_unlock(&ses->ses_lock);
 	if (!ses->server || !server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	spin_lock(&server->srv_lock);
 	if (server->tcpStatus == CifsNeedReconnect) {
@@ -1061,7 +1061,7 @@ SMB2_negotiate(const unsigned int xid,
 
 	if (!server) {
 		WARN(1, "%s: server is NULL!\n", __func__);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	}
 
 	rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server,
@@ -1142,64 +1142,84 @@ SMB2_negotiate(const unsigned int xid,
 	} else if (rc != 0)
 		goto neg_exit;
 
-	rc = -EIO;
+	u16 dialect = le16_to_cpu(rsp->DialectRevision);
 	if (strcmp(server->vals->version_string,
 		   SMB3ANY_VERSION_STRING) == 0) {
-		if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
+		switch (dialect) {
+		case SMB20_PROT_ID:
 			cifs_server_dbg(VFS,
 				"SMB2 dialect returned but not requested\n");
+			rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3);
 			goto neg_exit;
-		} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
+		case SMB21_PROT_ID:
 			cifs_server_dbg(VFS,
 				"SMB2.1 dialect returned but not requested\n");
+			rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3);
 			goto neg_exit;
-		} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
+		case SMB311_PROT_ID:
 			/* ops set to 3.0 by default for default so update */
 			server->ops = &smb311_operations;
 			server->vals = &smb311_values;
+			break;
+		default:
+			break;
 		}
 	} else if (strcmp(server->vals->version_string,
-		   SMBDEFAULT_VERSION_STRING) == 0) {
-		if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
+			  SMBDEFAULT_VERSION_STRING) == 0) {
+		switch (dialect) {
+		case SMB20_PROT_ID:
 			cifs_server_dbg(VFS,
 				"SMB2 dialect returned but not requested\n");
+			rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 0);
 			goto neg_exit;
-		} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
+		case SMB21_PROT_ID:
 			/* ops set to 3.0 by default for default so update */
 			server->ops = &smb21_operations;
 			server->vals = &smb21_values;
-		} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
+			break;
+		case SMB311_PROT_ID:
 			server->ops = &smb311_operations;
 			server->vals = &smb311_values;
+			break;
+		default:
+			break;
 		}
-	} else if (le16_to_cpu(rsp->DialectRevision) !=
-				server->vals->protocol_id) {
+	} else if (dialect != server->vals->protocol_id) {
 		/* if requested single dialect ensure returned dialect matched */
 		cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n",
-				le16_to_cpu(rsp->DialectRevision));
+				dialect);
+		rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect,
+			      dialect, server->vals->protocol_id);
 		goto neg_exit;
 	}
 
 	cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
 
-	if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID))
+	switch (dialect) {
+	case SMB20_PROT_ID:
 		cifs_dbg(FYI, "negotiated smb2.0 dialect\n");
-	else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID))
+		break;
+	case SMB21_PROT_ID:
 		cifs_dbg(FYI, "negotiated smb2.1 dialect\n");
-	else if (rsp->DialectRevision == cpu_to_le16(SMB30_PROT_ID))
+		break;
+	case SMB30_PROT_ID:
 		cifs_dbg(FYI, "negotiated smb3.0 dialect\n");
-	else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID))
+		break;
+	case SMB302_PROT_ID:
 		cifs_dbg(FYI, "negotiated smb3.02 dialect\n");
-	else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
+		break;
+	case SMB311_PROT_ID:
 		cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n");
-	else {
+		break;
+	default:
 		cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n",
-				le16_to_cpu(rsp->DialectRevision));
+				dialect);
+		rc = smb_EIO1(smb_eio_trace_neg_inval_dialect, dialect);
 		goto neg_exit;
 	}
 
 	rc = 0;
-	server->dialect = le16_to_cpu(rsp->DialectRevision);
+	server->dialect = dialect;
 
 	/*
 	 * Keep a copy of the hash after negprot. This hash will be
@@ -1255,10 +1275,10 @@ SMB2_negotiate(const unsigned int xid,
 		if (rc == 1)
 			rc = 0;
 		else if (rc == 0)
-			rc = -EIO;
+			rc = smb_EIO1(smb_eio_trace_neg_decode_token, rc);
 	}
 
-	if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
+	if (server->dialect == SMB311_PROT_ID) {
 		if (rsp->NegotiateContextCount)
 			rc = smb311_decode_neg_context(rsp, server,
 						       rsp_iov.iov_len);
@@ -1371,32 +1391,47 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
 	} else if (rc != 0) {
 		cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n",
 			      rc);
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_neg_info_fail, rc);
 		goto out_free_inbuf;
 	}
 
-	rc = -EIO;
 	if (rsplen != sizeof(*pneg_rsp)) {
 		cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n",
 			      rsplen);
 
 		/* relax check since Mac returns max bufsize allowed on ioctl */
-		if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp))
+		if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) {
+			rc = smb_EIO1(smb_eio_trace_neg_bad_rsplen, rsplen);
 			goto out_free_rsp;
+		}
 	}
 
 	/* check validate negotiate info response matches what we got earlier */
-	if (pneg_rsp->Dialect != cpu_to_le16(server->dialect))
+	u16 dialect = le16_to_cpu(pneg_rsp->Dialect);
+
+	if (dialect != server->dialect) {
+		rc = smb_EIO2(smb_eio_trace_neg_info_dialect,
+			      dialect, server->dialect);
 		goto vneg_out;
+	}
 
-	if (pneg_rsp->SecurityMode != cpu_to_le16(server->sec_mode))
+	u16 sec_mode = le16_to_cpu(pneg_rsp->SecurityMode);
+
+	if (sec_mode != server->sec_mode) {
+		rc = smb_EIO2(smb_eio_trace_neg_info_sec_mode,
+			      sec_mode, server->sec_mode);
 		goto vneg_out;
+	}
 
 	/* do not validate server guid because not saved at negprot time yet */
+	u32 caps = le32_to_cpu(pneg_rsp->Capabilities);
 
-	if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
-	      SMB2_LARGE_FILES) != server->capabilities)
+	if ((caps | SMB2_NT_FIND |
+	     SMB2_LARGE_FILES) != server->capabilities) {
+		rc = smb_EIO2(smb_eio_trace_neg_info_caps,
+			      caps, server->capabilities);
 		goto vneg_out;
+	}
 
 	/* validate negotiate successful */
 	rc = 0;
@@ -1758,11 +1793,11 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
 	if (rc)
 		goto out;
 
-	if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=
-			le16_to_cpu(rsp->SecurityBufferOffset)) {
-		cifs_dbg(VFS, "Invalid security buffer offset %d\n",
-			le16_to_cpu(rsp->SecurityBufferOffset));
-		rc = -EIO;
+	u16 boff = le16_to_cpu(rsp->SecurityBufferOffset);
+
+	if (offsetof(struct smb2_sess_setup_rsp, Buffer) != boff) {
+		cifs_dbg(VFS, "Invalid security buffer offset %d\n", boff);
+		rc = smb_EIO1(smb_eio_trace_sess_buf_off, boff);
 		goto out;
 	}
 	rc = decode_ntlmssp_challenge(rsp->Buffer,
@@ -1916,7 +1951,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
 
 	if (!server) {
 		WARN(1, "%s: server is NULL!\n", __func__);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	}
 
 	sess_data = kzalloc(sizeof(struct SMB2_sess_data), GFP_KERNEL);
@@ -1966,10 +2001,9 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
 
 	cifs_dbg(FYI, "disconnect session %p\n", ses);
 
-	if (ses && (ses->server))
-		server = ses->server;
-	else
-		return -EIO;
+	if (!ses || !ses->server)
+		return smb_EIO(smb_eio_trace_null_pointers);
+	server = ses->server;
 
 	/* no need to send SMB logoff if uid already closed due to reconnect */
 	spin_lock(&ses->chan_lock);
@@ -2048,7 +2082,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
 	cifs_dbg(FYI, "TCON\n");
 
 	if (!server || !tree)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
 	if (unc_path == NULL)
@@ -2186,7 +2220,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
 	cifs_dbg(FYI, "Tree Disconnect\n");
 
 	if (!ses || !(ses->server))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	trace_smb3_tdis_enter(xid, tcon->tid, ses->Suid, tcon->tree_name);
 	spin_lock(&ses->chan_lock);
@@ -2856,7 +2890,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 		return -ENOMEM;
 
 	if (!ses || !server) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_null_pointers);
 		goto err_free_path;
 	}
 
@@ -2973,7 +3007,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 	 */
 	rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
 	if (rsp == NULL) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_mkdir_no_rsp);
 		kfree(pc_buf);
 		goto err_free_req;
 	}
@@ -3211,7 +3245,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
 
 	cifs_dbg(FYI, "create/open\n");
 	if (!ses || !server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -3417,11 +3451,11 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 	int retries = 0, cur_sleep = 1;
 
 	if (!tcon)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	ses = tcon->ses;
 	if (!ses)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 replay_again:
 	/* reinitialize for possible replay */
@@ -3429,7 +3463,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 	server = cifs_pick_channel(ses);
 
 	if (!server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	cifs_dbg(FYI, "SMB2 IOCTL\n");
 
@@ -3492,7 +3526,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 	 * warning)
 	 */
 	if (rsp == NULL) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_ioctl_no_rsp);
 		goto ioctl_exit;
 	}
 
@@ -3503,16 +3537,18 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 		goto ioctl_exit; /* server returned no data */
 	else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) {
 		cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
+		rc = smb_EIO2(smb_eio_trace_ioctl_data_len, *plen, rsp_iov.iov_len);
 		*plen = 0;
-		rc = -EIO;
 		goto ioctl_exit;
 	}
 
-	if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) {
-		cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
-			le32_to_cpu(rsp->OutputOffset));
+	u32 outoff = le32_to_cpu(rsp->OutputOffset);
+
+	if (rsp_iov.iov_len - *plen < outoff) {
+		cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n",
+			      *plen, outoff);
+		rc = smb_EIO2(smb_eio_trace_ioctl_out_off, rsp_iov.iov_len - *plen, outoff);
 		*plen = 0;
-		rc = -EIO;
 		goto ioctl_exit;
 	}
 
@@ -3620,7 +3656,7 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
 	cifs_dbg(FYI, "Close\n");
 
 	if (!ses || !server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -3817,7 +3853,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
 	cifs_dbg(FYI, "Query Info\n");
 
 	if (!ses)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 replay_again:
 	/* reinitialize for possible replay */
@@ -3826,7 +3862,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
 	server = cifs_pick_channel(ses);
 
 	if (!server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -4012,7 +4048,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
 
 	cifs_dbg(FYI, "change notify\n");
 	if (!ses || !server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -4348,7 +4384,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
 
 	cifs_dbg(FYI, "flush\n");
 	if (!ses || !(ses->server))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -4583,11 +4619,12 @@ smb2_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
 		credits.value = le16_to_cpu(shdr->CreditRequest);
 		credits.instance = server->reconnect_instance;
-		rdata->result = -EIO;
+		rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
 		break;
 	default:
 		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
-		rdata->result = -EIO;
+		rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
+					 smb->mid_state);
 		break;
 	}
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -4796,7 +4833,8 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
 	    (*nbytes > io_parms->length)) {
 		cifs_dbg(FYI, "bad length %d for count %d\n",
 			 *nbytes, io_parms->length);
-		rc = -EIO;
+		rc = smb_EIO2(smb_eio_trace_read_overlarge,
+			      *nbytes, io_parms->length);
 		*nbytes = 0;
 	}
 
@@ -4882,11 +4920,12 @@ smb2_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
 		credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
 		credits.instance = server->reconnect_instance;
-		result = -EIO;
+		result = smb_EIO(smb_eio_trace_write_rsp_malformed);
 		break;
 	default:
 		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
-		result = -EIO;
+		result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
+				  smb->mid_state);
 		break;
 	}
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -5529,7 +5568,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
 	server = cifs_pick_channel(ses);
 
 	if (!ses || !(ses->server))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -5664,7 +5703,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
 	server = cifs_pick_channel(ses);
 
 	if (!ses || !server)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	if (!num)
 		return -EINVAL;
@@ -5861,7 +5900,7 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
 	cifs_dbg(FYI, "Query FSInfo level %d\n", level);
 
 	if ((tcon->ses == NULL) || server == NULL)
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 
 	rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
 				 (void **) &req, &total_len);
diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
index 47eab3753c9e..b5bd450d30a8 100644
--- a/fs/smb/client/smb2transport.c
+++ b/fs/smb/client/smb2transport.c
@@ -153,7 +153,7 @@ static int smb2_get_sign_key(struct TCP_Server_Info *server,
 				memcpy(key, ses->auth_key.response,
 				       SMB2_NTLMV2_SESSKEY_SIZE);
 			} else {
-				rc = -EIO;
+				rc = smb_EIO(smb_eio_trace_no_auth_key);
 			}
 			break;
 		default:
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
index c6c428c2e08d..1c2fc560b2de 100644
--- a/fs/smb/client/smbdirect.c
+++ b/fs/smb/client/smbdirect.c
@@ -979,7 +979,7 @@ static int smbd_post_send_negotiate_req(struct smbdirect_socket *sc)
 				sc->ib.dev, (void *)packet,
 				sizeof(*packet), DMA_TO_DEVICE);
 	if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_rdma_dma_map);
 		goto dma_mapping_failed;
 	}
 
@@ -1179,7 +1179,7 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
 						 header_length,
 						 DMA_TO_DEVICE);
 	if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_rdma_dma_map);
 		goto err_dma;
 	}
 
@@ -1321,13 +1321,13 @@ static int smbd_post_recv(
 {
 	struct smbdirect_socket_parameters *sp = &sc->parameters;
 	struct ib_recv_wr recv_wr;
-	int rc = -EIO;
+	int rc;
 
 	response->sge.addr = ib_dma_map_single(
 				sc->ib.dev, response->packet,
 				sp->max_recv_size, DMA_FROM_DEVICE);
 	if (ib_dma_mapping_error(sc->ib.dev, response->sge.addr))
-		return rc;
+		return smb_EIO(smb_eio_trace_rdma_dma_map);
 
 	response->sge.length = sp->max_recv_size;
 	response->sge.lkey = sc->ib.pd->local_dma_lkey;
@@ -2855,7 +2855,7 @@ static ssize_t smb_extract_bvec_to_rdma(struct iov_iter *iter,
 		off = bv[i].bv_offset + start;
 
 		if (!smb_set_sge(rdma, bv[i].bv_page, off, len))
-			return -EIO;
+			return smb_EIO(smb_eio_trace_rdma_set_sge);
 
 		ret += len;
 		maxsize -= len;
@@ -2909,7 +2909,7 @@ static ssize_t smb_extract_kvec_to_rdma(struct iov_iter *iter,
 				page = virt_to_page((void *)kaddr);
 
 			if (!smb_set_sge(rdma, page, off, seg))
-				return -EIO;
+				return smb_EIO(smb_eio_trace_rdma_set_sge);
 
 			ret += seg;
 			len -= seg;
@@ -2945,7 +2945,7 @@ static ssize_t smb_extract_folioq_to_rdma(struct iov_iter *iter,
 	if (slot >= folioq_nr_slots(folioq)) {
 		folioq = folioq->next;
 		if (WARN_ON_ONCE(!folioq))
-			return -EIO;
+			return smb_EIO(smb_eio_trace_rdma_fq_overrun);
 		slot = 0;
 	}
 
@@ -2957,7 +2957,7 @@ static ssize_t smb_extract_folioq_to_rdma(struct iov_iter *iter,
 			size_t part = umin(maxsize, fsize - offset);
 
 			if (!smb_set_sge(rdma, folio_page(folio, 0), offset, part))
-				return -EIO;
+				return smb_EIO(smb_eio_trace_rdma_set_sge);
 
 			offset += part;
 			ret += part;
@@ -3014,7 +3014,7 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len,
 		break;
 	default:
 		WARN_ON_ONCE(1);
-		return -EIO;
+		return smb_EIO(smb_eio_trace_rdma_iter_type);
 	}
 
 	if (ret < 0) {
diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
index 28e00c34df1c..65c62c7a7b00 100644
--- a/fs/smb/client/trace.h
+++ b/fs/smb/client/trace.h
@@ -20,6 +20,140 @@
 /*
  * Specify enums for tracing information.
  */
+#define smb_eio_traces \
+	EM(smb_eio_trace_compress_copy,			"compress_copy") \
+	EM(smb_eio_trace_copychunk_inv_rsp,		"copychunk_inv_rsp") \
+	EM(smb_eio_trace_copychunk_overcopy_b,		"copychunk_overcopy_b") \
+	EM(smb_eio_trace_copychunk_overcopy_c,		"copychunk_overcopy_c") \
+	EM(smb_eio_trace_create_rsp_too_small,		"create_rsp_too_small") \
+	EM(smb_eio_trace_dfsref_no_rsp,			"dfsref_no_rsp") \
+	EM(smb_eio_trace_ea_overrun,			"ea_overrun") \
+	EM(smb_eio_trace_extract_will_pin,		"extract_will_pin") \
+	EM(smb_eio_trace_forced_shutdown,		"forced_shutdown") \
+	EM(smb_eio_trace_getacl_bcc_too_small,		"getacl_bcc_too_small") \
+	EM(smb_eio_trace_getcifsacl_param_count,	"getcifsacl_param_count") \
+	EM(smb_eio_trace_getdfsrefer_bcc_too_small,	"getdfsrefer_bcc_too_small") \
+	EM(smb_eio_trace_getextattr_bcc_too_small,	"getextattr_bcc_too_small") \
+	EM(smb_eio_trace_getextattr_inv_size,		"getextattr_inv_size") \
+	EM(smb_eio_trace_getsrvinonum_bcc_too_small,	"getsrvinonum_bcc_too_small") \
+	EM(smb_eio_trace_getsrvinonum_size,		"getsrvinonum_size") \
+	EM(smb_eio_trace_ioctl_data_len,		"ioctl_data_len") \
+	EM(smb_eio_trace_ioctl_no_rsp,			"ioctl_no_rsp") \
+	EM(smb_eio_trace_ioctl_out_off,			"ioctl_out_off") \
+	EM(smb_eio_trace_lock_bcc_too_small,		"lock_bcc_too_small") \
+	EM(smb_eio_trace_lock_data_too_small,		"lock_data_too_small") \
+	EM(smb_eio_trace_malformed_ksid_key,		"malformed_ksid_key") \
+	EM(smb_eio_trace_malformed_sid_key,		"malformed_sid_key") \
+	EM(smb_eio_trace_mkdir_no_rsp,			"mkdir_no_rsp") \
+	EM(smb_eio_trace_neg_bad_rsplen,		"neg_bad_rsplen") \
+	EM(smb_eio_trace_neg_decode_token,		"neg_decode_token") \
+	EM(smb_eio_trace_neg_info_caps,			"neg_info_caps") \
+	EM(smb_eio_trace_neg_info_dialect,		"neg_info_dialect") \
+	EM(smb_eio_trace_neg_info_fail,			"neg_info_fail") \
+	EM(smb_eio_trace_neg_info_sec_mode,		"neg_info_sec_mode") \
+	EM(smb_eio_trace_neg_inval_dialect,		"neg_inval_dialect") \
+	EM(smb_eio_trace_neg_no_crypt_key,		"neg_no_crypt_key") \
+	EM(smb_eio_trace_neg_sec_blob_too_small,	"neg_sec_blob_too_small") \
+	EM(smb_eio_trace_neg_unreq_dialect,		"neg_unreq_dialect") \
+	EM(smb_eio_trace_no_auth_key,			"no_auth_key") \
+	EM(smb_eio_trace_no_lease_key,			"no_lease_key") \
+	EM(smb_eio_trace_not_netfs_writeback,		"not_netfs_writeback") \
+	EM(smb_eio_trace_null_pointers,			"null_pointers") \
+	EM(smb_eio_trace_oldqfsinfo_bcc_too_small,	"oldqfsinfo_bcc_too_small") \
+	EM(smb_eio_trace_pend_del_fail,			"pend_del_fail") \
+	EM(smb_eio_trace_qalleas_bcc_too_small,		"qalleas_bcc_too_small") \
+	EM(smb_eio_trace_qalleas_ea_overlong,		"qalleas_ea_overlong") \
+	EM(smb_eio_trace_qalleas_overlong,		"qalleas_overlong") \
+	EM(smb_eio_trace_qfileinfo_bcc_too_small,	"qfileinfo_bcc_too_small") \
+	EM(smb_eio_trace_qfileinfo_invalid,		"qfileinfo_invalid") \
+	EM(smb_eio_trace_qfsattrinfo_bcc_too_small,	"qfsattrinfo_bcc_too_small") \
+	EM(smb_eio_trace_qfsdevinfo_bcc_too_small,	"qfsdevinfo_bcc_too_small") \
+	EM(smb_eio_trace_qfsinfo_bcc_too_small,		"qfsinfo_bcc_too_small") \
+	EM(smb_eio_trace_qfsposixinfo_bcc_too_small,	"qfsposixinfo_bcc_too_small") \
+	EM(smb_eio_trace_qfsunixinfo_bcc_too_small,	"qfsunixinfo_bcc_too_small") \
+	EM(smb_eio_trace_qpathinfo_bcc_too_small,	"qpathinfo_bcc_too_small") \
+	EM(smb_eio_trace_qpathinfo_invalid,		"qpathinfo_invalid") \
+	EM(smb_eio_trace_qreparse_data_area,		"qreparse_data_area") \
+	EM(smb_eio_trace_qreparse_rep_datalen,		"qreparse_rep_datalen") \
+	EM(smb_eio_trace_qreparse_ret_datalen,		"qreparse_ret_datalen") \
+	EM(smb_eio_trace_qreparse_setup_count,		"qreparse_setup_count") \
+	EM(smb_eio_trace_qreparse_sizes_wrong,		"qreparse_sizes_wrong") \
+	EM(smb_eio_trace_qsym_bcc_too_small,		"qsym_bcc_too_small") \
+	EM(smb_eio_trace_rdma_dma_map,			"rdma_dma_map") \
+	EM(smb_eio_trace_rdma_fq_overrun,		"rdma_fq_overrun") \
+	EM(smb_eio_trace_rdma_iter_type,		"rdma_iter_type") \
+	EM(smb_eio_trace_rdma_set_sge,			"rdma_set_sge") \
+	EM(smb_eio_trace_read_mid_state_unknown,	"read_mid_state_unknown") \
+	EM(smb_eio_trace_read_overlarge,		"read_overlarge") \
+	EM(smb_eio_trace_read_rsp_malformed,		"read_rsp_malformed") \
+	EM(smb_eio_trace_read_rsp_short,		"read_rsp_short") \
+	EM(smb_eio_trace_read_too_far,			"read_too_far") \
+	EM(smb_eio_trace_reparse_data_len,		"reparse_data_len") \
+	EM(smb_eio_trace_reparse_native_len,		"reparse_native_len") \
+	EM(smb_eio_trace_reparse_native_nul,		"reparse_native_nul") \
+	EM(smb_eio_trace_reparse_native_sym_len,	"reparse_native_sym_len") \
+	EM(smb_eio_trace_reparse_nfs_dev,		"reparse_nfs_dev") \
+	EM(smb_eio_trace_reparse_nfs_nul,		"reparse_nfs_nul") \
+	EM(smb_eio_trace_reparse_nfs_sockfifo,		"reparse_nfs_sockfifo") \
+	EM(smb_eio_trace_reparse_nfs_symbuf,		"reparse_nfs_symbuf") \
+	EM(smb_eio_trace_reparse_nfs_too_short,		"reparse_nfs_too_short") \
+	EM(smb_eio_trace_reparse_overlong,		"reparse_overlong") \
+	EM(smb_eio_trace_reparse_rdlen,			"reparse_rdlen") \
+	EM(smb_eio_trace_reparse_wsl_nul,		"reparse_wsl_nul") \
+	EM(smb_eio_trace_reparse_wsl_symbuf,		"reparse_wsl_symbuf") \
+	EM(smb_eio_trace_reparse_wsl_ver,		"reparse_wsl_ver") \
+	EM(smb_eio_trace_rx_b_read_short,		"rx_b_read_short") \
+	EM(smb_eio_trace_rx_bad_datalen,		"rx_bad_datalen") \
+	EM(smb_eio_trace_rx_both_buf,			"rx_both_buf") \
+	EM(smb_eio_trace_rx_calc_len_too_big,		"rx_calc_len_too_big") \
+	EM(smb_eio_trace_rx_check_rsp,			"rx_check_rsp") \
+	EM(smb_eio_trace_rx_copy_to_iter,		"rx_copy_to_iter") \
+	EM(smb_eio_trace_rx_insuff_res,			"rx_insuff_res") \
+	EM(smb_eio_trace_rx_inv_bcc,			"rx_inv_bcc") \
+	EM(smb_eio_trace_rx_mid_unready,		"rx_mid_unready") \
+	EM(smb_eio_trace_rx_neg_sess_resp,		"rx_neg_sess_resp") \
+	EM(smb_eio_trace_rx_overlong,			"rx_overlong") \
+	EM(smb_eio_trace_rx_overpage,			"rx_overpage") \
+	EM(smb_eio_trace_rx_pos_sess_resp,		"rx_pos_sess_resp") \
+	EM(smb_eio_trace_rx_rfc1002_magic,		"rx_rfc1002_magic") \
+	EM(smb_eio_trace_rx_sync_mid_invalid,		"rx_sync_mid_invalid") \
+	EM(smb_eio_trace_rx_sync_mid_malformed,		"rx_sync_mid_malformed") \
+	EM(smb_eio_trace_rx_too_short,			"rx_too_short") \
+	EM(smb_eio_trace_rx_trans2_extract,		"rx_trans2_extract") \
+	EM(smb_eio_trace_rx_unknown_resp,		"rx_unknown_resp") \
+	EM(smb_eio_trace_rx_unspec_error,		"rx_unspec_error") \
+	EM(smb_eio_trace_sess_buf_off,			"sess_buf_off") \
+	EM(smb_eio_trace_sess_exiting,			"sess_exiting") \
+	EM(smb_eio_trace_sess_krb_wcc,			"sess_krb_wcc") \
+	EM(smb_eio_trace_sess_nl2_wcc,			"sess_nl2_wcc") \
+	EM(smb_eio_trace_sess_rawnl_auth_wcc,		"sess_rawnl_auth_wcc") \
+	EM(smb_eio_trace_sess_rawnl_neg_wcc,		"sess_rawnl_neg_wcc") \
+	EM(smb_eio_trace_short_symlink_write,		"short_symlink_write") \
+	EM(smb_eio_trace_sid_too_many_auth,		"sid_too_many_auth") \
+	EM(smb_eio_trace_sig_data_too_small,		"sig_data_too_small") \
+	EM(smb_eio_trace_sig_iter,			"sig_iter") \
+	EM(smb_eio_trace_smb1_received_error,		"smb1_received_error") \
+	EM(smb_eio_trace_smb2_received_error,		"smb2_received_error") \
+	EM(smb_eio_trace_sym_slash,			"sym_slash") \
+	EM(smb_eio_trace_sym_target_len,		"sym_target_len") \
+	EM(smb_eio_trace_symlink_file_size,		"symlink_file_size") \
+	EM(smb_eio_trace_tdis_in_reconnect,		"tdis_in_reconnect") \
+	EM(smb_eio_trace_tx_chained_async,		"tx_chained_async") \
+	EM(smb_eio_trace_tx_compress_failed,		"tx_compress_failed") \
+	EM(smb_eio_trace_tx_copy_iter_to_buf,		"tx_copy_iter_to_buf") \
+	EM(smb_eio_trace_tx_copy_to_buf,		"tx_copy_to_buf") \
+	EM(smb_eio_trace_tx_max_compound,		"tx_max_compound") \
+	EM(smb_eio_trace_tx_miscopy_to_buf,		"tx_miscopy_to_buf") \
+	EM(smb_eio_trace_tx_need_transform,		"tx_need_transform") \
+	EM(smb_eio_trace_tx_too_long,			"sr_too_long") \
+	EM(smb_eio_trace_unixqfileinfo_bcc_too_small,	"unixqfileinfo_bcc_too_small") \
+	EM(smb_eio_trace_unixqpathinfo_bcc_too_small,	"unixqpathinfo_bcc_too_small") \
+	EM(smb_eio_trace_user_iter,			"user_iter") \
+	EM(smb_eio_trace_write_bad_buf_type,		"write_bad_buf_type") \
+	EM(smb_eio_trace_write_mid_state_unknown,	"write_mid_state_unknown") \
+	EM(smb_eio_trace_write_rsp_malformed,		"write_rsp_malformed") \
+	E_(smb_eio_trace_write_too_far,			"write_too_far")
+
 #define smb3_rw_credits_traces \
 	EM(cifs_trace_rw_credits_call_readv_adjust,	"rd-call-adj") \
 	EM(cifs_trace_rw_credits_call_writev_adjust,	"wr-call-adj") \
@@ -79,6 +213,7 @@
 #define EM(a, b) a,
 #define E_(a, b) a
 
+enum smb_eio_trace		{ smb_eio_traces } __mode(byte);
 enum smb3_rw_credits_trace	{ smb3_rw_credits_traces } __mode(byte);
 enum smb3_tcon_ref_trace	{ smb3_tcon_ref_traces } __mode(byte);
 
@@ -92,6 +227,7 @@ enum smb3_tcon_ref_trace	{ smb3_tcon_ref_traces } __mode(byte);
 #define EM(a, b) TRACE_DEFINE_ENUM(a);
 #define E_(a, b) TRACE_DEFINE_ENUM(a);
 
+smb_eio_traces;
 smb3_rw_credits_traces;
 smb3_tcon_ref_traces;
 
@@ -1616,6 +1752,23 @@ TRACE_EVENT(smb3_rw_credits,
 		      __entry->server_credits, __entry->in_flight)
 	    );
 
+TRACE_EVENT(smb3_eio,
+	    TP_PROTO(enum smb_eio_trace trace, unsigned long info, unsigned long info2),
+	    TP_ARGS(trace, info, info2),
+	    TP_STRUCT__entry(
+		    __field(enum smb_eio_trace,	trace)
+		    __field(unsigned long,	info)
+		    __field(unsigned long,	info2)
+			     ),
+	    TP_fast_assign(
+		    __entry->trace	= trace;
+		    __entry->info	= info;
+		    __entry->info2	= info2;
+			   ),
+	    TP_printk("%s info=%lx,%lx",
+		      __print_symbolic(__entry->trace, smb_eio_traces),
+		      __entry->info, __entry->info2)
+	    );
 
 #undef EM
 #undef E_
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index 362c5c6c91a4..47bfa5bef4e5 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -402,11 +402,11 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
 		return __smb_send_rqst(server, num_rqst, rqst);
 
 	if (WARN_ON_ONCE(num_rqst > MAX_COMPOUND - 1))
-		return -EIO;
+		return smb_EIO1(smb_eio_trace_tx_max_compound, num_rqst);
 
 	if (!server->ops->init_transform_rq) {
 		cifs_server_dbg(VFS, "Encryption requested but transform callback is missing\n");
-		return -EIO;
+		return smb_EIO(smb_eio_trace_tx_need_transform);
 	}
 
 	new_rqst[0].rq_iov = &iov;
@@ -753,7 +753,7 @@ int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server
 		rc = -EAGAIN;
 		break;
 	case MID_RESPONSE_MALFORMED:
-		rc = -EIO;
+		rc = smb_EIO(smb_eio_trace_rx_sync_mid_malformed);
 		break;
 	case MID_SHUTDOWN:
 		rc = -EHOSTDOWN;
@@ -769,7 +769,7 @@ int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server
 		spin_unlock(&server->mid_queue_lock);
 		cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
 			 __func__, smb->mid, smb->mid_state);
-		rc = -EIO;
+		rc = smb_EIO1(smb_eio_trace_rx_sync_mid_invalid, smb->mid_state);
 		goto sync_mid_done;
 	}
 	spin_unlock(&server->mid_queue_lock);
@@ -883,7 +883,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 
 	if (!ses || !ses->server || !server) {
 		cifs_dbg(VFS, "Null session\n");
-		return -EIO;
+		return smb_EIO(smb_eio_trace_null_pointers);
 	}
 
 	spin_lock(&server->srv_lock);
@@ -1040,7 +1040,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 
 		if (!smb[i]->resp_buf ||
 		    smb[i]->mid_state != MID_RESPONSE_READY) {
-			rc = -EIO;
+			rc = smb_EIO1(smb_eio_trace_rx_mid_unready, smb[i]->mid_state);
 			cifs_dbg(FYI, "Bad MID state?\n");
 			goto out;
 		}
@@ -1212,7 +1212,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
 		cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
 			 __func__, server->total_read,
 			 server->vals->read_rsp_size);
-		rdata->result = -EIO;
+		rdata->result = smb_EIO2(smb_eio_trace_read_rsp_short,
+					 server->total_read, server->vals->read_rsp_size);
 		return cifs_readv_discard(server, smb);
 	}
 
@@ -1230,7 +1231,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
 		/* data_offset is beyond the end of smallbuf */
 		cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
 			 __func__, data_offset);
-		rdata->result = -EIO;
+		rdata->result = smb_EIO1(smb_eio_trace_read_overlarge,
+					 data_offset);
 		return cifs_readv_discard(server, smb);
 	}
 
@@ -1254,7 +1256,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
 	data_len = server->ops->read_data_length(buf, use_rdma_mr);
 	if (!use_rdma_mr && (data_offset + data_len > buflen)) {
 		/* data_len is corrupt -- discard frame */
-		rdata->result = -EIO;
+		rdata->result = smb_EIO2(smb_eio_trace_read_rsp_malformed,
+					 data_offset + data_len, buflen);
 		return cifs_readv_discard(server, smb);
 	}
 
diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c
index 029910d56c22..6bc89c59164a 100644
--- a/fs/smb/client/xattr.c
+++ b/fs/smb/client/xattr.c
@@ -397,7 +397,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
 	void *page;
 
 	if (unlikely(cifs_forced_shutdown(cifs_sb)))
-		return -EIO;
+		return smb_EIO(smb_eio_trace_forced_shutdown);
 
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
 		return -EOPNOTSUPP;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 12:42 ` [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002 David Howells
@ 2025-11-24 14:20   ` Stefan Metzmacher
  2025-11-24 14:36   ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: Stefan Metzmacher @ 2025-11-24 14:20 UTC (permalink / raw)
  To: David Howells, Steve French
  Cc: Paulo Alcantara, Shyam Prasad N, linux-cifs, netfs, linux-fsdevel,
	linux-kernel, Tom Talpey

Hi David,

I had to squash this into the patch

I'm using smatch when building and got the following error
with this change:

     client/transport.c:1073 compound_send_recv() error: we previously assumed 'resp_iov' could be null (see line 1051)

See my inline comment below to see where the problem is introduced.

It goes away when I squash the following:

diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index c023c9873c88..7036acd6542b 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -995,6 +995,9 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
  	if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
  		spin_unlock(&ses->ses_lock);

+		if (WARN_ON_ONCE(num_rqst != 1 || !resp_iov))
+			return -EINVAL;
+
  		cifs_server_lock(server);
  		smb311_update_preauth_hash(ses, server, rqst[0].rq_iov, rqst[0].rq_nvec);
  		cifs_server_unlock(server);


Am 24.11.25 um 13:42 schrieb David Howells:
> Clean up some places where previously an extra element in the kvec array
> was being used to hold an rfc1002 header for SMB1 (a previous patch removed
> this and generated it on the fly as for SMB2/3).
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Steve French <sfrench@samba.org>
> cc: Paulo Alcantara <pc@manguebit.org>
> cc: Shyam Prasad N <sprasad@microsoft.com>
> cc: Tom Talpey <tom@talpey.com>
> cc: linux-cifs@vger.kernel.org
> cc: netfs@lists.linux.dev
> cc: linux-fsdevel@vger.kernel.org
> ---
>   fs/smb/client/cifsencrypt.c   | 52 ++++++++---------------------------
>   fs/smb/client/cifsproto.h     |  5 ----
>   fs/smb/client/cifstransport.c | 20 ++------------
>   fs/smb/client/smb1ops.c       | 12 +++++---
>   fs/smb/client/transport.c     | 25 +++++++++--------
>   5 files changed, 35 insertions(+), 79 deletions(-)
> 
> diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
> index 1e0ac87c6686..a9a57904c6b1 100644
> --- a/fs/smb/client/cifsencrypt.c
> +++ b/fs/smb/client/cifsencrypt.c
> @@ -86,26 +86,21 @@ static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize,
>   int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
>   			  char *signature, struct cifs_calc_sig_ctx *ctx)
>   {
> -	int i;
> +	struct iov_iter iter;
>   	ssize_t rc;
> -	struct kvec *iov = rqst->rq_iov;
> -	int n_vec = rqst->rq_nvec;
> +	size_t size = 0;
>   
> -	for (i = 0; i < n_vec; i++) {
> -		if (iov[i].iov_len == 0)
> -			continue;
> -		if (iov[i].iov_base == NULL) {
> -			cifs_dbg(VFS, "null iovec entry\n");
> -			return -EIO;
> -		}
> +	for (int i = 0; i < rqst->rq_nvec; i++)
> +		size += rqst->rq_iov[i].iov_len;
>   
> -		rc = cifs_sig_update(ctx, iov[i].iov_base, iov[i].iov_len);
> -		if (rc) {
> -			cifs_dbg(VFS, "%s: Could not update with payload\n",
> -				 __func__);
> -			return rc;
> -		}
> -	}
> +	iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size);
> +
> +	if (iov_iter_count(&iter) <= 4)
> +		return -EIO;
> +
> +	rc = cifs_sig_iter(&iter, iov_iter_count(&iter), ctx);
> +	if (rc < 0)
> +		return rc;
>   
>   	rc = cifs_sig_iter(&rqst->rq_iter, iov_iter_count(&rqst->rq_iter), ctx);
>   	if (rc < 0)
> @@ -186,29 +181,6 @@ int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
>   	return rc;
>   }
>   
> -int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
> -		   __u32 *pexpected_response_sequence)
> -{
> -	struct smb_rqst rqst = { .rq_iov = iov,
> -				 .rq_nvec = n_vec };
> -
> -	return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
> -}
> -
> -/* must be called with server->srv_mutex held */
> -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[1] = {
> -		[0].iov_base = (char *)cifs_pdu,
> -		[0].iov_len = pdu_len,
> -	};
> -
> -	return cifs_sign_smbv(iov, ARRAY_SIZE(iov), server,
> -			      pexpected_response_sequence_number);
> -}
> -
>   int cifs_verify_signature(struct smb_rqst *rqst,
>   			  struct TCP_Server_Info *server,
>   			  __u32 expected_sequence_number)
> diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
> index 4af6ea8150c3..39586f2dfad5 100644
> --- a/fs/smb/client/cifsproto.h
> +++ b/fs/smb/client/cifsproto.h
> @@ -68,11 +68,6 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
>   			  char *signature, struct cifs_calc_sig_ctx *ctx);
>   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, 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,
>   			  __u32 expected_sequence_number);
> diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
> index 1a0b80fc97d4..6fa60de786e9 100644
> --- a/fs/smb/client/cifstransport.c
> +++ b/fs/smb/client/cifstransport.c
> @@ -71,22 +71,6 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
>   	return smb;
>   }
>   
> -int
> -smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
> -	 unsigned int 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);
> -}
> -
>   static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
>   			struct smb_message **ppmidQ)
>   {
> @@ -370,7 +354,7 @@ int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
>   		return rc;
>   	}
>   
> -	rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
> +	rc = cifs_sign_rqst(&rqst, server, &smb->sequence_number);
>   	if (rc) {
>   		delete_mid(smb);
>   		cifs_server_unlock(server);
> @@ -378,7 +362,7 @@ int SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
>   	}
>   
>   	smb->mid_state = MID_REQUEST_SUBMITTED;
> -	rc = smb_send(server, in_buf, in_len);
> +	rc = __smb_send_rqst(server, 1, &rqst);
>   	cifs_save_when_sent(smb);
>   
>   	if (rc < 0)
> diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
> index 91205685057c..6b0d0b511b9f 100644
> --- a/fs/smb/client/smb1ops.c
> +++ b/fs/smb/client/smb1ops.c
> @@ -34,17 +34,21 @@ static int
>   send_nt_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
>   	       struct smb_message *smb)
>   {
> -	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;
> +	struct kvec iov[1];
> +	struct smb_rqst crqst = { .rq_iov = iov, .rq_nvec = 1 };
> +	int rc = 0;
>   
>   	/* +2 for BCC field */
>   	in_buf->Command = SMB_COM_NT_CANCEL;
>   	in_buf->WordCount = 0;
>   	put_bcc(0, in_buf);
>   
> +	iov[0].iov_base = in_buf;
> +	iov[0].iov_len  = sizeof(struct smb_hdr) + 2;
> +
>   	cifs_server_lock(server);
> -	rc = cifs_sign_smb(in_buf, in_len, server, &smb->sequence_number);
> +	rc = cifs_sign_rqst(&crqst, server, &smb->sequence_number);
>   	if (rc) {
>   		cifs_server_unlock(server);
>   		return rc;
> @@ -56,7 +60,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, in_len);
> +	rc = __smb_send_rqst(server, 1, &crqst);
>   	if (rc < 0)
>   		server->sequence_number--;
>   
> diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
> index 2e338e186809..c023c9873c88 100644
> --- a/fs/smb/client/transport.c
> +++ b/fs/smb/client/transport.c
> @@ -1043,22 +1043,23 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
>   			goto out;
>   		}
>   
> -		buf = (char *)smb[i]->resp_buf;
> -		resp_iov[i].iov_base = buf;
> -		resp_iov[i].iov_len = smb[i]->resp_buf_size;
> -
> -		if (smb[i]->large_buf)
> -			resp_buf_type[i] = CIFS_LARGE_BUFFER;
> -		else
> -			resp_buf_type[i] = CIFS_SMALL_BUFFER;
> -
>   		rc = server->ops->check_receive(smb[i], server,
>   						     flags & CIFS_LOG_ERROR);
>   
> -		/* mark it so buf will not be freed by delete_mid */
> -		if ((flags & CIFS_NO_RSP_BUF) == 0)
> -			smb[i]->resp_buf = NULL;
> +		if (resp_iov) {

Is it really possible that resp_iov is NULL here?

I guess it is for things with CIFS_NO_RSP_BUF, correct?

> +			buf = (char *)smb[i]->resp_buf;
> +			resp_iov[i].iov_base = buf;
> +			resp_iov[i].iov_len = smb[i]->resp_buf_size;
>   
> +			if (smb[i]->large_buf)
> +				resp_buf_type[i] = CIFS_LARGE_BUFFER;
> +			else
> +				resp_buf_type[i] = CIFS_SMALL_BUFFER;
> +
> +			/* mark it so buf will not be freed by delete_mid */
> +			if ((flags & CIFS_NO_RSP_BUF) == 0)
> +				smb[i]->resp_buf = NULL;
> +		}
>   	}
>   
>   	/*
> 


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors
  2025-11-24 12:42 ` [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors David Howells
@ 2025-11-24 14:22   ` Stefan Metzmacher
  2025-11-24 14:38   ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: Stefan Metzmacher @ 2025-11-24 14:22 UTC (permalink / raw)
  To: David Howells, Steve French
  Cc: Paulo Alcantara, Shyam Prasad N, linux-cifs, netfs, linux-fsdevel,
	linux-kernel

Hi David,

would you mind if we remove all smbdirect.c changes from this patch,
as my changes I'm currently rebasing on this would remove them again
anyway.

metze

Am 24.11.25 um 13:42 schrieb David Howells:

> Add a tracepoint to log EIO errors and give it the capacity to convey up to
> two integers of information.  This is then wrapped with three functions:
> 
>   int smb_EIO(enum smb_eio_trace trace)
>   int smb_EIO1(enum smb_eio_trace trace, unsigned long info)
>   int smb_EIO2(enum smb_eio_trace trace, unsigned long info,
> 	      unsigned long info2)
> 
> depending on how many bits of info are desired to be logged with any
> particular trace.  The functions all return -EIO and can be used in place
> of -EIO.
> 
> The trace argument is an enum value that gets translated to a string when
> the trace is printed.
> 
> This makes is easier to log EIO instances when the client is under high
> load than turning on a printk wrapper such as cifs_dbg().  Granted, EIO
> could have its own separate EIO printing since EIO shouldn't happen.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: Steve French <sfrench@samba.org>
> cc: Paulo Alcantara <pc@manguebit.org>
> cc: linux-cifs@vger.kernel.org
> cc: linux-fsdevel@vger.kernel.org
> ---
>   fs/smb/client/cached_dir.c    |   2 +-
>   fs/smb/client/cifsacl.c       |  10 +-
>   fs/smb/client/cifsencrypt.c   |  13 ++-
>   fs/smb/client/cifsglob.h      |  88 -----------------
>   fs/smb/client/cifsproto.h     | 106 ++++++++++++++++++++
>   fs/smb/client/cifssmb.c       | 147 ++++++++++++++++++----------
>   fs/smb/client/cifstransport.c |   8 +-
>   fs/smb/client/compress.c      |   2 +-
>   fs/smb/client/connect.c       |  11 ++-
>   fs/smb/client/dir.c           |   6 +-
>   fs/smb/client/file.c          |   6 +-
>   fs/smb/client/inode.c         |  14 +--
>   fs/smb/client/link.c          |  10 +-
>   fs/smb/client/misc.c          |  18 ++--
>   fs/smb/client/netmisc.c       |   4 +
>   fs/smb/client/readdir.c       |   2 +-
>   fs/smb/client/reparse.c       |  53 ++++++----
>   fs/smb/client/sess.c          |   8 +-
>   fs/smb/client/smb2file.c      |   6 +-
>   fs/smb/client/smb2inode.c     |  12 ++-
>   fs/smb/client/smb2maperror.c  |   3 +
>   fs/smb/client/smb2ops.c       |  41 +++++---
>   fs/smb/client/smb2pdu.c       | 177 +++++++++++++++++++++-------------
>   fs/smb/client/smb2transport.c |   2 +-
>   fs/smb/client/smbdirect.c     |  18 ++--
>   fs/smb/client/trace.h         | 153 +++++++++++++++++++++++++++++
>   fs/smb/client/transport.c     |  21 ++--
>   fs/smb/client/xattr.c         |   2 +-
>   28 files changed, 622 insertions(+), 321 deletions(-)
> 
> diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
> index e3ea6fe7edb4..1db7ab6c2529 100644
> --- a/fs/smb/client/cached_dir.c
> +++ b/fs/smb/client/cached_dir.c
> @@ -176,7 +176,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>   	server = cifs_pick_channel(ses);
>   
>   	if (!server->ops->new_lease_key)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_no_lease_key);
>   
>   	utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
>   	if (!utf16_path)
> diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c
> index 7b88ef38bdf4..78a9d9bb9365 100644
> --- a/fs/smb/client/cifsacl.c
> +++ b/fs/smb/client/cifsacl.c
> @@ -301,7 +301,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
>   			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
>   		goto out_revert_creds;
>   	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
>   		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
>   			 __func__, sidkey->datalen);
>   		goto invalidate_key;
> @@ -318,7 +318,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
>   
>   	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
>   	if (ksid_size > sidkey->datalen) {
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
> +			      ksid_size, sidkey->datalen);
>   		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
>   			 __func__, sidkey->datalen, ksid_size);
>   		goto invalidate_key;
> @@ -353,7 +354,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
>   	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
>   		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
>   			 __func__, psid->num_subauth);
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_sid_too_many_auth,
> +				psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
>   	}
>   
>   	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
> @@ -1228,7 +1230,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
>   	__u32 dacloffset;
>   
>   	if (pntsd == NULL)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
>   				le32_to_cpu(pntsd->osidoffset));
> diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
> index a9a57904c6b1..ca2a84e8673e 100644
> --- a/fs/smb/client/cifsencrypt.c
> +++ b/fs/smb/client/cifsencrypt.c
> @@ -75,11 +75,13 @@ static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize,
>   			 struct cifs_calc_sig_ctx *ctx)
>   {
>   	struct iov_iter tmp_iter = *iter;
> -	int err = -EIO;
> +	size_t did;
> +	int err;
>   
> -	if (iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
> -				       cifs_sig_step) != maxsize)
> -		return err;
> +	did = iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
> +					 cifs_sig_step);
> +	if (did != maxsize)
> +		return smb_EIO2(smb_eio_trace_sig_iter, did, maxsize);
>   	return 0;
>   }
>   
> @@ -96,7 +98,8 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
>   	iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size);
>   
>   	if (iov_iter_count(&iter) <= 4)
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_sig_data_too_small,
> +				iov_iter_count(&iter), 4);
>   
>   	rc = cifs_sig_iter(&iter, iov_iter_count(&iter), ctx);
>   	if (rc < 0)
> diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
> index 33e8ecec0067..92d8ff2065b3 100644
> --- a/fs/smb/client/cifsglob.h
> +++ b/fs/smb/client/cifsglob.h
> @@ -2184,94 +2184,6 @@ static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const
>   	dst->FileNameLength = src->FileNameLength;
>   }
>   
> -static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
> -				   int num_rqst,
> -				   const u8 *sig)
> -{
> -	unsigned int len, skip;
> -	unsigned int nents = 0;
> -	unsigned long addr;
> -	size_t data_size;
> -	int i, j;
> -
> -	/*
> -	 * The first rqst has a transform header where the first 20 bytes are
> -	 * not part of the encrypted blob.
> -	 */
> -	skip = 20;
> -
> -	/* Assumes the first rqst has a transform header as the first iov.
> -	 * I.e.
> -	 * rqst[0].rq_iov[0]  is transform header
> -	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
> -	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
> -	 */
> -	for (i = 0; i < num_rqst; i++) {
> -		data_size = iov_iter_count(&rqst[i].rq_iter);
> -
> -		/* We really don't want a mixture of pinned and unpinned pages
> -		 * in the sglist.  It's hard to keep track of which is what.
> -		 * Instead, we convert to a BVEC-type iterator higher up.
> -		 */
> -		if (data_size &&
> -		    WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
> -			return -EIO;
> -
> -		/* We also don't want to have any extra refs or pins to clean
> -		 * up in the sglist.
> -		 */
> -		if (data_size &&
> -		    WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
> -			return -EIO;
> -
> -		for (j = 0; j < rqst[i].rq_nvec; j++) {
> -			struct kvec *iov = &rqst[i].rq_iov[j];
> -
> -			addr = (unsigned long)iov->iov_base + skip;
> -			if (is_vmalloc_or_module_addr((void *)addr)) {
> -				len = iov->iov_len - skip;
> -				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
> -						      PAGE_SIZE);
> -			} else {
> -				nents++;
> -			}
> -			skip = 0;
> -		}
> -		if (data_size)
> -			nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
> -	}
> -	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
> -	return nents;
> -}
> -
> -/* We can not use the normal sg_set_buf() as we will sometimes pass a
> - * stack object as buf.
> - */
> -static inline void cifs_sg_set_buf(struct sg_table *sgtable,
> -				   const void *buf,
> -				   unsigned int buflen)
> -{
> -	unsigned long addr = (unsigned long)buf;
> -	unsigned int off = offset_in_page(addr);
> -
> -	addr &= PAGE_MASK;
> -	if (is_vmalloc_or_module_addr((void *)addr)) {
> -		do {
> -			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
> -
> -			sg_set_page(&sgtable->sgl[sgtable->nents++],
> -				    vmalloc_to_page((void *)addr), len, off);
> -
> -			off = 0;
> -			addr += PAGE_SIZE;
> -			buflen -= len;
> -		} while (buflen);
> -	} else {
> -		sg_set_page(&sgtable->sgl[sgtable->nents++],
> -			    virt_to_page((void *)addr), buflen, off);
> -	}
> -}
> -
>   #define CIFS_OPARMS(_cifs_sb, _tcon, _path, _da, _cd, _co, _mode) \
>   	((struct cifs_open_parms) { \
>   		.tcon = _tcon, \
> diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
> index df7e86e0471c..6dbf2cec3859 100644
> --- a/fs/smb/client/cifsproto.h
> +++ b/fs/smb/client/cifsproto.h
> @@ -707,4 +707,110 @@ static inline void cifs_free_open_info(struct cifs_open_info_data *data)
>   	memset(data, 0, sizeof(*data));
>   }
>   
> +static inline int smb_EIO(enum smb_eio_trace trace)
> +{
> +	trace_smb3_eio(trace, 0, 0);
> +	return -EIO;
> +}
> +
> +static inline int smb_EIO1(enum smb_eio_trace trace, unsigned long info)
> +{
> +	trace_smb3_eio(trace, info, 0);
> +	return -EIO;
> +}
> +
> +static inline int smb_EIO2(enum smb_eio_trace trace, unsigned long info, unsigned long info2)
> +{
> +	trace_smb3_eio(trace, info, info2);
> +	return -EIO;
> +}
> +
> +static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
> +				   int num_rqst,
> +				   const u8 *sig)
> +{
> +	unsigned int len, skip;
> +	unsigned int nents = 0;
> +	unsigned long addr;
> +	size_t data_size;
> +	int i, j;
> +
> +	/*
> +	 * The first rqst has a transform header where the first 20 bytes are
> +	 * not part of the encrypted blob.
> +	 */
> +	skip = 20;
> +
> +	/* Assumes the first rqst has a transform header as the first iov.
> +	 * I.e.
> +	 * rqst[0].rq_iov[0]  is transform header
> +	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
> +	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
> +	 */
> +	for (i = 0; i < num_rqst; i++) {
> +		data_size = iov_iter_count(&rqst[i].rq_iter);
> +
> +		/* We really don't want a mixture of pinned and unpinned pages
> +		 * in the sglist.  It's hard to keep track of which is what.
> +		 * Instead, we convert to a BVEC-type iterator higher up.
> +		 */
> +		if (data_size &&
> +		    WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
> +			return smb_EIO(smb_eio_trace_user_iter);
> +
> +		/* We also don't want to have any extra refs or pins to clean
> +		 * up in the sglist.
> +		 */
> +		if (data_size &&
> +		    WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
> +			return smb_EIO(smb_eio_trace_extract_will_pin);
> +
> +		for (j = 0; j < rqst[i].rq_nvec; j++) {
> +			struct kvec *iov = &rqst[i].rq_iov[j];
> +
> +			addr = (unsigned long)iov->iov_base + skip;
> +			if (is_vmalloc_or_module_addr((void *)addr)) {
> +				len = iov->iov_len - skip;
> +				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
> +						      PAGE_SIZE);
> +			} else {
> +				nents++;
> +			}
> +			skip = 0;
> +		}
> +		if (data_size)
> +			nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
> +	}
> +	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
> +	return nents;
> +}
> +
> +/* We can not use the normal sg_set_buf() as we will sometimes pass a
> + * stack object as buf.
> + */
> +static inline void cifs_sg_set_buf(struct sg_table *sgtable,
> +				   const void *buf,
> +				   unsigned int buflen)
> +{
> +	unsigned long addr = (unsigned long)buf;
> +	unsigned int off = offset_in_page(addr);
> +
> +	addr &= PAGE_MASK;
> +	if (is_vmalloc_or_module_addr((void *)addr)) {
> +		do {
> +			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
> +
> +			sg_set_page(&sgtable->sgl[sgtable->nents++],
> +				    vmalloc_to_page((void *)addr), len, off);
> +
> +			off = 0;
> +			addr += PAGE_SIZE;
> +			buflen -= len;
> +		} while (buflen);
> +	} else {
> +		sg_set_page(&sgtable->sgl[sgtable->nents++],
> +			    virt_to_page((void *)addr), buflen, off);
> +	}
> +}
> +
>   #endif			/* _CIFSPROTO_H */
> diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
> index d28b1b113e79..d33c624b3356 100644
> --- a/fs/smb/client/cifssmb.c
> +++ b/fs/smb/client/cifssmb.c
> @@ -374,7 +374,8 @@ decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE_RSP *pSMBr)
>   
>   	count = get_bcc(&pSMBr->hdr);
>   	if (count < SMB1_CLIENT_GUID_SIZE)
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_neg_sec_blob_too_small,
> +				count, SMB1_CLIENT_GUID_SIZE);
>   
>   	spin_lock(&cifs_tcp_ses_lock);
>   	if (server->srv_count > 1) {
> @@ -433,7 +434,7 @@ CIFSSMBNegotiate(const unsigned int xid,
>   
>   	if (!server) {
>   		WARN(1, "%s: server is NULL!\n", __func__);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	}
>   
>   	rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
> @@ -517,7 +518,8 @@ CIFSSMBNegotiate(const unsigned int xid,
>   		server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
>   		rc = decode_ext_sec_blob(ses, pSMBr);
>   	} else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
> -		rc = -EIO; /* no crypt key only if plain text pwd */
> +		/* no crypt key only if plain text pwd */
> +		rc = smb_EIO(smb_eio_trace_neg_no_crypt_key);
>   	} else {
>   		server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
>   		server->capabilities &= ~CAP_EXTENDED_SECURITY;
> @@ -543,7 +545,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
>   
>   	/* BB: do we need to check this? These should never be NULL. */
>   	if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	/*
>   	 * No need to return error on this operation if tid invalidated and
> @@ -554,7 +556,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
>   	spin_lock(&tcon->ses->chan_lock);
>   	if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
>   		spin_unlock(&tcon->ses->chan_lock);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_tdis_in_reconnect);
>   	}
>   	spin_unlock(&tcon->ses->chan_lock);
>   
> @@ -651,7 +653,7 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
>   	 * should probably be a BUG()
>   	 */
>   	if (!ses || !ses->server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	mutex_lock(&ses->session_mutex);
>   	spin_lock(&ses->chan_lock);
> @@ -981,7 +983,8 @@ CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon,
>   	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   	if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
> -		rc = -EIO;	/* bad smb */
> +		rc = smb_EIO2(smb_eio_trace_create_rsp_too_small,
> +			      get_bcc(&pSMBr->hdr), sizeof(OPEN_PSX_RSP));
>   		goto psx_create_err;
>   	}
>   
> @@ -1372,11 +1375,12 @@ cifs_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
>   		break;
>   	case MID_RESPONSE_MALFORMED:
>   		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
>   		break;
>   	default:
>   		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
> +					 smb->mid_state);
>   		break;
>   	}
>   
> @@ -1447,7 +1451,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
>   		wct = 10; /* old style read */
>   		if ((rdata->subreq.start >> 32) > 0)  {
>   			/* can not handle this big offset for old */
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_read_too_far);
>   		}
>   	}
>   
> @@ -1522,7 +1526,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
>   		wct = 10; /* old style read */
>   		if ((offset >> 32) > 0)  {
>   			/* can not handle this big offset for old */
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_read_too_far);
>   		}
>   	}
>   
> @@ -1577,7 +1581,8 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
>   				|| (data_length > count)) {
>   			cifs_dbg(FYI, "bad length %d for count %d\n",
>   				 data_length, count);
> -			rc = -EIO;
> +			rc = smb_EIO2(smb_eio_trace_read_overlarge,
> +				      data_length, count);
>   			*nbytes = 0;
>   		} else {
>   			pReadData = (char *) (&pSMBr->hdr.Protocol) +
> @@ -1636,7 +1641,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
>   		wct = 12;
>   		if ((offset >> 32) > 0) {
>   			/* can not handle big offset for old srv */
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_write_too_far);
>   		}
>   	}
>   
> @@ -1787,11 +1792,12 @@ cifs_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
>   		break;
>   	case MID_RESPONSE_MALFORMED:
>   		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
> -		result = -EIO;
> +		result = smb_EIO(smb_eio_trace_write_rsp_malformed);
>   		break;
>   	default:
>   		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
> -		result = -EIO;
> +		result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
> +				  smb->mid_state);
>   		break;
>   	}
>   
> @@ -1826,7 +1832,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
>   		wct = 12;
>   		if (wdata->subreq.start >> 32 > 0) {
>   			/* can not handle big offset for old srv */
> -			rc = -EIO;
> +			rc = smb_EIO(smb_eio_trace_write_too_far);
>   			goto out;
>   		}
>   	}
> @@ -1918,7 +1924,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
>   		wct = 12;
>   		if ((offset >> 32) > 0) {
>   			/* can not handle big offset for old srv */
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_write_too_far);
>   		}
>   	}
>   	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
> @@ -1974,7 +1980,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
>   		cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
>   	} else if (resp_buf_type == 0) {
>   		/* presumably this can not happen, but best to be safe */
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_write_bad_buf_type, resp_buf_type);
>   	} else {
>   		WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
>   		*nbytes = le16_to_cpu(pSMBr->CountHigh);
> @@ -2210,13 +2216,15 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
> -			rc = -EIO;      /* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_lock_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), sizeof(*parm_data));
>   			goto plk_err_exit;
>   		}
>   		data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   		data_count  = le16_to_cpu(pSMBr->t2.DataCount);
>   		if (data_count < sizeof(struct cifs_posix_lock)) {
> -			rc = -EIO;
> +			rc = smb_EIO2(smb_eio_trace_lock_data_too_small,
> +				      data_count, sizeof(struct cifs_posix_lock));
>   			goto plk_err_exit;
>   		}
>   		parm_data = (struct cifs_posix_lock *)
> @@ -2775,7 +2783,8 @@ CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   		/* BB also check enough total bytes returned */
>   		if (rc || get_bcc(&pSMBr->hdr) < 2)
> -			rc = -EIO;
> +			rc = smb_EIO2(smb_eio_trace_qsym_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 2);
>   		else {
>   			bool is_unicode;
>   			u16 count = le16_to_cpu(pSMBr->t2.DataCount);
> @@ -2877,13 +2886,15 @@ int cifs_query_reparse_point(const unsigned int xid,
>   	data_count = le32_to_cpu(io_rsp->DataCount);
>   	if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
>   	    !data_count || data_count > 2048) {
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_qreparse_sizes_wrong,
> +			      get_bcc(&io_rsp->hdr), data_count);
>   		goto error;
>   	}
>   
>   	/* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
>   	if (io_rsp->SetupCount != 1) {
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_qreparse_setup_count,
> +			      io_rsp->SetupCount, 1);
>   		goto error;
>   	}
>   
> @@ -2893,14 +2904,17 @@ int cifs_query_reparse_point(const unsigned int xid,
>   	 * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
>   	 */
>   	if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_qreparse_ret_datalen,
> +			      data_count, le16_to_cpu(io_rsp->ReturnedDataLen));
>   		goto error;
>   	}
>   
>   	end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
>   	start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
>   	if (start >= end) {
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_qreparse_data_area,
> +			      (unsigned long)start - (unsigned long)io_rsp,
> +			      (unsigned long)end - (unsigned long)io_rsp);
>   		goto error;
>   	}
>   
> @@ -2909,7 +2923,8 @@ int cifs_query_reparse_point(const unsigned int xid,
>   	len = sizeof(*buf);
>   	if (data_count < len ||
>   	    data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_qreparse_rep_datalen,
> +			      data_count, le16_to_cpu(buf->ReparseDataLength) + len);
>   		goto error;
>   	}
>   
> @@ -3353,7 +3368,8 @@ int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   		/* BB also check enough total bytes returned */
>   		if (rc || get_bcc(&pSMBr->hdr) < 2)
> -			rc = -EIO;      /* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_getacl_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 2);
>   		else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
> @@ -3526,7 +3542,8 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
>   		if (rc || get_bcc(&pSMBr->hdr) < 2)
>   			/* If rc should we check for EOPNOSUPP and
>   			   disable the srvino flag? or in caller? */
> -			rc = -EIO;      /* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_getextattr_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 2);
>   		else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
> @@ -3534,7 +3551,8 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
>   
>   			if (count != 16) {
>   				cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
> -				rc = -EIO;
> +				rc = smb_EIO2(smb_eio_trace_getextattr_inv_size,
> +					      count, 16);
>   				goto GetExtAttrOut;
>   			}
>   			pfinfo = (struct file_chattr_info *)
> @@ -3701,7 +3719,8 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
>   			 pSMBr, parm, *acl_inf);
>   
>   		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
> -			rc = -EIO;      /* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_getcifsacl_param_count,
> +				      le32_to_cpu(pSMBr->ParameterCount), 4);
>   			*pbuflen = 0;
>   			goto qsec_out;
>   		}
> @@ -3859,8 +3878,10 @@ SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
>   		data->EndOfFile = data->AllocationSize;
>   		data->Attributes =
>   			cpu_to_le32(le16_to_cpu(pSMBr->attr));
> -	} else
> -		rc = -EIO; /* bad buffer passed in */
> +	} else {
> +		/* bad buffer passed in */
> +		rc = smb_EIO(smb_eio_trace_null_pointers);
> +	}
>   
>   	cifs_buf_release(pSMB);
>   
> @@ -3922,9 +3943,11 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc) /* BB add auto retry on EOPNOTSUPP? */
> -			rc = -EIO;
> +			rc = smb_EIO2(smb_eio_trace_qfileinfo_invalid,
> +				      get_bcc(&pSMBr->hdr), 40);
>   		else if (get_bcc(&pSMBr->hdr) < 40)
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 40);
>   		else if (pFindData) {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			memcpy((char *) pFindData,
> @@ -4009,12 +4032,15 @@ CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc) /* BB add auto retry on EOPNOTSUPP? */
> -			rc = -EIO;
> +			rc = smb_EIO2(smb_eio_trace_qpathinfo_invalid,
> +				      get_bcc(&pSMBr->hdr), 40);
>   		else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 40);
>   		else if (legacy && get_bcc(&pSMBr->hdr) < 24)
> -			rc = -EIO;  /* 24 or 26 expected but we do not read
> -					last field */
> +			/* 24 or 26 expected but we do not read last field */
> +			rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 24);
>   		else if (data) {
>   			int size;
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
> @@ -4094,7 +4120,8 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
>   			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
>   		} else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			memcpy((char *) pFindData,
> @@ -4178,7 +4205,8 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
>   			cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
>   		} else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			memcpy((char *) pFindData,
> @@ -4581,7 +4609,8 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
>   		if (rc || get_bcc(&pSMBr->hdr) < 2)
>   			/* If rc should we check for EOPNOSUPP and
>   			disable the srvino flag? or in caller? */
> -			rc = -EIO;      /* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 2);
>   		else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			__u16 count = le16_to_cpu(pSMBr->t2.DataCount);
> @@ -4589,7 +4618,8 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
>   			/* BB Do we need a cast or hash here ? */
>   			if (count < 8) {
>   				cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
> -				rc = -EIO;
> +				rc = smb_EIO2(smb_eio_trace_getsrvinonum_size,
> +					      count, 8);
>   				goto GetInodeNumOut;
>   			}
>   			pfinfo = (struct file_internal_info *)
> @@ -4698,7 +4728,8 @@ CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses,
>   
>   	/* BB Also check if enough total bytes returned? */
>   	if (rc || get_bcc(&pSMBr->hdr) < 17) {
> -		rc = -EIO;      /* bad smb */
> +		rc = smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small,
> +			      get_bcc(&pSMBr->hdr), 17);
>   		goto GetDFSRefExit;
>   	}
>   
> @@ -4774,7 +4805,8 @@ SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < 18)
> -			rc = -EIO;      /* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 18);
>   		else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
> @@ -4863,7 +4895,8 @@ CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < 24)
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 24);
>   		else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   
> @@ -4953,7 +4986,8 @@ CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon)
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < 13) {
>   			/* BB also check if enough bytes returned */
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 13);
>   		} else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			response_data =
> @@ -5026,7 +5060,9 @@ CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon)
>   
>   		if (rc || get_bcc(&pSMBr->hdr) <
>   			  sizeof(FILE_SYSTEM_DEVICE_INFO))
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr),
> +				      sizeof(FILE_SYSTEM_DEVICE_INFO));
>   		else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			response_data =
> @@ -5097,7 +5133,8 @@ CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon)
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < 13) {
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 13);
>   		} else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			response_data =
> @@ -5245,7 +5282,8 @@ CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
>   		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   
>   		if (rc || get_bcc(&pSMBr->hdr) < 13) {
> -			rc = -EIO;	/* bad smb */
> +			rc = smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small,
> +				      get_bcc(&pSMBr->hdr), 13);
>   		} else {
>   			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
>   			response_data =
> @@ -6045,7 +6083,8 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
>   
>   	rc = validate_t2((struct smb_t2_rsp *)pSMBr);
>   	if (rc || get_bcc(&pSMBr->hdr) < 4) {
> -		rc = -EIO;	/* bad smb */
> +		rc = smb_EIO2(smb_eio_trace_qalleas_bcc_too_small,
> +			      get_bcc(&pSMBr->hdr), 4);
>   		goto QAllEAsOut;
>   	}
>   
> @@ -6075,7 +6114,9 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
>   	end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
>   	if ((char *)ea_response_data + list_len > end_of_smb) {
>   		cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
> +			      (unsigned long)ea_response_data + list_len - (unsigned long)pSMBr,
> +			      (unsigned long)end_of_smb - (unsigned long)pSMBr);
>   		goto QAllEAsOut;
>   	}
>   
> @@ -6092,7 +6133,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
>   		/* make sure we can read name_len and value_len */
>   		if (list_len < 0) {
>   			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
> -			rc = -EIO;
> +			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
>   			goto QAllEAsOut;
>   		}
>   
> @@ -6101,7 +6142,7 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
>   		list_len -= name_len + 1 + value_len;
>   		if (list_len < 0) {
>   			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
> -			rc = -EIO;
> +			rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
>   			goto QAllEAsOut;
>   		}
>   
> diff --git a/fs/smb/client/cifstransport.c b/fs/smb/client/cifstransport.c
> index 218c0fad901b..04d39b1de899 100644
> --- a/fs/smb/client/cifstransport.c
> +++ b/fs/smb/client/cifstransport.c
> @@ -228,15 +228,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
>   	int rc = 0;
>   
>   	if (WARN_ON_ONCE(in_len > 0xffffff))
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_tx_too_long, in_len);
>   	if (ses == NULL) {
>   		cifs_dbg(VFS, "Null smb session\n");
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	}
>   	server = ses->server;
>   	if (server == NULL) {
>   		cifs_dbg(VFS, "Null tcp session\n");
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	}
>   
>   	/* Ensure that we do not send more than 50 overlapping requests
> @@ -246,7 +246,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
>   	if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
>   		cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
>   				in_len);
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_tx_too_long, in_len);
>   	}
>   
>   	rc = cifs_send_recv(xid, ses, ses->server,
> diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c
> index fb2a48f1d2ad..e0c44b46080e 100644
> --- a/fs/smb/client/compress.c
> +++ b/fs/smb/client/compress.c
> @@ -325,7 +325,7 @@ int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_s
>   	iter = rq->rq_iter;
>   
>   	if (!copy_from_iter_full(src, slen, &iter)) {
> -		ret = -EIO;
> +		ret = smb_EIO(smb_eio_trace_compress_copy);
>   		goto err_free;
>   	}
>   
> diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
> index 7a1112fae6ee..13426c2d3fad 100644
> --- a/fs/smb/client/connect.c
> +++ b/fs/smb/client/connect.c
> @@ -3241,7 +3241,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
>   		if (be16_to_cpu(resp.length) != 0) {
>   			cifs_dbg(VFS, "RFC 1002 positive session response but with invalid non-zero length %u\n",
>   				 be16_to_cpu(resp.length));
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_rx_pos_sess_resp);
>   		}
>   		cifs_dbg(FYI, "RFC 1002 positive session response");
>   		break;
> @@ -3280,17 +3280,18 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
>   				break;
>   			case RFC1002_INSUFFICIENT_RESOURCE:
>   				/* remote server resource error */
> +				smb_EIO(smb_eio_trace_rx_insuff_res);
>   				rc = -EREMOTEIO;
>   				break;
>   			case RFC1002_UNSPECIFIED_ERROR:
>   			default:
>   				/* other/unknown error */
> -				rc = -EIO;
> +				rc = smb_EIO(smb_eio_trace_rx_unspec_error);
>   				break;
>   			}
>   		} else {
>   			cifs_dbg(VFS, "RFC 1002 negative session response\n");
> -			rc = -EIO;
> +			rc = smb_EIO(smb_eio_trace_rx_neg_sess_resp);
>   		}
>   		return rc;
>   	case RFC1002_RETARGET_SESSION_RESPONSE:
> @@ -3312,7 +3313,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
>   		return -EMULTIHOP;
>   	default:
>   		cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", resp.type);
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_rx_unknown_resp, resp.type);
>   	}
>   
>   	server->with_rfc1001 = true;
> @@ -4002,7 +4003,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
>   	__u16 bytes_left, count;
>   
>   	if (ses == NULL)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	smb_buffer = cifs_buf_get();
>   	if (smb_buffer == NULL)
> diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
> index 2cf0c4f1746d..9a45578741fa 100644
> --- a/fs/smb/client/dir.c
> +++ b/fs/smb/client/dir.c
> @@ -472,7 +472,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
>   	struct cifs_open_info_data buf = {};
>   
>   	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	/*
>   	 * Posix open is only called (at lookup time) for file create now. For
> @@ -590,7 +590,7 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *inode,
>   		 inode, direntry, direntry);
>   
>   	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_forced_shutdown);
>   		goto out_free_xid;
>   	}
>   
> @@ -632,7 +632,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode,
>   
>   	cifs_sb = CIFS_SB(inode->i_sb);
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	tlink = cifs_sb_tlink(cifs_sb);
>   	if (IS_ERR(tlink))
> diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
> index 0939b91c5acc..f4b625ea2abe 100644
> --- a/fs/smb/client/file.c
> +++ b/fs/smb/client/file.c
> @@ -118,7 +118,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
>   	int rc;
>   
>   	if (cifs_forced_shutdown(sbi)) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_forced_shutdown);
>   		goto fail;
>   	}
>   
> @@ -286,7 +286,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file)
>   			req->pid = req->cfile->pid;
>   	} else if (rreq->origin != NETFS_WRITEBACK) {
>   		WARN_ON_ONCE(1);
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_not_netfs_writeback, rreq->origin);
>   	}
>   
>   	return 0;
> @@ -1036,7 +1036,7 @@ int cifs_open(struct inode *inode, struct file *file)
>   	cifs_sb = CIFS_SB(inode->i_sb);
>   	if (unlikely(cifs_forced_shutdown(cifs_sb))) {
>   		free_xid(xid);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   	}
>   
>   	tlink = cifs_sb_tlink(cifs_sb);
> diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
> index a6489517495d..d94203dc5131 100644
> --- a/fs/smb/client/inode.c
> +++ b/fs/smb/client/inode.c
> @@ -1952,7 +1952,7 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
>   	cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry);
>   
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	/* Unhash dentry in advance to prevent any concurrent opens */
>   	spin_lock(&dentry->d_lock);
> @@ -2268,7 +2268,7 @@ struct dentry *cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
>   
>   	cifs_sb = CIFS_SB(inode->i_sb);
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return ERR_PTR(-EIO);
> +		return ERR_PTR(smb_EIO(smb_eio_trace_forced_shutdown));
>   	tlink = cifs_sb_tlink(cifs_sb);
>   	if (IS_ERR(tlink))
>   		return ERR_CAST(tlink);
> @@ -2354,7 +2354,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
>   
>   	cifs_sb = CIFS_SB(inode->i_sb);
>   	if (unlikely(cifs_forced_shutdown(cifs_sb))) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_forced_shutdown);
>   		goto rmdir_exit;
>   	}
>   
> @@ -2516,7 +2516,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
>   
>   	cifs_sb = CIFS_SB(source_dir->i_sb);
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	/*
>   	 * Prevent any concurrent opens on the target by unhashing the dentry.
> @@ -2901,7 +2901,7 @@ int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,
>   	int rc;
>   
>   	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	/*
>   	 * We need to be sure that all dirty pages are written and the server
> @@ -2976,7 +2976,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start,
>   	int rc;
>   
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	/*
>   	 * We need to be sure that all dirty pages are written as they
> @@ -3468,7 +3468,7 @@ cifs_setattr(struct mnt_idmap *idmap, struct dentry *direntry,
>   #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
>   
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   	/*
>   	 * Avoid setting [cm]time with O_TRUNC to prevent the server from
>   	 * disabling automatic timestamp updates as specified in
> diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c
> index d92eb14b97dd..a6e5a3d93077 100644
> --- a/fs/smb/client/link.c
> +++ b/fs/smb/client/link.c
> @@ -161,7 +161,8 @@ create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
>   		goto out;
>   
>   	if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_symlink_file_size,
> +			      bytes_written, CIFS_MF_SYMLINK_FILE_SIZE);
>   out:
>   	kfree(buf);
>   	return rc;
> @@ -425,7 +426,8 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
>   
>   	/* Make sure we wrote all of the symlink data */
>   	if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_short_symlink_write,
> +			      *pbytes_written, CIFS_MF_SYMLINK_FILE_SIZE);
>   
>   	SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
>   
> @@ -452,7 +454,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
>   	struct cifsInodeInfo *cifsInode;
>   
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	tlink = cifs_sb_tlink(cifs_sb);
>   	if (IS_ERR(tlink))
> @@ -554,7 +556,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
>   	struct inode *newinode = NULL;
>   
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	page = alloc_dentry_path();
>   	if (!page)
> diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
> index 6e59c79dbbc6..9529fa385938 100644
> --- a/fs/smb/client/misc.c
> +++ b/fs/smb/client/misc.c
> @@ -380,25 +380,29 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
>   				return 0;
>   			}
>   			cifs_dbg(VFS, "rcvd invalid byte count (bcc)\n");
> +			return smb_EIO1(smb_eio_trace_rx_inv_bcc, tmp[sizeof(struct smb_hdr)]);
>   		} else {
>   			cifs_dbg(VFS, "Length less than smb header size\n");
> +			return smb_EIO2(smb_eio_trace_rx_too_short,
> +					total_read, smb->WordCount);
>   		}
> -		return -EIO;
>   	} else if (total_read < sizeof(*smb) + 2 * smb->WordCount) {
>   		cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n",
>   			 __func__, smb->WordCount);
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_rx_check_rsp,
> +				total_read, 2 + sizeof(struct smb_hdr));
>   	}
>   
>   	/* otherwise, there is enough to get to the BCC */
>   	if (check_smb_hdr(smb))
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_rx_rfc1002_magic, *(u32 *)smb->Protocol);
>   	clc_len = smbCalcSize(smb);
>   
>   	if (rfclen != total_read) {
>   		cifs_dbg(VFS, "Length read does not match RFC1001 length %d/%d\n",
>   			 rfclen, total_read);
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_rx_check_rsp,
> +				total_read, rfclen);
>   	}
>   
>   	if (rfclen != clc_len) {
> @@ -415,7 +419,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
>   		if (rfclen < clc_len) {
>   			cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n",
>   				 rfclen, mid);
> -			return -EIO;
> +			return smb_EIO2(smb_eio_trace_rx_calc_len_too_big,
> +					rfclen, clc_len);
>   		} else if (rfclen > clc_len + 512) {
>   			/*
>   			 * Some servers (Windows XP in particular) send more
> @@ -428,7 +433,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
>   			 */
>   			cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for mid=%u\n",
>   				 rfclen, mid);
> -			return -EIO;
> +			return smb_EIO2(smb_eio_trace_rx_overlong,
> +					rfclen, clc_len + 512);
>   		}
>   	}
>   	return 0;
> diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
> index 7ad5a3cc05d1..4a98b71288d6 100644
> --- a/fs/smb/client/netmisc.c
> +++ b/fs/smb/client/netmisc.c
> @@ -885,6 +885,10 @@ map_smb_to_linux_error(char *buf, bool logErr)
>   	/* generic corrective action e.g. reconnect SMB session on
>   	 * ERRbaduid could be added */
>   
> +	if (rc == -EIO)
> +		smb_EIO2(smb_eio_trace_smb1_received_error,
> +			 le32_to_cpu(smb->Status.CifsError),
> +			 le16_to_cpu(smb->Flags2));
>   	return rc;
>   }
>   
> diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
> index 7ff728503ed1..6844f1dc3921 100644
> --- a/fs/smb/client/readdir.c
> +++ b/fs/smb/client/readdir.c
> @@ -775,7 +775,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
>   
>   		if (cfile->srch_inf.ntwrk_buf_start == NULL) {
>   			cifs_dbg(VFS, "ntwrk_buf_start is NULL during readdir\n");
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_null_pointers);
>   		}
>   
>   		end_of_smb = cfile->srch_inf.ntwrk_buf_start +
> diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
> index 10c84c095fe7..ce9b923498b5 100644
> --- a/fs/smb/client/reparse.c
> +++ b/fs/smb/client/reparse.c
> @@ -732,7 +732,8 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
>   	len = le16_to_cpu(buf->ReparseDataLength);
>   	if (len < sizeof(buf->InodeType)) {
>   		cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_reparse_nfs_too_short,
> +				len, sizeof(buf->InodeType));
>   	}
>   
>   	len -= sizeof(buf->InodeType);
> @@ -741,7 +742,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
>   	case NFS_SPECFILE_LNK:
>   		if (len == 0 || (len % 2)) {
>   			cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
> -			return -EIO;
> +			return smb_EIO1(smb_eio_trace_reparse_nfs_symbuf, len);
>   		}
>   		/*
>   		 * Check that buffer does not contain UTF-16 null codepoint
> @@ -749,7 +750,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
>   		 */
>   		if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
>   			cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
> -			return -EIO;
> +			return smb_EIO1(smb_eio_trace_reparse_nfs_nul, len);
>   		}
>   		data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
>   							       len, true,
> @@ -764,7 +765,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
>   		/* DataBuffer for block and char devices contains two 32-bit numbers */
>   		if (len != 8) {
>   			cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
> -			return -EIO;
> +			return smb_EIO1(smb_eio_trace_reparse_nfs_dev, len);
>   		}
>   		break;
>   	case NFS_SPECFILE_FIFO:
> @@ -772,7 +773,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
>   		/* DataBuffer for fifos and sockets is empty */
>   		if (len != 0) {
>   			cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
> -			return -EIO;
> +			return smb_EIO1(smb_eio_trace_reparse_nfs_sockfifo, len);
>   		}
>   		break;
>   	default:
> @@ -796,13 +797,13 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
>   	int abs_path_len;
>   	char *abs_path;
>   	int levels;
> -	int rc;
> +	int rc, ulen;
>   	int i;
>   
>   	/* Check that length it valid */
>   	if (!len || (len % 2)) {
>   		cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_reparse_native_nul, len);
>   		goto out;
>   	}
>   
> @@ -810,9 +811,10 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
>   	 * Check that buffer does not contain UTF-16 null codepoint
>   	 * because Linux cannot process symlink with null byte.
>   	 */
> -	if (UniStrnlen((wchar_t *)buf, len/2) != len/2) {
> +	ulen = UniStrnlen((wchar_t *)buf, len/2);
> +	if (ulen != len/2) {
>   		cifs_dbg(VFS, "srv returned null byte in native symlink target location\n");
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_reparse_native_nul, ulen, len);
>   		goto out;
>   	}
>   
> @@ -996,7 +998,8 @@ static int parse_reparse_native_symlink(struct reparse_symlink_data_buffer *sym,
>   	len = le16_to_cpu(sym->SubstituteNameLength);
>   	if (offs + 20 > plen || offs + len + 20 > plen) {
>   		cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_reparse_native_sym_len,
> +				offs << 16 | len, plen);
>   	}
>   
>   	return smb2_parse_native_symlink(&data->symlink_target,
> @@ -1019,13 +1022,16 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
>   
>   	if (len <= data_offset) {
>   		cifs_dbg(VFS, "srv returned malformed wsl symlink buffer\n");
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_reparse_wsl_symbuf,
> +				len, data_offset);
>   	}
>   
>   	/* MS-FSCC 2.1.2.7 defines layout of the Target field only for Version 2. */
> -	if (le32_to_cpu(buf->Version) != 2) {
> -		cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", le32_to_cpu(buf->Version));
> -		return -EIO;
> +	u32 version = le32_to_cpu(buf->Version);
> +
> +	if (version != 2) {
> +		cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", version);
> +		return smb_EIO1(smb_eio_trace_reparse_wsl_ver, version);
>   	}
>   
>   	/* Target for Version 2 is in UTF-8 but without trailing null-term byte */
> @@ -1034,9 +1040,12 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
>   	 * Check that buffer does not contain null byte
>   	 * because Linux cannot process symlink with null byte.
>   	 */
> -	if (strnlen(buf->Target, symname_utf8_len) != symname_utf8_len) {
> +	size_t ulen = strnlen(buf->Target, symname_utf8_len);
> +
> +	if (ulen != symname_utf8_len) {
>   		cifs_dbg(VFS, "srv returned null byte in wsl symlink target location\n");
> -		return -EIO;
> +		return smb_EIO2(smb_eio_trace_reparse_wsl_ver,
> +				ulen, symname_utf8_len);
>   	}
>   	symname_utf16 = kzalloc(symname_utf8_len * 2, GFP_KERNEL);
>   	if (!symname_utf16)
> @@ -1083,13 +1092,17 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
>   	case IO_REPARSE_TAG_AF_UNIX:
>   	case IO_REPARSE_TAG_LX_FIFO:
>   	case IO_REPARSE_TAG_LX_CHR:
> -	case IO_REPARSE_TAG_LX_BLK:
> -		if (le16_to_cpu(buf->ReparseDataLength) != 0) {
> +	case IO_REPARSE_TAG_LX_BLK: {
> +		u16 dlen = le16_to_cpu(buf->ReparseDataLength);
> +
> +		if (dlen != 0) {
> +			u32 rtag = le32_to_cpu(buf->ReparseTag);
>   			cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\n",
> -				 le32_to_cpu(buf->ReparseTag));
> -			return -EIO;
> +				 rtag);
> +			return smb_EIO2(smb_eio_trace_reparse_data_len, dlen, rtag);
>   		}
>   		return 0;
> +	}
>   	default:
>   		return -EOPNOTSUPP;
>   	}
> diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
> index 4cec7d7b6d9c..ffbdb38f00c4 100644
> --- a/fs/smb/client/sess.c
> +++ b/fs/smb/client/sess.c
> @@ -1504,7 +1504,7 @@ sess_auth_ntlmv2(struct sess_data *sess_data)
>   	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
>   
>   	if (smb_buf->WordCount != 3) {
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_sess_nl2_wcc, smb_buf->WordCount);
>   		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
>   		goto out;
>   	}
> @@ -1630,7 +1630,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
>   	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
>   
>   	if (smb_buf->WordCount != 4) {
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_sess_krb_wcc, smb_buf->WordCount);
>   		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
>   		goto out_put_spnego_key;
>   	}
> @@ -1791,7 +1791,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
>   	cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
>   
>   	if (smb_buf->WordCount != 4) {
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_sess_rawnl_neg_wcc, smb_buf->WordCount);
>   		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
>   		goto out_free_ntlmsspblob;
>   	}
> @@ -1881,7 +1881,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
>   	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
>   	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
>   	if (smb_buf->WordCount != 4) {
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_sess_rawnl_auth_wcc, smb_buf->WordCount);
>   		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
>   		goto out_free_ntlmsspblob;
>   	}
> diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c
> index 66e5d6f9e3b7..7f11ae6bb785 100644
> --- a/fs/smb/client/smb2file.c
> +++ b/fs/smb/client/smb2file.c
> @@ -76,11 +76,11 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
>   		return 0;
>   
>   	if (!*target)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	len = strlen(*target);
>   	if (!len)
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_sym_target_len, len);
>   
>   	/*
>   	 * If this is directory symlink and it does not have trailing slash then
> @@ -104,7 +104,7 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
>   	 * both Windows and Linux systems. So return an error for such symlink.
>   	 */
>   	if (!directory && (*target)[len-1] == '/')
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_sym_slash);
>   
>   	return 0;
>   }
> diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
> index 8f86c05d0036..2ded3246600c 100644
> --- a/fs/smb/client/smb2inode.c
> +++ b/fs/smb/client/smb2inode.c
> @@ -30,16 +30,20 @@ static struct reparse_data_buffer *reparse_buf_ptr(struct kvec *iov)
>   	struct reparse_data_buffer *buf;
>   	struct smb2_ioctl_rsp *io = iov->iov_base;
>   	u32 off, count, len;
> +	u16 rdlen;
>   
>   	count = le32_to_cpu(io->OutputCount);
>   	off = le32_to_cpu(io->OutputOffset);
>   	if (check_add_overflow(off, count, &len) || len > iov->iov_len)
> -		return ERR_PTR(-EIO);
> +		return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_overlong,
> +					off, count));
>   
>   	buf = (struct reparse_data_buffer *)((u8 *)io + off);
>   	len = sizeof(*buf);
> -	if (count < len || count < le16_to_cpu(buf->ReparseDataLength) + len)
> -		return ERR_PTR(-EIO);
> +	rdlen = le16_to_cpu(buf->ReparseDataLength);
> +
> +	if (count < len || count < rdlen + len)
> +		return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_rdlen, count, rdlen));
>   	return buf;
>   }
>   
> @@ -1634,7 +1638,7 @@ int smb2_rename_pending_delete(const char *full_path,
>   	} else {
>   		cifs_tcon_dbg(FYI, "%s: failed to rename '%s' to '%s': %d\n",
>   			      __func__, full_path, to_name, rc);
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_pend_del_fail, rc);
>   	}
>   out:
>   	cifs_put_tlink(tlink);
> diff --git a/fs/smb/client/smb2maperror.c b/fs/smb/client/smb2maperror.c
> index 29cf456dade9..4fc22456c39e 100644
> --- a/fs/smb/client/smb2maperror.c
> +++ b/fs/smb/client/smb2maperror.c
> @@ -9,6 +9,7 @@
>    */
>   #include <linux/errno.h>
>   #include "cifsglob.h"
> +#include "cifsproto.h"
>   #include "cifs_debug.h"
>   #include "smb2proto.h"
>   #include "smb2glob.h"
> @@ -2476,5 +2477,7 @@ map_smb2_to_linux_error(char *buf, bool log_err)
>   			   le16_to_cpu(shdr->Command),
>   			   le64_to_cpu(shdr->MessageId),
>   			   le32_to_cpu(smb2err), rc);
> +	if (rc == -EIO)
> +		smb_EIO1(smb_eio_trace_smb2_received_error, le32_to_cpu(smb2err));
>   	return rc;
>   }
> diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
> index 0bc2e4cc2617..7cec987218e9 100644
> --- a/fs/smb/client/smb2ops.c
> +++ b/fs/smb/client/smb2ops.c
> @@ -1046,7 +1046,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
>   
>   		if (src_size < 8 + name_len + 1 + value_len) {
>   			cifs_dbg(FYI, "EA entry goes beyond length of list\n");
> -			rc = -EIO;
> +			rc = smb_EIO2(smb_eio_trace_ea_overrun,
> +				      src_size, 8 + name_len + 1 + value_len);
>   			goto out;
>   		}
>   
> @@ -1607,7 +1608,7 @@ smb2_ioctl_query_info(const unsigned int xid,
>   	}
>   
>   	if (!ses || !server) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_null_pointers);
>   		goto free_vars;
>   	}
>   
> @@ -1942,7 +1943,7 @@ smb2_copychunk_range(const unsigned int xid,
>   		if (unlikely(ret_data_len != sizeof(*cc_rsp))) {
>   			cifs_tcon_dbg(VFS, "Copychunk invalid response: size %u/%zu\n",
>   				      ret_data_len, sizeof(*cc_rsp));
> -			rc = -EIO;
> +			rc = smb_EIO1(smb_eio_trace_copychunk_inv_rsp, ret_data_len);
>   			goto out;
>   		}
>   
> @@ -1952,11 +1953,18 @@ smb2_copychunk_range(const unsigned int xid,
>   
>   		if (rc == 0) {
>   			/* Check if server claimed to write more than we asked */
> -			if (unlikely(!bytes_written || bytes_written > copy_bytes ||
> -				     !chunks_written || chunks_written > chunks)) {
> -				cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u, chunks written %u/%u\n",
> -					      bytes_written, copy_bytes, chunks_written, chunks);
> -				rc = -EIO;
> +			if (unlikely(!bytes_written || bytes_written > copy_bytes)) {
> +				cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u\n",
> +					      bytes_written, copy_bytes);
> +				rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_b,
> +					      bytes_written, copy_bytes);
> +				goto out;
> +			}
> +			if (unlikely(!chunks_written || chunks_written > chunks)) {
> +				cifs_tcon_dbg(VFS, "Copychunk invalid response: chunks written %u/%u\n",
> +					      chunks_written, chunks);
> +				rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_c,
> +					      chunks_written, chunks);
>   				goto out;
>   			}
>   
> @@ -3127,7 +3135,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
>   	}
>   
>   	if (!rc && !dfs_rsp)
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_dfsref_no_rsp);
>   	if (rc) {
>   		if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP)
>   			cifs_tcon_dbg(FYI, "%s: ioctl error: rc=%d\n", __func__, rc);
> @@ -4556,7 +4564,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
>   					     buffer, 0, 0, size);
>   
>   			if (!cifs_copy_iter_to_folioq(&old->rq_iter, size, buffer)) {
> -				rc = -EIO;
> +				rc = smb_EIO1(smb_eio_trace_tx_copy_iter_to_buf, size);
>   				goto err_free;
>   			}
>   		}
> @@ -4657,7 +4665,8 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size,
>   			n = copy_folio_to_iter(folio, skip, len, iter);
>   			if (n != len) {
>   				cifs_dbg(VFS, "%s: something went wrong\n", __func__);
> -				return -EIO;
> +				return smb_EIO2(smb_eio_trace_rx_copy_to_iter,
> +						n, len);
>   			}
>   			data_size -= n;
>   			skip = 0;
> @@ -4740,7 +4749,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
>   		/* data_offset is beyond the end of smallbuf */
>   		cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
>   			 __func__, data_offset);
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO1(smb_eio_trace_rx_overlong, data_offset);
>   		if (is_offloaded)
>   			smb->mid_state = MID_RESPONSE_MALFORMED;
>   		else
> @@ -4759,7 +4768,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
>   			/* data offset is beyond the 1st page of response */
>   			cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n",
>   				 __func__, data_offset);
> -			rdata->result = -EIO;
> +			rdata->result = smb_EIO1(smb_eio_trace_rx_overpage, data_offset);
>   			if (is_offloaded)
>   				smb->mid_state = MID_RESPONSE_MALFORMED;
>   			else
> @@ -4769,7 +4778,7 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
>   
>   		if (data_len > buffer_len - pad_len) {
>   			/* data_len is corrupt -- discard frame */
> -			rdata->result = -EIO;
> +			rdata->result = smb_EIO1(smb_eio_trace_rx_bad_datalen, data_len);
>   			if (is_offloaded)
>   				smb->mid_state = MID_RESPONSE_MALFORMED;
>   			else
> @@ -4794,12 +4803,12 @@ handle_read_data(struct TCP_Server_Info *server, struct smb_message *smb,
>   		WARN_ONCE(buffer, "read data can be either in buf or in buffer");
>   		copied = copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_iter);
>   		if (copied == 0)
> -			return -EIO;
> +			return smb_EIO2(smb_eio_trace_rx_copy_to_iter, copied, data_len);
>   		rdata->got_bytes = copied;
>   	} else {
>   		/* read response payload cannot be in both buf and pages */
>   		WARN_ONCE(1, "buf can not contain only a part of read data");
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO(smb_eio_trace_rx_both_buf);
>   		if (is_offloaded)
>   			smb->mid_state = MID_RESPONSE_MALFORMED;
>   		else
> diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
> index 9c21521061a9..ce56237928a0 100644
> --- a/fs/smb/client/smb2pdu.c
> +++ b/fs/smb/client/smb2pdu.c
> @@ -249,15 +249,15 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
>   
>   	ses = tcon->ses;
>   	if (!ses)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	spin_lock(&ses->ses_lock);
>   	if (ses->ses_status == SES_EXITING) {
>   		spin_unlock(&ses->ses_lock);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_sess_exiting);
>   	}
>   	spin_unlock(&ses->ses_lock);
>   	if (!ses->server || !server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	spin_lock(&server->srv_lock);
>   	if (server->tcpStatus == CifsNeedReconnect) {
> @@ -1061,7 +1061,7 @@ SMB2_negotiate(const unsigned int xid,
>   
>   	if (!server) {
>   		WARN(1, "%s: server is NULL!\n", __func__);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	}
>   
>   	rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server,
> @@ -1142,64 +1142,84 @@ SMB2_negotiate(const unsigned int xid,
>   	} else if (rc != 0)
>   		goto neg_exit;
>   
> -	rc = -EIO;
> +	u16 dialect = le16_to_cpu(rsp->DialectRevision);
>   	if (strcmp(server->vals->version_string,
>   		   SMB3ANY_VERSION_STRING) == 0) {
> -		if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
> +		switch (dialect) {
> +		case SMB20_PROT_ID:
>   			cifs_server_dbg(VFS,
>   				"SMB2 dialect returned but not requested\n");
> +			rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3);
>   			goto neg_exit;
> -		} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
> +		case SMB21_PROT_ID:
>   			cifs_server_dbg(VFS,
>   				"SMB2.1 dialect returned but not requested\n");
> +			rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3);
>   			goto neg_exit;
> -		} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
> +		case SMB311_PROT_ID:
>   			/* ops set to 3.0 by default for default so update */
>   			server->ops = &smb311_operations;
>   			server->vals = &smb311_values;
> +			break;
> +		default:
> +			break;
>   		}
>   	} else if (strcmp(server->vals->version_string,
> -		   SMBDEFAULT_VERSION_STRING) == 0) {
> -		if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
> +			  SMBDEFAULT_VERSION_STRING) == 0) {
> +		switch (dialect) {
> +		case SMB20_PROT_ID:
>   			cifs_server_dbg(VFS,
>   				"SMB2 dialect returned but not requested\n");
> +			rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 0);
>   			goto neg_exit;
> -		} else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
> +		case SMB21_PROT_ID:
>   			/* ops set to 3.0 by default for default so update */
>   			server->ops = &smb21_operations;
>   			server->vals = &smb21_values;
> -		} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
> +			break;
> +		case SMB311_PROT_ID:
>   			server->ops = &smb311_operations;
>   			server->vals = &smb311_values;
> +			break;
> +		default:
> +			break;
>   		}
> -	} else if (le16_to_cpu(rsp->DialectRevision) !=
> -				server->vals->protocol_id) {
> +	} else if (dialect != server->vals->protocol_id) {
>   		/* if requested single dialect ensure returned dialect matched */
>   		cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n",
> -				le16_to_cpu(rsp->DialectRevision));
> +				dialect);
> +		rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect,
> +			      dialect, server->vals->protocol_id);
>   		goto neg_exit;
>   	}
>   
>   	cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
>   
> -	if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID))
> +	switch (dialect) {
> +	case SMB20_PROT_ID:
>   		cifs_dbg(FYI, "negotiated smb2.0 dialect\n");
> -	else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID))
> +		break;
> +	case SMB21_PROT_ID:
>   		cifs_dbg(FYI, "negotiated smb2.1 dialect\n");
> -	else if (rsp->DialectRevision == cpu_to_le16(SMB30_PROT_ID))
> +		break;
> +	case SMB30_PROT_ID:
>   		cifs_dbg(FYI, "negotiated smb3.0 dialect\n");
> -	else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID))
> +		break;
> +	case SMB302_PROT_ID:
>   		cifs_dbg(FYI, "negotiated smb3.02 dialect\n");
> -	else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
> +		break;
> +	case SMB311_PROT_ID:
>   		cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n");
> -	else {
> +		break;
> +	default:
>   		cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n",
> -				le16_to_cpu(rsp->DialectRevision));
> +				dialect);
> +		rc = smb_EIO1(smb_eio_trace_neg_inval_dialect, dialect);
>   		goto neg_exit;
>   	}
>   
>   	rc = 0;
> -	server->dialect = le16_to_cpu(rsp->DialectRevision);
> +	server->dialect = dialect;
>   
>   	/*
>   	 * Keep a copy of the hash after negprot. This hash will be
> @@ -1255,10 +1275,10 @@ SMB2_negotiate(const unsigned int xid,
>   		if (rc == 1)
>   			rc = 0;
>   		else if (rc == 0)
> -			rc = -EIO;
> +			rc = smb_EIO1(smb_eio_trace_neg_decode_token, rc);
>   	}
>   
> -	if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
> +	if (server->dialect == SMB311_PROT_ID) {
>   		if (rsp->NegotiateContextCount)
>   			rc = smb311_decode_neg_context(rsp, server,
>   						       rsp_iov.iov_len);
> @@ -1371,32 +1391,47 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
>   	} else if (rc != 0) {
>   		cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n",
>   			      rc);
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_neg_info_fail, rc);
>   		goto out_free_inbuf;
>   	}
>   
> -	rc = -EIO;
>   	if (rsplen != sizeof(*pneg_rsp)) {
>   		cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n",
>   			      rsplen);
>   
>   		/* relax check since Mac returns max bufsize allowed on ioctl */
> -		if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp))
> +		if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) {
> +			rc = smb_EIO1(smb_eio_trace_neg_bad_rsplen, rsplen);
>   			goto out_free_rsp;
> +		}
>   	}
>   
>   	/* check validate negotiate info response matches what we got earlier */
> -	if (pneg_rsp->Dialect != cpu_to_le16(server->dialect))
> +	u16 dialect = le16_to_cpu(pneg_rsp->Dialect);
> +
> +	if (dialect != server->dialect) {
> +		rc = smb_EIO2(smb_eio_trace_neg_info_dialect,
> +			      dialect, server->dialect);
>   		goto vneg_out;
> +	}
>   
> -	if (pneg_rsp->SecurityMode != cpu_to_le16(server->sec_mode))
> +	u16 sec_mode = le16_to_cpu(pneg_rsp->SecurityMode);
> +
> +	if (sec_mode != server->sec_mode) {
> +		rc = smb_EIO2(smb_eio_trace_neg_info_sec_mode,
> +			      sec_mode, server->sec_mode);
>   		goto vneg_out;
> +	}
>   
>   	/* do not validate server guid because not saved at negprot time yet */
> +	u32 caps = le32_to_cpu(pneg_rsp->Capabilities);
>   
> -	if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
> -	      SMB2_LARGE_FILES) != server->capabilities)
> +	if ((caps | SMB2_NT_FIND |
> +	     SMB2_LARGE_FILES) != server->capabilities) {
> +		rc = smb_EIO2(smb_eio_trace_neg_info_caps,
> +			      caps, server->capabilities);
>   		goto vneg_out;
> +	}
>   
>   	/* validate negotiate successful */
>   	rc = 0;
> @@ -1758,11 +1793,11 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
>   	if (rc)
>   		goto out;
>   
> -	if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=
> -			le16_to_cpu(rsp->SecurityBufferOffset)) {
> -		cifs_dbg(VFS, "Invalid security buffer offset %d\n",
> -			le16_to_cpu(rsp->SecurityBufferOffset));
> -		rc = -EIO;
> +	u16 boff = le16_to_cpu(rsp->SecurityBufferOffset);
> +
> +	if (offsetof(struct smb2_sess_setup_rsp, Buffer) != boff) {
> +		cifs_dbg(VFS, "Invalid security buffer offset %d\n", boff);
> +		rc = smb_EIO1(smb_eio_trace_sess_buf_off, boff);
>   		goto out;
>   	}
>   	rc = decode_ntlmssp_challenge(rsp->Buffer,
> @@ -1916,7 +1951,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
>   
>   	if (!server) {
>   		WARN(1, "%s: server is NULL!\n", __func__);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	}
>   
>   	sess_data = kzalloc(sizeof(struct SMB2_sess_data), GFP_KERNEL);
> @@ -1966,10 +2001,9 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
>   
>   	cifs_dbg(FYI, "disconnect session %p\n", ses);
>   
> -	if (ses && (ses->server))
> -		server = ses->server;
> -	else
> -		return -EIO;
> +	if (!ses || !ses->server)
> +		return smb_EIO(smb_eio_trace_null_pointers);
> +	server = ses->server;
>   
>   	/* no need to send SMB logoff if uid already closed due to reconnect */
>   	spin_lock(&ses->chan_lock);
> @@ -2048,7 +2082,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
>   	cifs_dbg(FYI, "TCON\n");
>   
>   	if (!server || !tree)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
>   	if (unc_path == NULL)
> @@ -2186,7 +2220,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
>   	cifs_dbg(FYI, "Tree Disconnect\n");
>   
>   	if (!ses || !(ses->server))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	trace_smb3_tdis_enter(xid, tcon->tid, ses->Suid, tcon->tree_name);
>   	spin_lock(&ses->chan_lock);
> @@ -2856,7 +2890,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
>   		return -ENOMEM;
>   
>   	if (!ses || !server) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_null_pointers);
>   		goto err_free_path;
>   	}
>   
> @@ -2973,7 +3007,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
>   	 */
>   	rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
>   	if (rsp == NULL) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_mkdir_no_rsp);
>   		kfree(pc_buf);
>   		goto err_free_req;
>   	}
> @@ -3211,7 +3245,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
>   
>   	cifs_dbg(FYI, "create/open\n");
>   	if (!ses || !server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (smb3_encryption_required(tcon))
>   		flags |= CIFS_TRANSFORM_REQ;
> @@ -3417,11 +3451,11 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
>   	int retries = 0, cur_sleep = 1;
>   
>   	if (!tcon)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	ses = tcon->ses;
>   	if (!ses)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   replay_again:
>   	/* reinitialize for possible replay */
> @@ -3429,7 +3463,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
>   	server = cifs_pick_channel(ses);
>   
>   	if (!server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	cifs_dbg(FYI, "SMB2 IOCTL\n");
>   
> @@ -3492,7 +3526,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
>   	 * warning)
>   	 */
>   	if (rsp == NULL) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_ioctl_no_rsp);
>   		goto ioctl_exit;
>   	}
>   
> @@ -3503,16 +3537,18 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
>   		goto ioctl_exit; /* server returned no data */
>   	else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) {
>   		cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
> +		rc = smb_EIO2(smb_eio_trace_ioctl_data_len, *plen, rsp_iov.iov_len);
>   		*plen = 0;
> -		rc = -EIO;
>   		goto ioctl_exit;
>   	}
>   
> -	if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) {
> -		cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
> -			le32_to_cpu(rsp->OutputOffset));
> +	u32 outoff = le32_to_cpu(rsp->OutputOffset);
> +
> +	if (rsp_iov.iov_len - *plen < outoff) {
> +		cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n",
> +			      *plen, outoff);
> +		rc = smb_EIO2(smb_eio_trace_ioctl_out_off, rsp_iov.iov_len - *plen, outoff);
>   		*plen = 0;
> -		rc = -EIO;
>   		goto ioctl_exit;
>   	}
>   
> @@ -3620,7 +3656,7 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
>   	cifs_dbg(FYI, "Close\n");
>   
>   	if (!ses || !server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (smb3_encryption_required(tcon))
>   		flags |= CIFS_TRANSFORM_REQ;
> @@ -3817,7 +3853,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
>   	cifs_dbg(FYI, "Query Info\n");
>   
>   	if (!ses)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   replay_again:
>   	/* reinitialize for possible replay */
> @@ -3826,7 +3862,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
>   	server = cifs_pick_channel(ses);
>   
>   	if (!server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (smb3_encryption_required(tcon))
>   		flags |= CIFS_TRANSFORM_REQ;
> @@ -4012,7 +4048,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
>   
>   	cifs_dbg(FYI, "change notify\n");
>   	if (!ses || !server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (smb3_encryption_required(tcon))
>   		flags |= CIFS_TRANSFORM_REQ;
> @@ -4348,7 +4384,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
>   
>   	cifs_dbg(FYI, "flush\n");
>   	if (!ses || !(ses->server))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (smb3_encryption_required(tcon))
>   		flags |= CIFS_TRANSFORM_REQ;
> @@ -4583,11 +4619,12 @@ smb2_readv_callback(struct TCP_Server_Info *server, struct smb_message *smb)
>   		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
>   		credits.value = le16_to_cpu(shdr->CreditRequest);
>   		credits.instance = server->reconnect_instance;
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
>   		break;
>   	default:
>   		trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
> +					 smb->mid_state);
>   		break;
>   	}
>   #ifdef CONFIG_CIFS_SMB_DIRECT
> @@ -4796,7 +4833,8 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
>   	    (*nbytes > io_parms->length)) {
>   		cifs_dbg(FYI, "bad length %d for count %d\n",
>   			 *nbytes, io_parms->length);
> -		rc = -EIO;
> +		rc = smb_EIO2(smb_eio_trace_read_overlarge,
> +			      *nbytes, io_parms->length);
>   		*nbytes = 0;
>   	}
>   
> @@ -4882,11 +4920,12 @@ smb2_writev_callback(struct TCP_Server_Info *server, struct smb_message *smb)
>   		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
>   		credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
>   		credits.instance = server->reconnect_instance;
> -		result = -EIO;
> +		result = smb_EIO(smb_eio_trace_write_rsp_malformed);
>   		break;
>   	default:
>   		trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
> -		result = -EIO;
> +		result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
> +				  smb->mid_state);
>   		break;
>   	}
>   #ifdef CONFIG_CIFS_SMB_DIRECT
> @@ -5529,7 +5568,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
>   	server = cifs_pick_channel(ses);
>   
>   	if (!ses || !(ses->server))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (smb3_encryption_required(tcon))
>   		flags |= CIFS_TRANSFORM_REQ;
> @@ -5664,7 +5703,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
>   	server = cifs_pick_channel(ses);
>   
>   	if (!ses || !server)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	if (!num)
>   		return -EINVAL;
> @@ -5861,7 +5900,7 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
>   	cifs_dbg(FYI, "Query FSInfo level %d\n", level);
>   
>   	if ((tcon->ses == NULL) || server == NULL)
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   
>   	rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
>   				 (void **) &req, &total_len);
> diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c
> index 47eab3753c9e..b5bd450d30a8 100644
> --- a/fs/smb/client/smb2transport.c
> +++ b/fs/smb/client/smb2transport.c
> @@ -153,7 +153,7 @@ static int smb2_get_sign_key(struct TCP_Server_Info *server,
>   				memcpy(key, ses->auth_key.response,
>   				       SMB2_NTLMV2_SESSKEY_SIZE);
>   			} else {
> -				rc = -EIO;
> +				rc = smb_EIO(smb_eio_trace_no_auth_key);
>   			}
>   			break;
>   		default:
> diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c
> index c6c428c2e08d..1c2fc560b2de 100644
> --- a/fs/smb/client/smbdirect.c
> +++ b/fs/smb/client/smbdirect.c
> @@ -979,7 +979,7 @@ static int smbd_post_send_negotiate_req(struct smbdirect_socket *sc)
>   				sc->ib.dev, (void *)packet,
>   				sizeof(*packet), DMA_TO_DEVICE);
>   	if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_rdma_dma_map);
>   		goto dma_mapping_failed;
>   	}
>   
> @@ -1179,7 +1179,7 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
>   						 header_length,
>   						 DMA_TO_DEVICE);
>   	if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_rdma_dma_map);
>   		goto err_dma;
>   	}
>   
> @@ -1321,13 +1321,13 @@ static int smbd_post_recv(
>   {
>   	struct smbdirect_socket_parameters *sp = &sc->parameters;
>   	struct ib_recv_wr recv_wr;
> -	int rc = -EIO;
> +	int rc;
>   
>   	response->sge.addr = ib_dma_map_single(
>   				sc->ib.dev, response->packet,
>   				sp->max_recv_size, DMA_FROM_DEVICE);
>   	if (ib_dma_mapping_error(sc->ib.dev, response->sge.addr))
> -		return rc;
> +		return smb_EIO(smb_eio_trace_rdma_dma_map);
>   
>   	response->sge.length = sp->max_recv_size;
>   	response->sge.lkey = sc->ib.pd->local_dma_lkey;
> @@ -2855,7 +2855,7 @@ static ssize_t smb_extract_bvec_to_rdma(struct iov_iter *iter,
>   		off = bv[i].bv_offset + start;
>   
>   		if (!smb_set_sge(rdma, bv[i].bv_page, off, len))
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_rdma_set_sge);
>   
>   		ret += len;
>   		maxsize -= len;
> @@ -2909,7 +2909,7 @@ static ssize_t smb_extract_kvec_to_rdma(struct iov_iter *iter,
>   				page = virt_to_page((void *)kaddr);
>   
>   			if (!smb_set_sge(rdma, page, off, seg))
> -				return -EIO;
> +				return smb_EIO(smb_eio_trace_rdma_set_sge);
>   
>   			ret += seg;
>   			len -= seg;
> @@ -2945,7 +2945,7 @@ static ssize_t smb_extract_folioq_to_rdma(struct iov_iter *iter,
>   	if (slot >= folioq_nr_slots(folioq)) {
>   		folioq = folioq->next;
>   		if (WARN_ON_ONCE(!folioq))
> -			return -EIO;
> +			return smb_EIO(smb_eio_trace_rdma_fq_overrun);
>   		slot = 0;
>   	}
>   
> @@ -2957,7 +2957,7 @@ static ssize_t smb_extract_folioq_to_rdma(struct iov_iter *iter,
>   			size_t part = umin(maxsize, fsize - offset);
>   
>   			if (!smb_set_sge(rdma, folio_page(folio, 0), offset, part))
> -				return -EIO;
> +				return smb_EIO(smb_eio_trace_rdma_set_sge);
>   
>   			offset += part;
>   			ret += part;
> @@ -3014,7 +3014,7 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len,
>   		break;
>   	default:
>   		WARN_ON_ONCE(1);
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_rdma_iter_type);
>   	}
>   
>   	if (ret < 0) {
> diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
> index 28e00c34df1c..65c62c7a7b00 100644
> --- a/fs/smb/client/trace.h
> +++ b/fs/smb/client/trace.h
> @@ -20,6 +20,140 @@
>   /*
>    * Specify enums for tracing information.
>    */
> +#define smb_eio_traces \
> +	EM(smb_eio_trace_compress_copy,			"compress_copy") \
> +	EM(smb_eio_trace_copychunk_inv_rsp,		"copychunk_inv_rsp") \
> +	EM(smb_eio_trace_copychunk_overcopy_b,		"copychunk_overcopy_b") \
> +	EM(smb_eio_trace_copychunk_overcopy_c,		"copychunk_overcopy_c") \
> +	EM(smb_eio_trace_create_rsp_too_small,		"create_rsp_too_small") \
> +	EM(smb_eio_trace_dfsref_no_rsp,			"dfsref_no_rsp") \
> +	EM(smb_eio_trace_ea_overrun,			"ea_overrun") \
> +	EM(smb_eio_trace_extract_will_pin,		"extract_will_pin") \
> +	EM(smb_eio_trace_forced_shutdown,		"forced_shutdown") \
> +	EM(smb_eio_trace_getacl_bcc_too_small,		"getacl_bcc_too_small") \
> +	EM(smb_eio_trace_getcifsacl_param_count,	"getcifsacl_param_count") \
> +	EM(smb_eio_trace_getdfsrefer_bcc_too_small,	"getdfsrefer_bcc_too_small") \
> +	EM(smb_eio_trace_getextattr_bcc_too_small,	"getextattr_bcc_too_small") \
> +	EM(smb_eio_trace_getextattr_inv_size,		"getextattr_inv_size") \
> +	EM(smb_eio_trace_getsrvinonum_bcc_too_small,	"getsrvinonum_bcc_too_small") \
> +	EM(smb_eio_trace_getsrvinonum_size,		"getsrvinonum_size") \
> +	EM(smb_eio_trace_ioctl_data_len,		"ioctl_data_len") \
> +	EM(smb_eio_trace_ioctl_no_rsp,			"ioctl_no_rsp") \
> +	EM(smb_eio_trace_ioctl_out_off,			"ioctl_out_off") \
> +	EM(smb_eio_trace_lock_bcc_too_small,		"lock_bcc_too_small") \
> +	EM(smb_eio_trace_lock_data_too_small,		"lock_data_too_small") \
> +	EM(smb_eio_trace_malformed_ksid_key,		"malformed_ksid_key") \
> +	EM(smb_eio_trace_malformed_sid_key,		"malformed_sid_key") \
> +	EM(smb_eio_trace_mkdir_no_rsp,			"mkdir_no_rsp") \
> +	EM(smb_eio_trace_neg_bad_rsplen,		"neg_bad_rsplen") \
> +	EM(smb_eio_trace_neg_decode_token,		"neg_decode_token") \
> +	EM(smb_eio_trace_neg_info_caps,			"neg_info_caps") \
> +	EM(smb_eio_trace_neg_info_dialect,		"neg_info_dialect") \
> +	EM(smb_eio_trace_neg_info_fail,			"neg_info_fail") \
> +	EM(smb_eio_trace_neg_info_sec_mode,		"neg_info_sec_mode") \
> +	EM(smb_eio_trace_neg_inval_dialect,		"neg_inval_dialect") \
> +	EM(smb_eio_trace_neg_no_crypt_key,		"neg_no_crypt_key") \
> +	EM(smb_eio_trace_neg_sec_blob_too_small,	"neg_sec_blob_too_small") \
> +	EM(smb_eio_trace_neg_unreq_dialect,		"neg_unreq_dialect") \
> +	EM(smb_eio_trace_no_auth_key,			"no_auth_key") \
> +	EM(smb_eio_trace_no_lease_key,			"no_lease_key") \
> +	EM(smb_eio_trace_not_netfs_writeback,		"not_netfs_writeback") \
> +	EM(smb_eio_trace_null_pointers,			"null_pointers") \
> +	EM(smb_eio_trace_oldqfsinfo_bcc_too_small,	"oldqfsinfo_bcc_too_small") \
> +	EM(smb_eio_trace_pend_del_fail,			"pend_del_fail") \
> +	EM(smb_eio_trace_qalleas_bcc_too_small,		"qalleas_bcc_too_small") \
> +	EM(smb_eio_trace_qalleas_ea_overlong,		"qalleas_ea_overlong") \
> +	EM(smb_eio_trace_qalleas_overlong,		"qalleas_overlong") \
> +	EM(smb_eio_trace_qfileinfo_bcc_too_small,	"qfileinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qfileinfo_invalid,		"qfileinfo_invalid") \
> +	EM(smb_eio_trace_qfsattrinfo_bcc_too_small,	"qfsattrinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qfsdevinfo_bcc_too_small,	"qfsdevinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qfsinfo_bcc_too_small,		"qfsinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qfsposixinfo_bcc_too_small,	"qfsposixinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qfsunixinfo_bcc_too_small,	"qfsunixinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qpathinfo_bcc_too_small,	"qpathinfo_bcc_too_small") \
> +	EM(smb_eio_trace_qpathinfo_invalid,		"qpathinfo_invalid") \
> +	EM(smb_eio_trace_qreparse_data_area,		"qreparse_data_area") \
> +	EM(smb_eio_trace_qreparse_rep_datalen,		"qreparse_rep_datalen") \
> +	EM(smb_eio_trace_qreparse_ret_datalen,		"qreparse_ret_datalen") \
> +	EM(smb_eio_trace_qreparse_setup_count,		"qreparse_setup_count") \
> +	EM(smb_eio_trace_qreparse_sizes_wrong,		"qreparse_sizes_wrong") \
> +	EM(smb_eio_trace_qsym_bcc_too_small,		"qsym_bcc_too_small") \
> +	EM(smb_eio_trace_rdma_dma_map,			"rdma_dma_map") \
> +	EM(smb_eio_trace_rdma_fq_overrun,		"rdma_fq_overrun") \
> +	EM(smb_eio_trace_rdma_iter_type,		"rdma_iter_type") \
> +	EM(smb_eio_trace_rdma_set_sge,			"rdma_set_sge") \
> +	EM(smb_eio_trace_read_mid_state_unknown,	"read_mid_state_unknown") \
> +	EM(smb_eio_trace_read_overlarge,		"read_overlarge") \
> +	EM(smb_eio_trace_read_rsp_malformed,		"read_rsp_malformed") \
> +	EM(smb_eio_trace_read_rsp_short,		"read_rsp_short") \
> +	EM(smb_eio_trace_read_too_far,			"read_too_far") \
> +	EM(smb_eio_trace_reparse_data_len,		"reparse_data_len") \
> +	EM(smb_eio_trace_reparse_native_len,		"reparse_native_len") \
> +	EM(smb_eio_trace_reparse_native_nul,		"reparse_native_nul") \
> +	EM(smb_eio_trace_reparse_native_sym_len,	"reparse_native_sym_len") \
> +	EM(smb_eio_trace_reparse_nfs_dev,		"reparse_nfs_dev") \
> +	EM(smb_eio_trace_reparse_nfs_nul,		"reparse_nfs_nul") \
> +	EM(smb_eio_trace_reparse_nfs_sockfifo,		"reparse_nfs_sockfifo") \
> +	EM(smb_eio_trace_reparse_nfs_symbuf,		"reparse_nfs_symbuf") \
> +	EM(smb_eio_trace_reparse_nfs_too_short,		"reparse_nfs_too_short") \
> +	EM(smb_eio_trace_reparse_overlong,		"reparse_overlong") \
> +	EM(smb_eio_trace_reparse_rdlen,			"reparse_rdlen") \
> +	EM(smb_eio_trace_reparse_wsl_nul,		"reparse_wsl_nul") \
> +	EM(smb_eio_trace_reparse_wsl_symbuf,		"reparse_wsl_symbuf") \
> +	EM(smb_eio_trace_reparse_wsl_ver,		"reparse_wsl_ver") \
> +	EM(smb_eio_trace_rx_b_read_short,		"rx_b_read_short") \
> +	EM(smb_eio_trace_rx_bad_datalen,		"rx_bad_datalen") \
> +	EM(smb_eio_trace_rx_both_buf,			"rx_both_buf") \
> +	EM(smb_eio_trace_rx_calc_len_too_big,		"rx_calc_len_too_big") \
> +	EM(smb_eio_trace_rx_check_rsp,			"rx_check_rsp") \
> +	EM(smb_eio_trace_rx_copy_to_iter,		"rx_copy_to_iter") \
> +	EM(smb_eio_trace_rx_insuff_res,			"rx_insuff_res") \
> +	EM(smb_eio_trace_rx_inv_bcc,			"rx_inv_bcc") \
> +	EM(smb_eio_trace_rx_mid_unready,		"rx_mid_unready") \
> +	EM(smb_eio_trace_rx_neg_sess_resp,		"rx_neg_sess_resp") \
> +	EM(smb_eio_trace_rx_overlong,			"rx_overlong") \
> +	EM(smb_eio_trace_rx_overpage,			"rx_overpage") \
> +	EM(smb_eio_trace_rx_pos_sess_resp,		"rx_pos_sess_resp") \
> +	EM(smb_eio_trace_rx_rfc1002_magic,		"rx_rfc1002_magic") \
> +	EM(smb_eio_trace_rx_sync_mid_invalid,		"rx_sync_mid_invalid") \
> +	EM(smb_eio_trace_rx_sync_mid_malformed,		"rx_sync_mid_malformed") \
> +	EM(smb_eio_trace_rx_too_short,			"rx_too_short") \
> +	EM(smb_eio_trace_rx_trans2_extract,		"rx_trans2_extract") \
> +	EM(smb_eio_trace_rx_unknown_resp,		"rx_unknown_resp") \
> +	EM(smb_eio_trace_rx_unspec_error,		"rx_unspec_error") \
> +	EM(smb_eio_trace_sess_buf_off,			"sess_buf_off") \
> +	EM(smb_eio_trace_sess_exiting,			"sess_exiting") \
> +	EM(smb_eio_trace_sess_krb_wcc,			"sess_krb_wcc") \
> +	EM(smb_eio_trace_sess_nl2_wcc,			"sess_nl2_wcc") \
> +	EM(smb_eio_trace_sess_rawnl_auth_wcc,		"sess_rawnl_auth_wcc") \
> +	EM(smb_eio_trace_sess_rawnl_neg_wcc,		"sess_rawnl_neg_wcc") \
> +	EM(smb_eio_trace_short_symlink_write,		"short_symlink_write") \
> +	EM(smb_eio_trace_sid_too_many_auth,		"sid_too_many_auth") \
> +	EM(smb_eio_trace_sig_data_too_small,		"sig_data_too_small") \
> +	EM(smb_eio_trace_sig_iter,			"sig_iter") \
> +	EM(smb_eio_trace_smb1_received_error,		"smb1_received_error") \
> +	EM(smb_eio_trace_smb2_received_error,		"smb2_received_error") \
> +	EM(smb_eio_trace_sym_slash,			"sym_slash") \
> +	EM(smb_eio_trace_sym_target_len,		"sym_target_len") \
> +	EM(smb_eio_trace_symlink_file_size,		"symlink_file_size") \
> +	EM(smb_eio_trace_tdis_in_reconnect,		"tdis_in_reconnect") \
> +	EM(smb_eio_trace_tx_chained_async,		"tx_chained_async") \
> +	EM(smb_eio_trace_tx_compress_failed,		"tx_compress_failed") \
> +	EM(smb_eio_trace_tx_copy_iter_to_buf,		"tx_copy_iter_to_buf") \
> +	EM(smb_eio_trace_tx_copy_to_buf,		"tx_copy_to_buf") \
> +	EM(smb_eio_trace_tx_max_compound,		"tx_max_compound") \
> +	EM(smb_eio_trace_tx_miscopy_to_buf,		"tx_miscopy_to_buf") \
> +	EM(smb_eio_trace_tx_need_transform,		"tx_need_transform") \
> +	EM(smb_eio_trace_tx_too_long,			"sr_too_long") \
> +	EM(smb_eio_trace_unixqfileinfo_bcc_too_small,	"unixqfileinfo_bcc_too_small") \
> +	EM(smb_eio_trace_unixqpathinfo_bcc_too_small,	"unixqpathinfo_bcc_too_small") \
> +	EM(smb_eio_trace_user_iter,			"user_iter") \
> +	EM(smb_eio_trace_write_bad_buf_type,		"write_bad_buf_type") \
> +	EM(smb_eio_trace_write_mid_state_unknown,	"write_mid_state_unknown") \
> +	EM(smb_eio_trace_write_rsp_malformed,		"write_rsp_malformed") \
> +	E_(smb_eio_trace_write_too_far,			"write_too_far")
> +
>   #define smb3_rw_credits_traces \
>   	EM(cifs_trace_rw_credits_call_readv_adjust,	"rd-call-adj") \
>   	EM(cifs_trace_rw_credits_call_writev_adjust,	"wr-call-adj") \
> @@ -79,6 +213,7 @@
>   #define EM(a, b) a,
>   #define E_(a, b) a
>   
> +enum smb_eio_trace		{ smb_eio_traces } __mode(byte);
>   enum smb3_rw_credits_trace	{ smb3_rw_credits_traces } __mode(byte);
>   enum smb3_tcon_ref_trace	{ smb3_tcon_ref_traces } __mode(byte);
>   
> @@ -92,6 +227,7 @@ enum smb3_tcon_ref_trace	{ smb3_tcon_ref_traces } __mode(byte);
>   #define EM(a, b) TRACE_DEFINE_ENUM(a);
>   #define E_(a, b) TRACE_DEFINE_ENUM(a);
>   
> +smb_eio_traces;
>   smb3_rw_credits_traces;
>   smb3_tcon_ref_traces;
>   
> @@ -1616,6 +1752,23 @@ TRACE_EVENT(smb3_rw_credits,
>   		      __entry->server_credits, __entry->in_flight)
>   	    );
>   
> +TRACE_EVENT(smb3_eio,
> +	    TP_PROTO(enum smb_eio_trace trace, unsigned long info, unsigned long info2),
> +	    TP_ARGS(trace, info, info2),
> +	    TP_STRUCT__entry(
> +		    __field(enum smb_eio_trace,	trace)
> +		    __field(unsigned long,	info)
> +		    __field(unsigned long,	info2)
> +			     ),
> +	    TP_fast_assign(
> +		    __entry->trace	= trace;
> +		    __entry->info	= info;
> +		    __entry->info2	= info2;
> +			   ),
> +	    TP_printk("%s info=%lx,%lx",
> +		      __print_symbolic(__entry->trace, smb_eio_traces),
> +		      __entry->info, __entry->info2)
> +	    );
>   
>   #undef EM
>   #undef E_
> diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
> index 362c5c6c91a4..47bfa5bef4e5 100644
> --- a/fs/smb/client/transport.c
> +++ b/fs/smb/client/transport.c
> @@ -402,11 +402,11 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
>   		return __smb_send_rqst(server, num_rqst, rqst);
>   
>   	if (WARN_ON_ONCE(num_rqst > MAX_COMPOUND - 1))
> -		return -EIO;
> +		return smb_EIO1(smb_eio_trace_tx_max_compound, num_rqst);
>   
>   	if (!server->ops->init_transform_rq) {
>   		cifs_server_dbg(VFS, "Encryption requested but transform callback is missing\n");
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_tx_need_transform);
>   	}
>   
>   	new_rqst[0].rq_iov = &iov;
> @@ -753,7 +753,7 @@ int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server
>   		rc = -EAGAIN;
>   		break;
>   	case MID_RESPONSE_MALFORMED:
> -		rc = -EIO;
> +		rc = smb_EIO(smb_eio_trace_rx_sync_mid_malformed);
>   		break;
>   	case MID_SHUTDOWN:
>   		rc = -EHOSTDOWN;
> @@ -769,7 +769,7 @@ int cifs_sync_mid_result(struct smb_message *smb, struct TCP_Server_Info *server
>   		spin_unlock(&server->mid_queue_lock);
>   		cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
>   			 __func__, smb->mid, smb->mid_state);
> -		rc = -EIO;
> +		rc = smb_EIO1(smb_eio_trace_rx_sync_mid_invalid, smb->mid_state);
>   		goto sync_mid_done;
>   	}
>   	spin_unlock(&server->mid_queue_lock);
> @@ -883,7 +883,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
>   
>   	if (!ses || !ses->server || !server) {
>   		cifs_dbg(VFS, "Null session\n");
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_null_pointers);
>   	}
>   
>   	spin_lock(&server->srv_lock);
> @@ -1040,7 +1040,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
>   
>   		if (!smb[i]->resp_buf ||
>   		    smb[i]->mid_state != MID_RESPONSE_READY) {
> -			rc = -EIO;
> +			rc = smb_EIO1(smb_eio_trace_rx_mid_unready, smb[i]->mid_state);
>   			cifs_dbg(FYI, "Bad MID state?\n");
>   			goto out;
>   		}
> @@ -1212,7 +1212,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
>   		cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
>   			 __func__, server->total_read,
>   			 server->vals->read_rsp_size);
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO2(smb_eio_trace_read_rsp_short,
> +					 server->total_read, server->vals->read_rsp_size);
>   		return cifs_readv_discard(server, smb);
>   	}
>   
> @@ -1230,7 +1231,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
>   		/* data_offset is beyond the end of smallbuf */
>   		cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
>   			 __func__, data_offset);
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO1(smb_eio_trace_read_overlarge,
> +					 data_offset);
>   		return cifs_readv_discard(server, smb);
>   	}
>   
> @@ -1254,7 +1256,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct smb_message *smb)
>   	data_len = server->ops->read_data_length(buf, use_rdma_mr);
>   	if (!use_rdma_mr && (data_offset + data_len > buflen)) {
>   		/* data_len is corrupt -- discard frame */
> -		rdata->result = -EIO;
> +		rdata->result = smb_EIO2(smb_eio_trace_read_rsp_malformed,
> +					 data_offset + data_len, buflen);
>   		return cifs_readv_discard(server, smb);
>   	}
>   
> diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c
> index 029910d56c22..6bc89c59164a 100644
> --- a/fs/smb/client/xattr.c
> +++ b/fs/smb/client/xattr.c
> @@ -397,7 +397,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
>   	void *page;
>   
>   	if (unlikely(cifs_forced_shutdown(cifs_sb)))
> -		return -EIO;
> +		return smb_EIO(smb_eio_trace_forced_shutdown);
>   
>   	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
>   		return -EOPNOTSUPP;
> 


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 12:42 ` [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002 David Howells
  2025-11-24 14:20   ` Stefan Metzmacher
@ 2025-11-24 14:36   ` David Howells
  2025-11-24 14:40     ` Stefan Metzmacher
  2025-11-24 14:44     ` David Howells
  1 sibling, 2 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 14:36 UTC (permalink / raw)
  To: Stefan Metzmacher
  Cc: dhowells, Steve French, Paulo Alcantara, Shyam Prasad N,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Hi Stefan,

Stefan Metzmacher <metze@samba.org> wrote:

> I had to squash this into the patch
> 
> I'm using smatch when building and got the following error
> with this change:
> 
>     client/transport.c:1073 compound_send_recv() error: we previously assumed 'resp_iov' could be null (see line 1051)
> ...
>  	if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {

In this case smatch is wrong, though it can't work this out as the context
spans more than one file.  This clause applies only to certain operations
(such as session setup and negotiate) that will always have a response buffer.
But I've no objection to adding this warning to splat the warning.

> > +		if (resp_iov) {
> 
> Is it really possible that resp_iov is NULL here?
> 
> I guess it is for things with CIFS_NO_RSP_BUF, correct?

It probably can't be NULL; even those things that provide CIFS_NO_RSP_BUF seem
to pass a resp_iov, though they tend not to actually initialise it.
Hopefully, this will go away in future and stuff will be attached to the
smb_message struct which will be allocated and passed down from the likes of
smb2pdu.c or cifssmb.c to transport.c.

David


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors
  2025-11-24 12:42 ` [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors David Howells
  2025-11-24 14:22   ` Stefan Metzmacher
@ 2025-11-24 14:38   ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 14:38 UTC (permalink / raw)
  To: Stefan Metzmacher
  Cc: dhowells, Steve French, Paulo Alcantara, Shyam Prasad N,
	linux-cifs, netfs, linux-fsdevel, linux-kernel

Stefan Metzmacher <metze@samba.org> wrote:

> would you mind if we remove all smbdirect.c changes from this patch,
> as my changes I'm currently rebasing on this would remove them again
> anyway.

Sure.

David


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 14:36   ` David Howells
@ 2025-11-24 14:40     ` Stefan Metzmacher
  2025-11-24 14:44     ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: Stefan Metzmacher @ 2025-11-24 14:40 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, Paulo Alcantara, Shyam Prasad N, linux-cifs, netfs,
	linux-fsdevel, linux-kernel, Tom Talpey

Am 24.11.25 um 15:36 schrieb David Howells:
> Hi Stefan,
> 
> Stefan Metzmacher <metze@samba.org> wrote:
> 
>> I had to squash this into the patch
>>
>> I'm using smatch when building and got the following error
>> with this change:
>>
>>      client/transport.c:1073 compound_send_recv() error: we previously assumed 'resp_iov' could be null (see line 1051)
>> ...
>>   	if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) {
> 
> In this case smatch is wrong, though it can't work this out as the context
> spans more than one file.  This clause applies only to certain operations
> (such as session setup and negotiate) that will always have a response buffer.
> But I've no objection to adding this warning to splat the warning.

Ok, I can just squash as well as the EIO changes below my branch
I'll hopefully be able to post later today or tomorrow.

My idea would be that my branch would replace ksmbd-for-next
and add your any my changes on top.

Thanks!
metze

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 14:36   ` David Howells
  2025-11-24 14:40     ` Stefan Metzmacher
@ 2025-11-24 14:44     ` David Howells
  2025-11-24 14:46       ` Stefan Metzmacher
  2025-11-25 11:11       ` David Howells
  1 sibling, 2 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 14:44 UTC (permalink / raw)
  To: Stefan Metzmacher
  Cc: dhowells, Steve French, Paulo Alcantara, Shyam Prasad N,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Stefan Metzmacher <metze@samba.org> wrote:

> Ok, I can just squash as well as the EIO changes below my branch
> I'll hopefully be able to post later today or tomorrow.
> 
> My idea would be that my branch would replace ksmbd-for-next
> and add your any my changes on top.

I've merged in your requested changes and repushed my branch.

David


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 14:44     ` David Howells
@ 2025-11-24 14:46       ` Stefan Metzmacher
  2025-11-25 11:11       ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: Stefan Metzmacher @ 2025-11-24 14:46 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, Paulo Alcantara, Shyam Prasad N, linux-cifs, netfs,
	linux-fsdevel, linux-kernel, Tom Talpey

Am 24.11.25 um 15:44 schrieb David Howells:
> Stefan Metzmacher <metze@samba.org> wrote:
> 
>> Ok, I can just squash as well as the EIO changes below my branch
>> I'll hopefully be able to post later today or tomorrow.
>>
>> My idea would be that my branch would replace ksmbd-for-next
>> and add your any my changes on top.
> 
> I've merged in your requested changes and repushed my branch.

Great thanks!
metze

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr
  2025-11-24 12:42 ` [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr David Howells
@ 2025-11-24 17:27   ` Tom Talpey
  2025-11-24 19:56   ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: Tom Talpey @ 2025-11-24 17:27 UTC (permalink / raw)
  To: David Howells, Steve French
  Cc: Paulo Alcantara, Shyam Prasad N, Stefan Metzmacher, linux-cifs,
	netfs, linux-fsdevel, linux-kernel

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@talpey.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@redhat.com>
> cc: Steve French <sfrench@samba.org>
> cc: Paulo Alcantara <pc@manguebit.org>
> cc: Shyam Prasad N <sprasad@microsoft.com>
> cc: Tom Talpey <tom@talpey.com>
> cc: linux-cifs@vger.kernel.org
> cc: netfs@lists.linux.dev
> cc: linux-fsdevel@vger.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;
> 
> 


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr
  2025-11-24 12:42 ` [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr David Howells
  2025-11-24 17:27   ` Tom Talpey
@ 2025-11-24 19:56   ` David Howells
  1 sibling, 0 replies; 23+ messages in thread
From: David Howells @ 2025-11-24 19:56 UTC (permalink / raw)
  To: Tom Talpey
  Cc: dhowells, Steve French, Paulo Alcantara, Shyam Prasad N,
	Stefan Metzmacher, linux-cifs, netfs, linux-fsdevel, linux-kernel

Tom Talpey <tom@talpey.com> wrote:

> 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.

SMB2/3 doesn't have the RFC1002 headers included in struct smb2_hdr,
presumably because of the compound chaining, so nothing needed doing in that
respect.  This harmonises SMB1 with SMB2/3.

> And, are similar changes envisioned in the ksmbd code?

None required AFAIK as that doesn't support SMB1?

David


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-24 14:44     ` David Howells
  2025-11-24 14:46       ` Stefan Metzmacher
@ 2025-11-25 11:11       ` David Howells
  2025-11-25 11:19         ` Stefan Metzmacher
  1 sibling, 1 reply; 23+ messages in thread
From: David Howells @ 2025-11-25 11:11 UTC (permalink / raw)
  To: Stefan Metzmacher
  Cc: dhowells, Steve French, Paulo Alcantara, Shyam Prasad N,
	linux-cifs, netfs, linux-fsdevel, linux-kernel, Tom Talpey

Hi Metze,

Do you want me to repost my patches so you can associate URLs with them?

David


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002
  2025-11-25 11:11       ` David Howells
@ 2025-11-25 11:19         ` Stefan Metzmacher
  0 siblings, 0 replies; 23+ messages in thread
From: Stefan Metzmacher @ 2025-11-25 11:19 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, Paulo Alcantara, Shyam Prasad N, linux-cifs, netfs,
	linux-fsdevel, linux-kernel, Tom Talpey

Hi David,

> Do you want me to repost my patches so you can associate URLs with them?

I don't need that, I'm just rebasing on your branch now.

I don't know what Steve needs in order to put it into ksmbd-for-next
and what review tags from Tom he should add.

Steve feel free to add 'Acked-by: Stefan Metzmacher <metze@samba.org>'

Thanks!
metze

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2025-11-25 11:19 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-24 12:42 [PATCH v4 00/11] cifs: Miscellaneous prep patches for rewrite of I/O layer David Howells
2025-11-24 12:42 ` [PATCH v4 01/11] cifs: Use netfs_alloc/free_folioq_buffer() David Howells
2025-11-24 12:42 ` [PATCH v4 02/11] cifs: Do some preparation prior to organising the function declarations David Howells
2025-11-24 12:42 ` [PATCH v4 03/11] cifs: Clean up declarations David Howells
2025-11-24 12:42 ` [PATCH v4 04/11] cifs: Rename mid_q_entry to smb_message David Howells
2025-11-24 12:42 ` [PATCH v4 05/11] cifs: Remove the RFC1002 header from smb_hdr David Howells
2025-11-24 17:27   ` Tom Talpey
2025-11-24 19:56   ` David Howells
2025-11-24 12:42 ` [PATCH v4 06/11] cifs: Make smb1's SendReceive() wrap cifs_send_recv() David Howells
2025-11-24 12:42 ` [PATCH v4 07/11] cifs: Clean up some places where an extra kvec[] was required for rfc1002 David Howells
2025-11-24 14:20   ` Stefan Metzmacher
2025-11-24 14:36   ` David Howells
2025-11-24 14:40     ` Stefan Metzmacher
2025-11-24 14:44     ` David Howells
2025-11-24 14:46       ` Stefan Metzmacher
2025-11-25 11:11       ` David Howells
2025-11-25 11:19         ` Stefan Metzmacher
2025-11-24 12:42 ` [PATCH v4 08/11] cifs: Replace SendReceiveBlockingLock() with SendReceive() plus flags David Howells
2025-11-24 12:42 ` [PATCH v4 09/11] cifs: Remove the server pointer from smb_message David Howells
2025-11-24 12:42 ` [PATCH v4 10/11] cifs: Don't need state locking in smb2_get_mid_entry() David Howells
2025-11-24 12:42 ` [PATCH v4 11/11] cifs: Add a tracepoint to log EIO errors David Howells
2025-11-24 14:22   ` Stefan Metzmacher
2025-11-24 14:38   ` David Howells

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).