linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/42] Update NFSD XDR functions
@ 2021-01-05 15:29 Chuck Lever
  2021-01-05 15:29 ` [PATCH v1 01/42] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
                   ` (43 more replies)
  0 siblings, 44 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:29 UTC (permalink / raw)
  To: linux-nfs

The long-term purpose is to convert the NFSD XDR encoder and decoder
functions to use the struct xdr_stream API. This is a refactor and
clean-up with few or no changes in behavior expected, but there are
some long-term benefits:

- More robust input sanitization in the NFSD decoders.
- Help make it possible to use common kernel library functions with
  XDR stream APIs (for example, GSS-API).
- Align the structure of the source code with the RFCs so it is
  easier to learn, verify, and maintain our XDR implementation.
- Removal of more than a hundred hidden dprintk() call sites.
- Removal of as much explicit manipulation of pages as possible to
  help make the eventual transition to xdr->bvecs smoother.

The current series focuses on NFSv2 and NFSv3 decoder changes. Please
review and comment!

The full set of patches lives in a topic branch in my git repo:

 git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-xdr_stream


---

Chuck Lever (42):
      SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
      SUNRPC: Display RPC procedure names instead of proc numbers
      SUNRPC: Move definition of XDR_UNIT
      NFSD: Update GETATTR3args decoder to use struct xdr_stream
      NFSD: Update ACCESS3arg decoder to use struct xdr_stream
      NFSD: Update READ3arg decoder to use struct xdr_stream
      NFSD: Update WRITE3arg decoder to use struct xdr_stream
      NFSD: Update READLINK3arg decoder to use struct xdr_stream
      NFSD: Fix returned READDIR offset cookie
      NFSD: Add helper to set up the pages where the dirlist is encoded
      NFSD: Update READDIR3args decoders to use struct xdr_stream
      NFSD: Update COMMIT3arg decoder to use struct xdr_stream
      NFSD: Update the NFSv3 DIROPargs decoder to use struct xdr_stream
      NFSD: Update the RENAME3args decoder to use struct xdr_stream
      NFSD: Update the LINK3args decoder to use struct xdr_stream
      NFSD: Update the SETATTR3args decoder to use struct xdr_stream
      NFSD: Update the CREATE3args decoder to use struct xdr_stream
      NFSD: Update the MKDIR3args decoder to use struct xdr_stream
      NFSD: Update the SYMLINK3args decoder to use struct xdr_stream
      NFSD: Update the MKNOD3args decoder to use struct xdr_stream
      NFSD: Update the NFSv2 GETATTR argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 READ argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 WRITE argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 READLINK argument decoder to use struct xdr_stream
      NFSD: Add helper to set up the pages where the dirlist is encoded
      NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream
      NFSD: Update NFSv2 diropargs decoding to use struct xdr_stream
      NFSD: Update the NFSv2 RENAME argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 LINK argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 SETATTR argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 CREATE argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 SYMLINK argument decoder to use struct xdr_stream
      NFSD: Remove argument length checking in nfsd_dispatch()
      NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream
      NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs
      NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 ACL GETATTR argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 ACL ACCESS argument decoder to use struct xdr_stream
      NFSD: Clean up after updating NFSv2 ACL decoders
      NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream
      NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
      NFSD: Clean up after updating NFSv3 ACL decoders


 fs/nfs_common/nfsacl.c          |  52 +++
 fs/nfsd/nfs2acl.c               |  62 ++--
 fs/nfsd/nfs3acl.c               |  42 ++-
 fs/nfsd/nfs3proc.c              |  71 +++--
 fs/nfsd/nfs3xdr.c               | 538 ++++++++++++++++++--------------
 fs/nfsd/nfsproc.c               |  74 +++--
 fs/nfsd/nfssvc.c                |  34 --
 fs/nfsd/nfsxdr.c                | 350 ++++++++++-----------
 fs/nfsd/xdr.h                   |  12 +-
 fs/nfsd/xdr3.h                  |  20 +-
 include/linux/nfsacl.h          |   3 +
 include/linux/sunrpc/msg_prot.h |   3 -
 include/linux/sunrpc/xdr.h      |  13 +-
 include/trace/events/sunrpc.h   |  15 +-
 include/uapi/linux/nfs3.h       |   6 +
 15 files changed, 680 insertions(+), 615 deletions(-)

--
Chuck Lever


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

* [PATCH v1 01/42] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
@ 2021-01-05 15:29 ` Chuck Lever
  2021-01-05 15:29 ` [PATCH v1 02/42] SUNRPC: Display RPC procedure names instead of proc numbers Chuck Lever
                   ` (42 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:29 UTC (permalink / raw)
  To: linux-nfs

The next few patches will employ these strings to help make server-
side trace logs more human-readable. A similar technique is already
in use in kernel RPC client code.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/lockd/svc4proc.c        |   24 ++++++++++++++++++++++++
 fs/lockd/svcproc.c         |   24 ++++++++++++++++++++++++
 fs/nfs/callback_xdr.c      |    2 ++
 fs/nfsd/nfs2acl.c          |    5 +++++
 fs/nfsd/nfs3acl.c          |    3 +++
 fs/nfsd/nfs3proc.c         |   22 ++++++++++++++++++++++
 fs/nfsd/nfs4proc.c         |    2 ++
 fs/nfsd/nfsproc.c          |   18 ++++++++++++++++++
 include/linux/sunrpc/svc.h |    1 +
 9 files changed, 101 insertions(+)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index fa41dda39925..4c10fb5138f1 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -512,6 +512,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "NULL",
 	},
 	[NLMPROC_TEST] = {
 		.pc_func = nlm4svc_proc_test,
@@ -520,6 +521,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+2+No+Rg,
+		.pc_name = "TEST",
 	},
 	[NLMPROC_LOCK] = {
 		.pc_func = nlm4svc_proc_lock,
@@ -528,6 +530,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "LOCK",
 	},
 	[NLMPROC_CANCEL] = {
 		.pc_func = nlm4svc_proc_cancel,
@@ -536,6 +539,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "CANCEL",
 	},
 	[NLMPROC_UNLOCK] = {
 		.pc_func = nlm4svc_proc_unlock,
@@ -544,6 +548,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "UNLOCK",
 	},
 	[NLMPROC_GRANTED] = {
 		.pc_func = nlm4svc_proc_granted,
@@ -552,6 +557,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "GRANTED",
 	},
 	[NLMPROC_TEST_MSG] = {
 		.pc_func = nlm4svc_proc_test_msg,
@@ -560,6 +566,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_MSG",
 	},
 	[NLMPROC_LOCK_MSG] = {
 		.pc_func = nlm4svc_proc_lock_msg,
@@ -568,6 +575,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_MSG",
 	},
 	[NLMPROC_CANCEL_MSG] = {
 		.pc_func = nlm4svc_proc_cancel_msg,
@@ -576,6 +584,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_MSG",
 	},
 	[NLMPROC_UNLOCK_MSG] = {
 		.pc_func = nlm4svc_proc_unlock_msg,
@@ -584,6 +593,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_MSG",
 	},
 	[NLMPROC_GRANTED_MSG] = {
 		.pc_func = nlm4svc_proc_granted_msg,
@@ -592,6 +602,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_MSG",
 	},
 	[NLMPROC_TEST_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -600,6 +611,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_RES",
 	},
 	[NLMPROC_LOCK_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -608,6 +620,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_RES",
 	},
 	[NLMPROC_CANCEL_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -616,6 +629,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_RES",
 	},
 	[NLMPROC_UNLOCK_RES] = {
 		.pc_func = nlm4svc_proc_null,
@@ -624,6 +638,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_RES",
 	},
 	[NLMPROC_GRANTED_RES] = {
 		.pc_func = nlm4svc_proc_granted_res,
@@ -632,6 +647,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_RES",
 	},
 	[NLMPROC_NSM_NOTIFY] = {
 		.pc_func = nlm4svc_proc_sm_notify,
@@ -640,6 +656,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_reboot),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "SM_NOTIFY",
 	},
 	[17] = {
 		.pc_func = nlm4svc_proc_unused,
@@ -648,6 +665,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = 0,
+		.pc_name = "UNUSED",
 	},
 	[18] = {
 		.pc_func = nlm4svc_proc_unused,
@@ -656,6 +674,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = 0,
+		.pc_name = "UNUSED",
 	},
 	[19] = {
 		.pc_func = nlm4svc_proc_unused,
@@ -664,6 +683,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = 0,
+		.pc_name = "UNUSED",
 	},
 	[NLMPROC_SHARE] = {
 		.pc_func = nlm4svc_proc_share,
@@ -672,6 +692,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "SHARE",
 	},
 	[NLMPROC_UNSHARE] = {
 		.pc_func = nlm4svc_proc_unshare,
@@ -680,6 +701,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "UNSHARE",
 	},
 	[NLMPROC_NM_LOCK] = {
 		.pc_func = nlm4svc_proc_nm_lock,
@@ -688,6 +710,7 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "NM_LOCK",
 	},
 	[NLMPROC_FREE_ALL] = {
 		.pc_func = nlm4svc_proc_free_all,
@@ -696,5 +719,6 @@ const struct svc_procedure nlmsvc_procedures4[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "FREE_ALL",
 	},
 };
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 50855f2c1f4b..4ae4b63b5392 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -554,6 +554,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "NULL",
 	},
 	[NLMPROC_TEST] = {
 		.pc_func = nlmsvc_proc_test,
@@ -562,6 +563,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+2+No+Rg,
+		.pc_name = "TEST",
 	},
 	[NLMPROC_LOCK] = {
 		.pc_func = nlmsvc_proc_lock,
@@ -570,6 +572,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "LOCK",
 	},
 	[NLMPROC_CANCEL] = {
 		.pc_func = nlmsvc_proc_cancel,
@@ -578,6 +581,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "CANCEL",
 	},
 	[NLMPROC_UNLOCK] = {
 		.pc_func = nlmsvc_proc_unlock,
@@ -586,6 +590,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "UNLOCK",
 	},
 	[NLMPROC_GRANTED] = {
 		.pc_func = nlmsvc_proc_granted,
@@ -594,6 +599,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "GRANTED",
 	},
 	[NLMPROC_TEST_MSG] = {
 		.pc_func = nlmsvc_proc_test_msg,
@@ -602,6 +608,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_MSG",
 	},
 	[NLMPROC_LOCK_MSG] = {
 		.pc_func = nlmsvc_proc_lock_msg,
@@ -610,6 +617,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_MSG",
 	},
 	[NLMPROC_CANCEL_MSG] = {
 		.pc_func = nlmsvc_proc_cancel_msg,
@@ -618,6 +626,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_MSG",
 	},
 	[NLMPROC_UNLOCK_MSG] = {
 		.pc_func = nlmsvc_proc_unlock_msg,
@@ -626,6 +635,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_MSG",
 	},
 	[NLMPROC_GRANTED_MSG] = {
 		.pc_func = nlmsvc_proc_granted_msg,
@@ -634,6 +644,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_MSG",
 	},
 	[NLMPROC_TEST_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -642,6 +653,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "TEST_RES",
 	},
 	[NLMPROC_LOCK_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -650,6 +662,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "LOCK_RES",
 	},
 	[NLMPROC_CANCEL_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -658,6 +671,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "CANCEL_RES",
 	},
 	[NLMPROC_UNLOCK_RES] = {
 		.pc_func = nlmsvc_proc_null,
@@ -666,6 +680,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNLOCK_RES",
 	},
 	[NLMPROC_GRANTED_RES] = {
 		.pc_func = nlmsvc_proc_granted_res,
@@ -674,6 +689,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_res),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "GRANTED_RES",
 	},
 	[NLMPROC_NSM_NOTIFY] = {
 		.pc_func = nlmsvc_proc_sm_notify,
@@ -682,6 +698,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_reboot),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "SM_NOTIFY",
 	},
 	[17] = {
 		.pc_func = nlmsvc_proc_unused,
@@ -690,6 +707,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNUSED",
 	},
 	[18] = {
 		.pc_func = nlmsvc_proc_unused,
@@ -698,6 +716,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNUSED",
 	},
 	[19] = {
 		.pc_func = nlmsvc_proc_unused,
@@ -706,6 +725,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_void),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = St,
+		.pc_name = "UNUSED",
 	},
 	[NLMPROC_SHARE] = {
 		.pc_func = nlmsvc_proc_share,
@@ -714,6 +734,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "SHARE",
 	},
 	[NLMPROC_UNSHARE] = {
 		.pc_func = nlmsvc_proc_unshare,
@@ -722,6 +743,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St+1,
+		.pc_name = "UNSHARE",
 	},
 	[NLMPROC_NM_LOCK] = {
 		.pc_func = nlmsvc_proc_nm_lock,
@@ -730,6 +752,7 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_res),
 		.pc_xdrressize = Ck+St,
+		.pc_name = "NM_LOCK",
 	},
 	[NLMPROC_FREE_ALL] = {
 		.pc_func = nlmsvc_proc_free_all,
@@ -738,5 +761,6 @@ const struct svc_procedure nlmsvc_procedures[24] = {
 		.pc_argsize = sizeof(struct nlm_args),
 		.pc_ressize = sizeof(struct nlm_void),
 		.pc_xdrressize = 0,
+		.pc_name = "FREE_ALL",
 	},
 };
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 79ff172eb1c8..c5348ba81129 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -1060,6 +1060,7 @@ static const struct svc_procedure nfs4_callback_procedures1[] = {
 		.pc_decode = nfs4_decode_void,
 		.pc_encode = nfs4_encode_void,
 		.pc_xdrressize = 1,
+		.pc_name = "NULL",
 	},
 	[CB_COMPOUND] = {
 		.pc_func = nfs4_callback_compound,
@@ -1067,6 +1068,7 @@ static const struct svc_procedure nfs4_callback_procedures1[] = {
 		.pc_argsize = 256,
 		.pc_ressize = 256,
 		.pc_xdrressize = NFS4_CALLBACK_BUFSIZE,
+		.pc_name = "COMPOUND",
 	}
 };
 
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index b0f66604532a..899762da23c9 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -371,6 +371,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[ACLPROC2_GETACL] = {
 		.pc_func = nfsacld_proc_getacl,
@@ -381,6 +382,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd3_getaclres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+2*(1+ACL),
+		.pc_name = "GETACL",
 	},
 	[ACLPROC2_SETACL] = {
 		.pc_func = nfsacld_proc_setacl,
@@ -391,6 +393,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "SETACL",
 	},
 	[ACLPROC2_GETATTR] = {
 		.pc_func = nfsacld_proc_getattr,
@@ -401,6 +404,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "GETATTR",
 	},
 	[ACLPROC2_ACCESS] = {
 		.pc_func = nfsacld_proc_access,
@@ -411,6 +415,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_ressize = sizeof(struct nfsd3_accessres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT+1,
+		.pc_name = "SETATTR",
 	},
 };
 
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 7c30876a31a1..9e1a92fb9771 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -251,6 +251,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[ACLPROC3_GETACL] = {
 		.pc_func = nfsd3_proc_getacl,
@@ -261,6 +262,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = {
 		.pc_ressize = sizeof(struct nfsd3_getaclres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+2*(1+ACL),
+		.pc_name = "GETACL",
 	},
 	[ACLPROC3_SETACL] = {
 		.pc_func = nfsd3_proc_setacl,
@@ -271,6 +273,7 @@ static const struct svc_procedure nfsd_acl_procedures3[3] = {
 		.pc_ressize = sizeof(struct nfsd3_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT,
+		.pc_name = "SETACL",
 	},
 };
 
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 76931f4f57c3..c9c64471c568 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -708,6 +708,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
+		.pc_name = "NULL",
 	},
 	[NFS3PROC_GETATTR] = {
 		.pc_func = nfsd3_proc_getattr,
@@ -718,6 +719,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_attrstatres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "GETATTR",
 	},
 	[NFS3PROC_SETATTR] = {
 		.pc_func = nfsd3_proc_setattr,
@@ -728,6 +730,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_wccstatres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC,
+		.pc_name = "SETATTR",
 	},
 	[NFS3PROC_LOOKUP] = {
 		.pc_func = nfsd3_proc_lookup,
@@ -738,6 +741,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_diropres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+FH+pAT+pAT,
+		.pc_name = "LOOKUP",
 	},
 	[NFS3PROC_ACCESS] = {
 		.pc_func = nfsd3_proc_access,
@@ -748,6 +752,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_accessres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+1,
+		.pc_name = "ACCESS",
 	},
 	[NFS3PROC_READLINK] = {
 		.pc_func = nfsd3_proc_readlink,
@@ -758,6 +763,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_readlinkres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4,
+		.pc_name = "READLINK",
 	},
 	[NFS3PROC_READ] = {
 		.pc_func = nfsd3_proc_read,
@@ -768,6 +774,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_readres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+4+NFSSVC_MAXBLKSIZE/4,
+		.pc_name = "READ",
 	},
 	[NFS3PROC_WRITE] = {
 		.pc_func = nfsd3_proc_write,
@@ -778,6 +785,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_writeres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC+4,
+		.pc_name = "WRITE",
 	},
 	[NFS3PROC_CREATE] = {
 		.pc_func = nfsd3_proc_create,
@@ -788,6 +796,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "CREATE",
 	},
 	[NFS3PROC_MKDIR] = {
 		.pc_func = nfsd3_proc_mkdir,
@@ -798,6 +807,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "MKDIR",
 	},
 	[NFS3PROC_SYMLINK] = {
 		.pc_func = nfsd3_proc_symlink,
@@ -808,6 +818,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "SYMLINK",
 	},
 	[NFS3PROC_MKNOD] = {
 		.pc_func = nfsd3_proc_mknod,
@@ -818,6 +829,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_createres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+(1+FH+pAT)+WC,
+		.pc_name = "MKNOD",
 	},
 	[NFS3PROC_REMOVE] = {
 		.pc_func = nfsd3_proc_remove,
@@ -828,6 +840,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_wccstatres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC,
+		.pc_name = "REMOVE",
 	},
 	[NFS3PROC_RMDIR] = {
 		.pc_func = nfsd3_proc_rmdir,
@@ -838,6 +851,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_wccstatres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC,
+		.pc_name = "RMDIR",
 	},
 	[NFS3PROC_RENAME] = {
 		.pc_func = nfsd3_proc_rename,
@@ -848,6 +862,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_renameres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+WC+WC,
+		.pc_name = "RENAME",
 	},
 	[NFS3PROC_LINK] = {
 		.pc_func = nfsd3_proc_link,
@@ -858,6 +873,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_linkres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+pAT+WC,
+		.pc_name = "LINK",
 	},
 	[NFS3PROC_READDIR] = {
 		.pc_func = nfsd3_proc_readdir,
@@ -867,6 +883,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_argsize = sizeof(struct nfsd3_readdirargs),
 		.pc_ressize = sizeof(struct nfsd3_readdirres),
 		.pc_cachetype = RC_NOCACHE,
+		.pc_name = "READDIR",
 	},
 	[NFS3PROC_READDIRPLUS] = {
 		.pc_func = nfsd3_proc_readdirplus,
@@ -876,6 +893,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_argsize = sizeof(struct nfsd3_readdirplusargs),
 		.pc_ressize = sizeof(struct nfsd3_readdirres),
 		.pc_cachetype = RC_NOCACHE,
+		.pc_name = "READDIRPLUS",
 	},
 	[NFS3PROC_FSSTAT] = {
 		.pc_func = nfsd3_proc_fsstat,
@@ -885,6 +903,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_fsstatres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+2*6+1,
+		.pc_name = "FSSTAT",
 	},
 	[NFS3PROC_FSINFO] = {
 		.pc_func = nfsd3_proc_fsinfo,
@@ -894,6 +913,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_fsinfores),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+12,
+		.pc_name = "FSINFO",
 	},
 	[NFS3PROC_PATHCONF] = {
 		.pc_func = nfsd3_proc_pathconf,
@@ -903,6 +923,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_pathconfres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+6,
+		.pc_name = "PATHCONF",
 	},
 	[NFS3PROC_COMMIT] = {
 		.pc_func = nfsd3_proc_commit,
@@ -913,6 +934,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_ressize = sizeof(struct nfsd3_commitres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+WC+2,
+		.pc_name = "COMMIT",
 	},
 };
 
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 8d6d2678abad..f567592692ee 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -3305,6 +3305,7 @@ static const struct svc_procedure nfsd_procedures4[2] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 1,
+		.pc_name = "NULL",
 	},
 	[NFSPROC4_COMPOUND] = {
 		.pc_func = nfsd4_proc_compound,
@@ -3315,6 +3316,7 @@ static const struct svc_procedure nfsd_procedures4[2] = {
 		.pc_release = nfsd4_release_compoundargs,
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = NFSD_BUFSIZE/4,
+		.pc_name = "COMPOUND",
 	},
 };
 
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 9473d048efec..1f85a4dc9d1b 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -623,6 +623,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
+		.pc_name = "NULL",
 	},
 	[NFSPROC_GETATTR] = {
 		.pc_func = nfsd_proc_getattr,
@@ -633,6 +634,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "GETATTR",
 	},
 	[NFSPROC_SETATTR] = {
 		.pc_func = nfsd_proc_setattr,
@@ -643,6 +645,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "SETATTR",
 	},
 	[NFSPROC_ROOT] = {
 		.pc_func = nfsd_proc_root,
@@ -652,6 +655,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
+		.pc_name = "ROOT",
 	},
 	[NFSPROC_LOOKUP] = {
 		.pc_func = nfsd_proc_lookup,
@@ -662,6 +666,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_diropres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+FH+AT,
+		.pc_name = "LOOKUP",
 	},
 	[NFSPROC_READLINK] = {
 		.pc_func = nfsd_proc_readlink,
@@ -671,6 +676,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_readlinkres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+NFS_MAXPATHLEN/4,
+		.pc_name = "READLINK",
 	},
 	[NFSPROC_READ] = {
 		.pc_func = nfsd_proc_read,
@@ -681,6 +687,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_readres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4,
+		.pc_name = "READ",
 	},
 	[NFSPROC_WRITECACHE] = {
 		.pc_func = nfsd_proc_writecache,
@@ -690,6 +697,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
+		.pc_name = "WRITECACHE",
 	},
 	[NFSPROC_WRITE] = {
 		.pc_func = nfsd_proc_write,
@@ -700,6 +708,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_attrstat),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+AT,
+		.pc_name = "WRITE",
 	},
 	[NFSPROC_CREATE] = {
 		.pc_func = nfsd_proc_create,
@@ -710,6 +719,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_diropres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+FH+AT,
+		.pc_name = "CREATE",
 	},
 	[NFSPROC_REMOVE] = {
 		.pc_func = nfsd_proc_remove,
@@ -719,6 +729,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_stat),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "REMOVE",
 	},
 	[NFSPROC_RENAME] = {
 		.pc_func = nfsd_proc_rename,
@@ -728,6 +739,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_stat),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "RENAME",
 	},
 	[NFSPROC_LINK] = {
 		.pc_func = nfsd_proc_link,
@@ -737,6 +749,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_stat),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "LINK",
 	},
 	[NFSPROC_SYMLINK] = {
 		.pc_func = nfsd_proc_symlink,
@@ -746,6 +759,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_stat),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "SYMLINK",
 	},
 	[NFSPROC_MKDIR] = {
 		.pc_func = nfsd_proc_mkdir,
@@ -756,6 +770,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_diropres),
 		.pc_cachetype = RC_REPLBUFF,
 		.pc_xdrressize = ST+FH+AT,
+		.pc_name = "MKDIR",
 	},
 	[NFSPROC_RMDIR] = {
 		.pc_func = nfsd_proc_rmdir,
@@ -765,6 +780,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_stat),
 		.pc_cachetype = RC_REPLSTAT,
 		.pc_xdrressize = ST,
+		.pc_name = "RMDIR",
 	},
 	[NFSPROC_READDIR] = {
 		.pc_func = nfsd_proc_readdir,
@@ -773,6 +789,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_argsize = sizeof(struct nfsd_readdirargs),
 		.pc_ressize = sizeof(struct nfsd_readdirres),
 		.pc_cachetype = RC_NOCACHE,
+		.pc_name = "READDIR",
 	},
 	[NFSPROC_STATFS] = {
 		.pc_func = nfsd_proc_statfs,
@@ -782,6 +799,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 		.pc_ressize = sizeof(struct nfsd_statfsres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+5,
+		.pc_name = "STATFS",
 	},
 };
 
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 34c2a69820e9..31ee3b6047c3 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -463,6 +463,7 @@ struct svc_procedure {
 	unsigned int		pc_ressize;	/* result struct size */
 	unsigned int		pc_cachetype;	/* cache info (NFS) */
 	unsigned int		pc_xdrressize;	/* maximum size of XDR reply */
+	const char *		pc_name;	/* for display */
 };
 
 /*



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

* [PATCH v1 02/42] SUNRPC: Display RPC procedure names instead of proc numbers
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
  2021-01-05 15:29 ` [PATCH v1 01/42] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
@ 2021-01-05 15:29 ` Chuck Lever
  2021-01-05 15:29 ` [PATCH v1 03/42] SUNRPC: Move definition of XDR_UNIT Chuck Lever
                   ` (41 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:29 UTC (permalink / raw)
  To: linux-nfs

Make the sunrpc trace subsystem trace events easier to use.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 include/trace/events/sunrpc.h |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 58994e013022..562f2bb1e3ff 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -1556,6 +1556,7 @@ TRACE_EVENT(svc_process,
 		__field(u32, vers)
 		__field(u32, proc)
 		__string(service, name)
+		__string(procedure, rqst->rq_procinfo->pc_name)
 		__string(addr, rqst->rq_xprt ?
 			 rqst->rq_xprt->xpt_remotebuf : "(null)")
 	),
@@ -1565,13 +1566,16 @@ TRACE_EVENT(svc_process,
 		__entry->vers = rqst->rq_vers;
 		__entry->proc = rqst->rq_proc;
 		__assign_str(service, name);
+		__assign_str(procedure, rqst->rq_procinfo->pc_name);
 		__assign_str(addr, rqst->rq_xprt ?
 			     rqst->rq_xprt->xpt_remotebuf : "(null)");
 	),
 
-	TP_printk("addr=%s xid=0x%08x service=%s vers=%u proc=%u",
+	TP_printk("addr=%s xid=0x%08x service=%s vers=%u proc=%s",
 			__get_str(addr), __entry->xid,
-			__get_str(service), __entry->vers, __entry->proc)
+			__get_str(service), __entry->vers,
+			__get_str(procedure)
+	)
 );
 
 DECLARE_EVENT_CLASS(svc_rqst_event,
@@ -1827,6 +1831,7 @@ TRACE_EVENT(svc_stats_latency,
 	TP_STRUCT__entry(
 		__field(u32, xid)
 		__field(unsigned long, execute)
+		__string(procedure, rqst->rq_procinfo->pc_name)
 		__string(addr, rqst->rq_xprt->xpt_remotebuf)
 	),
 
@@ -1834,11 +1839,13 @@ TRACE_EVENT(svc_stats_latency,
 		__entry->xid = be32_to_cpu(rqst->rq_xid);
 		__entry->execute = ktime_to_us(ktime_sub(ktime_get(),
 							 rqst->rq_stime));
+		__assign_str(procedure, rqst->rq_procinfo->pc_name);
 		__assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
 	),
 
-	TP_printk("addr=%s xid=0x%08x execute-us=%lu",
-		__get_str(addr), __entry->xid, __entry->execute)
+	TP_printk("addr=%s xid=0x%08x proc=%s execute-us=%lu",
+		__get_str(addr), __entry->xid, __get_str(procedure),
+		__entry->execute)
 );
 
 DECLARE_EVENT_CLASS(svc_deferred_event,



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

* [PATCH v1 03/42] SUNRPC: Move definition of XDR_UNIT
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
  2021-01-05 15:29 ` [PATCH v1 01/42] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
  2021-01-05 15:29 ` [PATCH v1 02/42] SUNRPC: Display RPC procedure names instead of proc numbers Chuck Lever
@ 2021-01-05 15:29 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 04/42] NFSD: Update GETATTR3args decoder to use struct xdr_stream Chuck Lever
                   ` (40 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:29 UTC (permalink / raw)
  To: linux-nfs

Clean up: The unit of XDR alignment is defined by RFC 4506,
not as part of the RPC message header. Thus it belongs in
include/linux/sunrpc/xdr.h.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 include/linux/sunrpc/msg_prot.h |    3 ---
 include/linux/sunrpc/xdr.h      |   13 ++++++++++---
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 43f854487539..938c2bf29db8 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -10,9 +10,6 @@
 
 #define RPC_VERSION 2
 
-/* size of an XDR encoding unit in bytes, i.e. 32bit */
-#define XDR_UNIT	(4)
-
 /* spec defines authentication flavor as an unsigned 32 bit integer */
 typedef u32	rpc_authflavor_t;
 
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 9b35ce50cf2b..8b61ec92366f 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -19,6 +19,13 @@
 struct bio_vec;
 struct rpc_rqst;
 
+/*
+ * Size of an XDR encoding unit in bytes, i.e. 32 bits,
+ * as defined in Section 3 of RFC 4506. All encoded
+ * XDR data items are aligned on a boundary of 32 bits.
+ */
+#define XDR_UNIT		sizeof(__be32)
+
 /*
  * Buffer adjustment
  */
@@ -331,7 +338,7 @@ ssize_t xdr_stream_decode_string_dup(struct xdr_stream *xdr, char **str,
 static inline size_t
 xdr_align_size(size_t n)
 {
-	const size_t mask = sizeof(__u32) - 1;
+	const size_t mask = XDR_UNIT - 1;
 
 	return (n + mask) & ~mask;
 }
@@ -361,7 +368,7 @@ static inline size_t xdr_pad_size(size_t n)
  */
 static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr)
 {
-	const size_t len = sizeof(__be32);
+	const size_t len = XDR_UNIT;
 	__be32 *p = xdr_reserve_space(xdr, len);
 
 	if (unlikely(!p))
@@ -380,7 +387,7 @@ static inline ssize_t xdr_stream_encode_item_present(struct xdr_stream *xdr)
  */
 static inline int xdr_stream_encode_item_absent(struct xdr_stream *xdr)
 {
-	const size_t len = sizeof(__be32);
+	const size_t len = XDR_UNIT;
 	__be32 *p = xdr_reserve_space(xdr, len);
 
 	if (unlikely(!p))



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

* [PATCH v1 04/42] NFSD: Update GETATTR3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (2 preceding siblings ...)
  2021-01-05 15:29 ` [PATCH v1 03/42] SUNRPC: Move definition of XDR_UNIT Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 05/42] NFSD: Update ACCESS3arg " Chuck Lever
                   ` (39 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3proc.c |    3 +--
 fs/nfsd/nfs3xdr.c  |   31 +++++++++++++++++++++++++------
 fs/nfsd/xdr3.h     |    2 +-
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index c9c64471c568..4b66f055141b 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -683,7 +683,6 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
  * NFSv3 Server procedures.
  * Only the results of non-idempotent operations are cached.
  */
-#define nfs3svc_decode_fhandleargs	nfs3svc_decode_fhandle
 #define nfs3svc_encode_attrstatres	nfs3svc_encode_attrstat
 #define nfs3svc_encode_wccstatres	nfs3svc_encode_wccstat
 #define nfsd3_mkdirargs			nfsd3_createargs
@@ -715,7 +714,7 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 		.pc_decode = nfs3svc_decode_fhandleargs,
 		.pc_encode = nfs3svc_encode_attrstatres,
 		.pc_release = nfs3svc_release_fhandle,
-		.pc_argsize = sizeof(struct nfsd3_fhandleargs),
+		.pc_argsize = sizeof(struct nfsd_fhandle),
 		.pc_ressize = sizeof(struct nfsd3_attrstatres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+AT,
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 821db21ba072..01335b0e7c60 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -29,8 +29,9 @@ static u32	nfs3_ftypes[] = {
 
 
 /*
- * XDR functions for basic NFS types
+ * Basic NFSv3 data types (RFC 1813 Sections 2.5 and 2.6)
  */
+
 static __be32 *
 encode_time3(__be32 *p, struct timespec64 *time)
 {
@@ -46,6 +47,26 @@ decode_time3(__be32 *p, struct timespec64 *time)
 	return p;
 }
 
+static bool
+svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
+{
+	__be32 *p;
+	u32 size;
+
+	if (xdr_stream_decode_u32(xdr, &size) < 0)
+		return false;
+	if (size == 0 || size > NFS3_FHSIZE)
+		return false;
+	p = xdr_inline_decode(xdr, size);
+	if (!p)
+		return false;
+	fh_init(fhp, NFS3_FHSIZE);
+	fhp->fh_handle.fh_size = size;
+	memcpy(&fhp->fh_handle.fh_base, p, size);
+
+	return true;
+}
+
 static __be32 *
 decode_fh(__be32 *p, struct svc_fh *fhp)
 {
@@ -312,14 +333,12 @@ void fill_post_wcc(struct svc_fh *fhp)
  */
 
 int
-nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
+nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_fhandle *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_nfs_fh3(xdr, &args->fh);
 }
 
 int
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 456fcd7a1038..62ea669768cf 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -273,7 +273,7 @@ union nfsd3_xdrstore {
 
 #define NFS3_SVC_XDRSIZE		sizeof(union nfsd3_xdrstore)
 
-int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *);
+int nfs3svc_decode_fhandleargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *);



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

* [PATCH v1 05/42] NFSD: Update ACCESS3arg decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (3 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 04/42] NFSD: Update GETATTR3args decoder to use struct xdr_stream Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 06/42] NFSD: Update READ3arg " Chuck Lever
                   ` (38 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |    9 +++++----
 fs/nfsd/xdr3.h    |    2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 01335b0e7c60..ac680f34fcba 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -375,14 +375,15 @@ nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_accessargs *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->access) < 0)
 		return 0;
-	args->access = ntohl(*p++);
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 62ea669768cf..a4dce4baec7c 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -25,7 +25,7 @@ struct nfsd3_diropargs {
 
 struct nfsd3_accessargs {
 	struct svc_fh		fh;
-	unsigned int		access;
+	__u32			access;
 };
 
 struct nfsd3_readargs {



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

* [PATCH v1 06/42] NFSD: Update READ3arg decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (4 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 05/42] NFSD: Update ACCESS3arg " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 07/42] NFSD: Update WRITE3arg " Chuck Lever
                   ` (37 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

The code that sets up rq_vec is refactored so that it is now
adjacent to the nfsd_read() call site where it is used.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3proc.c |   23 ++++++++++++++++++-----
 fs/nfsd/nfs3xdr.c  |   28 +++++++---------------------
 fs/nfsd/xdr3.h     |    1 -
 3 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 4b66f055141b..acdf47179a38 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -144,25 +144,38 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
 {
 	struct nfsd3_readargs *argp = rqstp->rq_argp;
 	struct nfsd3_readres *resp = rqstp->rq_resp;
-	u32	max_blocksize = svc_max_payload(rqstp);
-	unsigned long cnt = min(argp->count, max_blocksize);
+	u32 max_blocksize = svc_max_payload(rqstp);
+	unsigned int len;
+	int v;
+
+	argp->count = min_t(u32, argp->count, max_blocksize);
 
 	dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n",
 				SVCFH_fmt(&argp->fh),
 				(unsigned long) argp->count,
 				(unsigned long long) argp->offset);
 
+	v = 0;
+	len = argp->count;
+	while (len > 0) {
+		struct page *page = *(rqstp->rq_next_page++);
+
+		rqstp->rq_vec[v].iov_base = page_address(page);
+		rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
+		len -= rqstp->rq_vec[v].iov_len;
+		v++;
+	}
+
 	/* Obtain buffer pointer for payload.
 	 * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof)
 	 * + 1 (xdr opaque byte count) = 26
 	 */
-	resp->count = cnt;
+	resp->count = argp->count;
 	svc_reserve_auth(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
 
 	fh_copy(&resp->fh, &argp->fh);
 	resp->status = nfsd_read(rqstp, &resp->fh, argp->offset,
-				 rqstp->rq_vec, argp->vlen, &resp->count,
-				 &resp->eof);
+				 rqstp->rq_vec, v, &resp->count, &resp->eof);
 	return rpc_success;
 }
 
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index ac680f34fcba..ff98eae5db81 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -389,31 +389,17 @@ nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_readargs *args = rqstp->rq_argp;
-	unsigned int len;
-	int v;
-	u32 max_blocksize = svc_max_payload(rqstp);
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
 		return 0;
-	p = xdr_decode_hyper(p, &args->offset);
-
-	args->count = ntohl(*p++);
-	len = min(args->count, max_blocksize);
-
-	/* set up the kvec */
-	v=0;
-	while (len > 0) {
-		struct page *p = *(rqstp->rq_next_page++);
 
-		rqstp->rq_vec[v].iov_base = page_address(p);
-		rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
-		len -= rqstp->rq_vec[v].iov_len;
-		v++;
-	}
-	args->vlen = v;
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index a4dce4baec7c..7dfeeaa4e1df 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -32,7 +32,6 @@ struct nfsd3_readargs {
 	struct svc_fh		fh;
 	__u64			offset;
 	__u32			count;
-	int			vlen;
 };
 
 struct nfsd3_writeargs {



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

* [PATCH v1 07/42] NFSD: Update WRITE3arg decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (5 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 06/42] NFSD: Update READ3arg " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-22 18:47   ` J. Bruce Fields
  2021-01-05 15:30 ` [PATCH v1 08/42] NFSD: Update READLINK3arg " Chuck Lever
                   ` (36 subsequent siblings)
  43 siblings, 1 reply; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

As part of the update, open code that sanity-checks the size of the
data payload against the length of the RPC Call message has to be
re-implemented to use xdr_stream infrastructure.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   51 ++++++++++++++++++++-------------------------------
 1 file changed, 20 insertions(+), 31 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index ff98eae5db81..0aafb096de91 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -405,52 +405,41 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_writeargs *args = rqstp->rq_argp;
-	unsigned int len, hdr, dlen;
 	u32 max_blocksize = svc_max_payload(rqstp);
 	struct kvec *head = rqstp->rq_arg.head;
 	struct kvec *tail = rqstp->rq_arg.tail;
+	size_t remaining;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
 		return 0;
-	p = xdr_decode_hyper(p, &args->offset);
-
-	args->count = ntohl(*p++);
-	args->stable = ntohl(*p++);
-	len = args->len = ntohl(*p++);
-	if ((void *)p > head->iov_base + head->iov_len)
+	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
 		return 0;
-	/*
-	 * The count must equal the amount of data passed.
-	 */
-	if (args->count != args->len)
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
 		return 0;
 
-	/*
-	 * Check to make sure that we got the right number of
-	 * bytes.
-	 */
-	hdr = (void*)p - head->iov_base;
-	dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr;
-	/*
-	 * Round the length of the data which was specified up to
-	 * the next multiple of XDR units and then compare that
-	 * against the length which was actually received.
-	 * Note that when RPCSEC/GSS (for example) is used, the
-	 * data buffer can be padded so dlen might be larger
-	 * than required.  It must never be smaller.
-	 */
-	if (dlen < XDR_QUADLEN(len)*4)
+	/* opaque data */
+	if (xdr_stream_decode_u32(xdr, &args->len) < 0)
 		return 0;
 
+	/* request sanity */
+	if (args->count != args->len)
+		return 0;
+	remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
+	remaining -= xdr_stream_pos(xdr);
+	if (remaining < xdr_align_size(args->len))
+		return 0;
 	if (args->count > max_blocksize) {
 		args->count = max_blocksize;
-		len = args->len = max_blocksize;
+		args->len = max_blocksize;
 	}
 
-	args->first.iov_base = (void *)p;
-	args->first.iov_len = head->iov_len - hdr;
+	args->first.iov_base = xdr->p;
+	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
+
 	return 1;
 }
 



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

* [PATCH v1 08/42] NFSD: Update READLINK3arg decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (6 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 07/42] NFSD: Update WRITE3arg " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 09/42] NFSD: Fix returned READDIR offset cookie Chuck Lever
                   ` (35 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

The NFSv3 READLINK request takes a single filehandle, so it can
re-use GETATTR's decoder.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3proc.c |    9 +++++----
 fs/nfsd/nfs3xdr.c  |   13 -------------
 fs/nfsd/xdr3.h     |    6 ------
 3 files changed, 5 insertions(+), 23 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index acdf47179a38..9e289e0f439b 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -124,15 +124,16 @@ nfsd3_proc_access(struct svc_rqst *rqstp)
 static __be32
 nfsd3_proc_readlink(struct svc_rqst *rqstp)
 {
-	struct nfsd3_readlinkargs *argp = rqstp->rq_argp;
+	struct nfsd_fhandle *argp = rqstp->rq_argp;
 	struct nfsd3_readlinkres *resp = rqstp->rq_resp;
+	char *buffer = page_address(*(rqstp->rq_next_page++));
 
 	dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh));
 
 	/* Read the symlink. */
 	fh_copy(&resp->fh, &argp->fh);
 	resp->len = NFS3_MAXPATHLEN;
-	resp->status = nfsd_readlink(rqstp, &resp->fh, argp->buffer, &resp->len);
+	resp->status = nfsd_readlink(rqstp, &resp->fh, buffer, &resp->len);
 	return rpc_success;
 }
 
@@ -768,10 +769,10 @@ static const struct svc_procedure nfsd_procedures3[22] = {
 	},
 	[NFS3PROC_READLINK] = {
 		.pc_func = nfsd3_proc_readlink,
-		.pc_decode = nfs3svc_decode_readlinkargs,
+		.pc_decode = nfs3svc_decode_fhandleargs,
 		.pc_encode = nfs3svc_encode_readlinkres,
 		.pc_release = nfs3svc_release_fhandle,
-		.pc_argsize = sizeof(struct nfsd3_readlinkargs),
+		.pc_argsize = sizeof(struct nfsd_fhandle),
 		.pc_ressize = sizeof(struct nfsd3_readlinkres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4,
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 0aafb096de91..db1d6ebf1353 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -543,19 +543,6 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
 	return xdr_argsize_check(rqstp, p);
 }
 
-int
-nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p)
-{
-	struct nfsd3_readlinkargs *args = rqstp->rq_argp;
-
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
-	args->buffer = page_address(*(rqstp->rq_next_page++));
-
-	return xdr_argsize_check(rqstp, p);
-}
-
 int
 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
 {
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 7dfeeaa4e1df..08f909142ddf 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -70,11 +70,6 @@ struct nfsd3_renameargs {
 	unsigned int		tlen;
 };
 
-struct nfsd3_readlinkargs {
-	struct svc_fh		fh;
-	char *			buffer;
-};
-
 struct nfsd3_linkargs {
 	struct svc_fh		ffh;
 	struct svc_fh		tfh;
@@ -282,7 +277,6 @@ int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *);
-int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *);



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

* [PATCH v1 09/42] NFSD: Fix returned READDIR offset cookie
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (7 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 08/42] NFSD: Update READLINK3arg " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 10/42] NFSD: Add helper to set up the pages where the dirlist is encoded Chuck Lever
                   ` (34 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Code inspection shows that the server's NFSv3 READDIR implementation
handles offset cookies slightly differently than the NFSv2 READDIR,
NFSv3 READDIRPLUS, and NFSv4 READDIR implementations,
and there doesn't seem to be any need for this difference.

As a clean up, I copied the logic from nfsd3_proc_readdirplus().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3proc.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 9e289e0f439b..7ea2fb127f6f 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -444,6 +444,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
 	struct nfsd3_readdirargs *argp = rqstp->rq_argp;
 	struct nfsd3_readdirres  *resp = rqstp->rq_resp;
 	int		count = 0;
+	loff_t		offset;
 	struct page	**p;
 	caddr_t		page_addr = NULL;
 
@@ -462,7 +463,9 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
 	resp->common.err = nfs_ok;
 	resp->buffer = argp->buffer;
 	resp->rqstp = rqstp;
-	resp->status = nfsd_readdir(rqstp, &resp->fh, (loff_t *)&argp->cookie,
+	offset = argp->cookie;
+
+	resp->status = nfsd_readdir(rqstp, &resp->fh, &offset,
 				    &resp->common, nfs3svc_encode_entry);
 	memcpy(resp->verf, argp->verf, 8);
 	count = 0;
@@ -478,8 +481,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
 	}
 	resp->count = count >> 2;
 	if (resp->offset) {
-		loff_t offset = argp->cookie;
-
 		if (unlikely(resp->offset1)) {
 			/* we ended up with offset on a page boundary */
 			*resp->offset = htonl(offset >> 32);



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

* [PATCH v1 10/42] NFSD: Add helper to set up the pages where the dirlist is encoded
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (8 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 09/42] NFSD: Fix returned READDIR offset cookie Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 11/42] NFSD: Update READDIR3args decoders to use struct xdr_stream Chuck Lever
                   ` (33 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

De-duplicate some code that is used by both READDIR and READDIRPLUS
to build the dirlist in the Reply. Because this code is not related
to decoding READ arguments, it is moved to a more appropriate spot.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3proc.c |   29 +++++++++++++++++++----------
 fs/nfsd/nfs3xdr.c  |   20 --------------------
 fs/nfsd/xdr3.h     |    1 -
 3 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 7ea2fb127f6f..8675851199f8 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -435,6 +435,23 @@ nfsd3_proc_link(struct svc_rqst *rqstp)
 	return rpc_success;
 }
 
+static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp,
+				     struct nfsd3_readdirres *resp,
+				     int count)
+{
+	count = min_t(u32, count, svc_max_payload(rqstp));
+
+	/* Convert byte count to number of words (i.e. >> 2),
+	 * and reserve room for the NULL ptr & eof flag (-2 words) */
+	resp->buflen = (count >> 2) - 2;
+
+	resp->buffer = page_address(*rqstp->rq_next_page);
+	while (count > 0) {
+		rqstp->rq_next_page++;
+		count -= PAGE_SIZE;
+	}
+}
+
 /*
  * Read a portion of a directory.
  */
@@ -452,16 +469,12 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
 				SVCFH_fmt(&argp->fh),
 				argp->count, (u32) argp->cookie);
 
-	/* Make sure we've room for the NULL ptr & eof flag, and shrink to
-	 * client read size */
-	count = (argp->count >> 2) - 2;
+	nfsd3_init_dirlist_pages(rqstp, resp, argp->count);
 
 	/* Read directory and encode entries on the fly */
 	fh_copy(&resp->fh, &argp->fh);
 
-	resp->buflen = count;
 	resp->common.err = nfs_ok;
-	resp->buffer = argp->buffer;
 	resp->rqstp = rqstp;
 	offset = argp->cookie;
 
@@ -513,16 +526,12 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp)
 				SVCFH_fmt(&argp->fh),
 				argp->count, (u32) argp->cookie);
 
-	/* Convert byte count to number of words (i.e. >> 2),
-	 * and reserve room for the NULL ptr & eof flag (-2 words) */
-	resp->count = (argp->count >> 2) - 2;
+	nfsd3_init_dirlist_pages(rqstp, resp, argp->count);
 
 	/* Read directory and encode entries on the fly */
 	fh_copy(&resp->fh, &argp->fh);
 
 	resp->common.err = nfs_ok;
-	resp->buffer = argp->buffer;
-	resp->buflen = resp->count;
 	resp->rqstp = rqstp;
 	offset = argp->cookie;
 
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index db1d6ebf1353..b601f0c6156f 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -560,8 +560,6 @@ int
 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
-	int len;
-	u32 max_blocksize = svc_max_payload(rqstp);
 
 	p = decode_fh(p, &args->fh);
 	if (!p)
@@ -570,14 +568,6 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 	args->verf   = p; p += 2;
 	args->dircount = ~0;
 	args->count  = ntohl(*p++);
-	len = args->count  = min_t(u32, args->count, max_blocksize);
-
-	while (len > 0) {
-		struct page *p = *(rqstp->rq_next_page++);
-		if (!args->buffer)
-			args->buffer = page_address(p);
-		len -= PAGE_SIZE;
-	}
 
 	return xdr_argsize_check(rqstp, p);
 }
@@ -586,8 +576,6 @@ int
 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
-	int len;
-	u32 max_blocksize = svc_max_payload(rqstp);
 
 	p = decode_fh(p, &args->fh);
 	if (!p)
@@ -597,14 +585,6 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)
 	args->dircount = ntohl(*p++);
 	args->count    = ntohl(*p++);
 
-	len = args->count = min(args->count, max_blocksize);
-	while (len > 0) {
-		struct page *p = *(rqstp->rq_next_page++);
-		if (!args->buffer)
-			args->buffer = page_address(p);
-		len -= PAGE_SIZE;
-	}
-
 	return xdr_argsize_check(rqstp, p);
 }
 
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 08f909142ddf..789a364d5e69 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -93,7 +93,6 @@ struct nfsd3_readdirargs {
 	__u32			dircount;
 	__u32			count;
 	__be32 *		verf;
-	__be32 *		buffer;
 };
 
 struct nfsd3_commitargs {



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

* [PATCH v1 11/42] NFSD: Update READDIR3args decoders to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (9 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 10/42] NFSD: Add helper to set up the pages where the dirlist is encoded Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 12/42] NFSD: Update COMMIT3arg decoder " Chuck Lever
                   ` (32 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

As an additional clean up, neither nfsd3_proc_readdir() nor
nfsd3_proc_readdirplus() make use of the dircount argument, so
remove it from struct nfsd3_readdirargs.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   38 ++++++++++++++++++++++++--------------
 fs/nfsd/xdr3.h    |    1 -
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index b601f0c6156f..6167955475e7 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -559,33 +559,43 @@ nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
+		return 0;
+	args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
+	if (!args->verf)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
 		return 0;
-	p = xdr_decode_hyper(p, &args->cookie);
-	args->verf   = p; p += 2;
-	args->dircount = ~0;
-	args->count  = ntohl(*p++);
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int
 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
+	u32 dircount;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
+		return 0;
+	args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
+	if (!args->verf)
+		return 0;
+	/* dircount is ignored */
+	if (xdr_stream_decode_u32(xdr, &dircount) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
 		return 0;
-	p = xdr_decode_hyper(p, &args->cookie);
-	args->verf     = p; p += 2;
-	args->dircount = ntohl(*p++);
-	args->count    = ntohl(*p++);
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 789a364d5e69..64af5b01c5d7 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -90,7 +90,6 @@ struct nfsd3_symlinkargs {
 struct nfsd3_readdirargs {
 	struct svc_fh		fh;
 	__u64			cookie;
-	__u32			dircount;
 	__u32			count;
 	__be32 *		verf;
 };



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

* [PATCH v1 12/42] NFSD: Update COMMIT3arg decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (10 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 11/42] NFSD: Update READDIR3args decoders to use struct xdr_stream Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 13/42] NFSD: Update the NFSv3 DIROPargs " Chuck Lever
                   ` (31 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 6167955475e7..bda6f3aed1e3 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -601,14 +601,17 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_commitargs *args = rqstp->rq_argp;
-	p = decode_fh(p, &args->fh);
-	if (!p)
+
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
 		return 0;
-	p = xdr_decode_hyper(p, &args->offset);
-	args->count = ntohl(*p++);
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 /*



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

* [PATCH v1 13/42] NFSD: Update the NFSv3 DIROPargs decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (11 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 12/42] NFSD: Update COMMIT3arg decoder " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 14/42] NFSD: Update the RENAME3args " Chuck Lever
                   ` (30 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index bda6f3aed1e3..7175b7315df0 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -117,6 +117,39 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)
 	return p;
 }
 
+static bool
+svcxdr_decode_filename3(struct xdr_stream *xdr, char **name, unsigned int *len)
+{
+	u32 size, i;
+	__be32 *p;
+	char *c;
+
+	if (xdr_stream_decode_u32(xdr, &size) < 0)
+		return false;
+	if (size == 0 || size > NFS3_MAXNAMLEN)
+		return false;
+	p = xdr_inline_decode(xdr, size);
+	if (!p)
+		return false;
+
+	*len = size;
+	*name = (char *)p;
+	for (i = 0, c = *name; i < size; i++, c++) {
+		if (*c == '\0' || *c == '/')
+			return false;
+	}
+
+	return true;
+}
+
+static bool
+svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp,
+			 char **name, unsigned int *len)
+{
+	return svcxdr_decode_nfs_fh3(xdr, fhp) &&
+		svcxdr_decode_filename3(xdr, name, len);
+}
+
 static __be32 *
 decode_sattr3(__be32 *p, struct iattr *iap, struct user_namespace *userns)
 {
@@ -363,13 +396,10 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_diropargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->fh))
-	 || !(p = decode_filename(p, &args->name, &args->len)))
-		return 0;
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len);
 }
 
 int



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

* [PATCH v1 14/42] NFSD: Update the RENAME3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (12 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 13/42] NFSD: Update the NFSv3 DIROPargs " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:30 ` [PATCH v1 15/42] NFSD: Update the LINK3args " Chuck Lever
                   ` (29 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 7175b7315df0..a5bbf9571821 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -562,15 +562,13 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_renameargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->ffh))
-	 || !(p = decode_filename(p, &args->fname, &args->flen))
-	 || !(p = decode_fh(p, &args->tfh))
-	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
-		return 0;
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_diropargs3(xdr, &args->ffh,
+					&args->fname, &args->flen) &&
+		svcxdr_decode_diropargs3(xdr, &args->tfh,
+					 &args->tname, &args->tlen);
 }
 
 int



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

* [PATCH v1 15/42] NFSD: Update the LINK3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (13 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 14/42] NFSD: Update the RENAME3args " Chuck Lever
@ 2021-01-05 15:30 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 16/42] NFSD: Update the SETATTR3args " Chuck Lever
                   ` (28 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:30 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index a5bbf9571821..ba5ec9cdafa1 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -574,14 +574,12 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_linkargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->ffh))
-	 || !(p = decode_fh(p, &args->tfh))
-	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
-		return 0;
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_nfs_fh3(xdr, &args->ffh) &&
+		svcxdr_decode_diropargs3(xdr, &args->tfh,
+					 &args->tname, &args->tlen);
 }
 
 int



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

* [PATCH v1 16/42] NFSD: Update the SETATTR3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (14 preceding siblings ...)
  2021-01-05 15:30 ` [PATCH v1 15/42] NFSD: Update the LINK3args " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 17/42] NFSD: Update the CREATE3args " Chuck Lever
                   ` (27 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c         |  138 +++++++++++++++++++++++++++++++++++++++------
 include/uapi/linux/nfs3.h |    6 ++
 2 files changed, 127 insertions(+), 17 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index ba5ec9cdafa1..ef536fb00728 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -39,12 +39,18 @@ encode_time3(__be32 *p, struct timespec64 *time)
 	return p;
 }
 
-static __be32 *
-decode_time3(__be32 *p, struct timespec64 *time)
+static bool
+svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)
 {
-	time->tv_sec = ntohl(*p++);
-	time->tv_nsec = ntohl(*p++);
-	return p;
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, XDR_UNIT * 2);
+	if (!p)
+		return false;
+	timep->tv_sec = be32_to_cpup(p++);
+	timep->tv_nsec = be32_to_cpup(p);
+
+	return true;
 }
 
 static bool
@@ -150,6 +156,112 @@ svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp,
 		svcxdr_decode_filename3(xdr, name, len);
 }
 
+static bool
+svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
+		     struct iattr *iap)
+{
+	u32 set_it;
+
+	iap->ia_valid = 0;
+
+	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
+		return false;
+	if (set_it) {
+		u32 mode;
+
+		if (xdr_stream_decode_u32(xdr, &mode) < 0)
+			return false;
+		iap->ia_valid |= ATTR_MODE;
+		iap->ia_mode = mode;
+	}
+	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
+		return false;
+	if (set_it) {
+		u32 uid;
+
+		if (xdr_stream_decode_u32(xdr, &uid) < 0)
+			return false;
+		iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), uid);
+		if (uid_valid(iap->ia_uid))
+			iap->ia_valid |= ATTR_UID;
+	}
+	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
+		return false;
+	if (set_it) {
+		u32 gid;
+
+		if (xdr_stream_decode_u32(xdr, &gid) < 0)
+			return false;
+		iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), gid);
+		if (gid_valid(iap->ia_gid))
+			iap->ia_valid |= ATTR_GID;
+	}
+	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
+		return false;
+	if (set_it) {
+		u64 newsize;
+
+		if (xdr_stream_decode_u64(xdr, &newsize) < 0)
+			return false;
+		iap->ia_valid |= ATTR_SIZE;
+		iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX);
+	}
+	if (xdr_stream_decode_u32(xdr, &set_it) < 0)
+		return false;
+	switch (set_it) {
+	case DONT_CHANGE:
+		break;
+	case SET_TO_SERVER_TIME:
+		iap->ia_valid |= ATTR_ATIME;
+		break;
+	case SET_TO_CLIENT_TIME:
+		if (!svcxdr_decode_nfstime3(xdr, &iap->ia_atime))
+			return false;
+		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
+		break;
+	default:
+		return false;
+	}
+	if (xdr_stream_decode_u32(xdr, &set_it) < 0)
+		return false;
+	switch (set_it) {
+	case DONT_CHANGE:
+		break;
+	case SET_TO_SERVER_TIME:
+		iap->ia_valid |= ATTR_MTIME;
+		break;
+	case SET_TO_CLIENT_TIME:
+		if (!svcxdr_decode_nfstime3(xdr, &iap->ia_mtime))
+			return false;
+		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static bool
+svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)
+{
+	__be32 *p;
+	u32 check;
+
+	if (xdr_stream_decode_bool(xdr, &check) < 0)
+		return false;
+	if (check) {
+		p = xdr_inline_decode(xdr, XDR_UNIT * 2);
+		if (!p)
+			return false;
+		args->check_guard = 1;
+		args->guardtime = be32_to_cpup(p);
+	} else
+		args->check_guard = 0;
+
+	return true;
+}
+
 static __be32 *
 decode_sattr3(__be32 *p, struct iattr *iap, struct user_namespace *userns)
 {
@@ -377,20 +489,12 @@ nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_sattrargs *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
-	p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
-
-	if ((args->check_guard = ntohl(*p++)) != 0) { 
-		struct timespec64 time;
-		p = decode_time3(p, &time);
-		args->guardtime = time.tv_sec;
-	}
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_nfs_fh3(xdr, &args->fh) &&
+		svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
+		svcxdr_decode_sattrguard3(xdr, args);
 }
 
 int
diff --git a/include/uapi/linux/nfs3.h b/include/uapi/linux/nfs3.h
index 37e4b34e6b43..c22ab77713bd 100644
--- a/include/uapi/linux/nfs3.h
+++ b/include/uapi/linux/nfs3.h
@@ -63,6 +63,12 @@ enum nfs3_ftype {
 	NF3BAD  = 8
 };
 
+enum nfs3_time_how {
+	DONT_CHANGE		= 0,
+	SET_TO_SERVER_TIME	= 1,
+	SET_TO_CLIENT_TIME	= 2,
+};
+
 struct nfs3_fh {
 	unsigned short size;
 	unsigned char  data[NFS3_FHSIZE];



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

* [PATCH v1 17/42] NFSD: Update the CREATE3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (15 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 16/42] NFSD: Update the SETATTR3args " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 18/42] NFSD: Update the MKDIR3args " Chuck Lever
                   ` (26 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index ef536fb00728..559344c95de9 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -580,26 +580,26 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_createargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->fh))
-	 || !(p = decode_filename(p, &args->name, &args->len)))
+	if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
 		return 0;
-
-	switch (args->createmode = ntohl(*p++)) {
+	if (xdr_stream_decode_u32(xdr, &args->createmode) < 0)
+		return 0;
+	switch (args->createmode) {
 	case NFS3_CREATE_UNCHECKED:
 	case NFS3_CREATE_GUARDED:
-		p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
-		break;
+		return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
 	case NFS3_CREATE_EXCLUSIVE:
-		args->verf = p;
-		p += 2;
+		args->verf = xdr_inline_decode(xdr, NFS3_CREATEVERFSIZE);
+		if (!args->verf)
+			return 0;
 		break;
 	default:
 		return 0;
 	}
-
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int



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

* [PATCH v1 18/42] NFSD: Update the MKDIR3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (16 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 17/42] NFSD: Update the CREATE3args " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 19/42] NFSD: Update the SYMLINK3args " Chuck Lever
                   ` (25 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 559344c95de9..45975fdb033e 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -605,14 +605,12 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_createargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->fh)) ||
-	    !(p = decode_filename(p, &args->name, &args->len)))
-		return 0;
-	p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_diropargs3(xdr, &args->fh,
+					&args->name, &args->len) &&
+		svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
 }
 
 int



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

* [PATCH v1 19/42] NFSD: Update the SYMLINK3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (17 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 18/42] NFSD: Update the MKDIR3args " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 20/42] NFSD: Update the MKNOD3args " Chuck Lever
                   ` (24 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Similar to the WRITE decoder, code that checks the sanity of the
payload size is re-wired to work with xdr_stream infrastructure.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 45975fdb033e..e599d1481b2d 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -616,25 +616,28 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_symlinkargs *args = rqstp->rq_argp;
-	char *base = (char *)p;
-	size_t dlen;
+	struct kvec *head = rqstp->rq_arg.head;
+	struct kvec *tail = rqstp->rq_arg.tail;
+	size_t remaining;
 
-	if (!(p = decode_fh(p, &args->ffh)) ||
-	    !(p = decode_filename(p, &args->fname, &args->flen)))
+	if (!svcxdr_decode_diropargs3(xdr, &args->ffh, &args->fname, &args->flen))
+		return 0;
+	if (!svcxdr_decode_sattr3(rqstp, xdr, &args->attrs))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->tlen) < 0)
 		return 0;
-	p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
 
-	args->tlen = ntohl(*p++);
+	/* request sanity */
+	remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
+	remaining -= xdr_stream_pos(xdr);
+	if (remaining < xdr_align_size(args->tlen))
+		return 0;
 
-	args->first.iov_base = p;
-	args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
-	args->first.iov_len -= (char *)p - base;
+	args->first.iov_base = xdr->p;
+	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
 
-	dlen = args->first.iov_len + rqstp->rq_arg.page_len +
-	       rqstp->rq_arg.tail[0].iov_len;
-	if (dlen < XDR_QUADLEN(args->tlen) << 2)
-		return 0;
 	return 1;
 }
 



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

* [PATCH v1 20/42] NFSD: Update the MKNOD3args decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (18 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 19/42] NFSD: Update the SYMLINK3args " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 21/42] NFSD: Update the NFSv2 GETATTR argument " Chuck Lever
                   ` (23 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

This commit removes the last usage of the original decode_sattr3(),
so it is removed as a clean-up.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |  107 +++++++++++++++++------------------------------------
 1 file changed, 35 insertions(+), 72 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e599d1481b2d..5fb7e8a599c4 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -103,26 +103,6 @@ encode_fh(__be32 *p, struct svc_fh *fhp)
 	return p + XDR_QUADLEN(size);
 }
 
-/*
- * Decode a file name and make sure that the path contains
- * no slashes or null bytes.
- */
-static __be32 *
-decode_filename(__be32 *p, char **namp, unsigned int *lenp)
-{
-	char		*name;
-	unsigned int	i;
-
-	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) {
-		for (i = 0, name = *namp; i < *lenp; i++, name++) {
-			if (*name == '\0' || *name == '/')
-				return NULL;
-		}
-	}
-
-	return p;
-}
-
 static bool
 svcxdr_decode_filename3(struct xdr_stream *xdr, char **name, unsigned int *len)
 {
@@ -262,49 +242,26 @@ svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)
 	return true;
 }
 
-static __be32 *
-decode_sattr3(__be32 *p, struct iattr *iap, struct user_namespace *userns)
+static bool
+svcxdr_decode_specdata3(struct xdr_stream *xdr, struct nfsd3_mknodargs *args)
 {
-	u32	tmp;
+	__be32 *p;
 
-	iap->ia_valid = 0;
+	p = xdr_inline_decode(xdr, XDR_UNIT * 2);
+	if (!p)
+		return false;
+	args->major = be32_to_cpup(p++);
+	args->minor = be32_to_cpup(p);
 
-	if (*p++) {
-		iap->ia_valid |= ATTR_MODE;
-		iap->ia_mode = ntohl(*p++);
-	}
-	if (*p++) {
-		iap->ia_uid = make_kuid(userns, ntohl(*p++));
-		if (uid_valid(iap->ia_uid))
-			iap->ia_valid |= ATTR_UID;
-	}
-	if (*p++) {
-		iap->ia_gid = make_kgid(userns, ntohl(*p++));
-		if (gid_valid(iap->ia_gid))
-			iap->ia_valid |= ATTR_GID;
-	}
-	if (*p++) {
-		u64	newsize;
+	return true;
+}
 
-		iap->ia_valid |= ATTR_SIZE;
-		p = xdr_decode_hyper(p, &newsize);
-		iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX);
-	}
-	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
-		iap->ia_valid |= ATTR_ATIME;
-	} else if (tmp == 2) {		/* set to client time */
-		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
-		iap->ia_atime.tv_sec = ntohl(*p++);
-		iap->ia_atime.tv_nsec = ntohl(*p++);
-	}
-	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
-		iap->ia_valid |= ATTR_MTIME;
-	} else if (tmp == 2) {		/* set to client time */
-		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
-		iap->ia_mtime.tv_sec = ntohl(*p++);
-		iap->ia_mtime.tv_nsec = ntohl(*p++);
-	}
-	return p;
+static bool
+svcxdr_decode_devicedata3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
+			  struct nfsd3_mknodargs *args)
+{
+	return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
+		svcxdr_decode_specdata3(xdr, args);
 }
 
 static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
@@ -644,24 +601,30 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_mknodargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->fh))
-	 || !(p = decode_filename(p, &args->name, &args->len)))
+	if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->ftype) < 0)
+		return 0;
+	switch (args->ftype) {
+	case NF3CHR:
+	case NF3BLK:
+		return svcxdr_decode_devicedata3(rqstp, xdr, args);
+	case NF3SOCK:
+	case NF3FIFO:
+		return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
+	case NF3REG:
+	case NF3DIR:
+	case NF3LNK:
+		/* Valid XDR but illegal file types */
+		break;
+	default:
 		return 0;
-
-	args->ftype = ntohl(*p++);
-
-	if (args->ftype == NF3BLK  || args->ftype == NF3CHR
-	 || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
-		p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
-
-	if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
-		args->major = ntohl(*p++);
-		args->minor = ntohl(*p++);
 	}
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int



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

* [PATCH v1 21/42] NFSD: Update the NFSv2 GETATTR argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (19 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 20/42] NFSD: Update the MKNOD3args " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 22/42] NFSD: Update the NFSv2 READ " Chuck Lever
                   ` (22 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsproc.c |    4 ++--
 fs/nfsd/nfsxdr.c  |   26 ++++++++++++++++++++------
 fs/nfsd/xdr.h     |    2 +-
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 1f85a4dc9d1b..b9bc162a5c77 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -627,7 +627,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_GETATTR] = {
 		.pc_func = nfsd_proc_getattr,
-		.pc_decode = nfssvc_decode_fhandle,
+		.pc_decode = nfssvc_decode_fhandleargs,
 		.pc_encode = nfssvc_encode_attrstat,
 		.pc_release = nfssvc_release_attrstat,
 		.pc_argsize = sizeof(struct nfsd_fhandle),
@@ -793,7 +793,7 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_STATFS] = {
 		.pc_func = nfsd_proc_statfs,
-		.pc_decode = nfssvc_decode_fhandle,
+		.pc_decode = nfssvc_decode_fhandleargs,
 		.pc_encode = nfssvc_encode_statfsres,
 		.pc_argsize = sizeof(struct nfsd_fhandle),
 		.pc_ressize = sizeof(struct nfsd_statfsres),
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 7aa6e8aca2c1..f3189e1be20f 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -23,8 +23,9 @@ static u32	nfs_ftypes[] = {
 
 
 /*
- * XDR functions for basic NFS types
+ * Basic NFSv2 data types (RFC 1094 Section 2.3)
  */
+
 static __be32 *
 decode_fh(__be32 *p, struct svc_fh *fhp)
 {
@@ -37,6 +38,21 @@ decode_fh(__be32 *p, struct svc_fh *fhp)
 	return p + (NFS_FHSIZE >> 2);
 }
 
+static bool
+svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, NFS_FHSIZE);
+	if (!p)
+		return false;
+	fh_init(fhp, NFS_FHSIZE);
+	memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE);
+	fhp->fh_handle.fh_size = NFS_FHSIZE;
+
+	return true;
+}
+
 /* Helper function for NFSv2 ACL code */
 __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp)
 {
@@ -194,14 +210,12 @@ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *f
  */
 
 int
-nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
+nfssvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_fhandle *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_fhandle(xdr, &args->fh);
 }
 
 int
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index ad77387734cc..84256a6a1ba1 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -144,7 +144,7 @@ union nfsd_xdrstore {
 #define NFS2_SVC_XDRSIZE	sizeof(union nfsd_xdrstore)
 
 
-int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *);
+int nfssvc_decode_fhandleargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_readargs(struct svc_rqst *, __be32 *);



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

* [PATCH v1 22/42] NFSD: Update the NFSv2 READ argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (20 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 21/42] NFSD: Update the NFSv2 GETATTR argument " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 23/42] NFSD: Update the NFSv2 WRITE " Chuck Lever
                   ` (21 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

The code that sets up rq_vec is refactored so that it is now
adjacent to the nfsd_read() call site where it is used.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsproc.c |   32 ++++++++++++++++++--------------
 fs/nfsd/nfsxdr.c  |   36 ++++++++++++------------------------
 fs/nfsd/xdr.h     |    1 -
 3 files changed, 30 insertions(+), 39 deletions(-)

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index b9bc162a5c77..814762793f9c 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -171,32 +171,36 @@ nfsd_proc_read(struct svc_rqst *rqstp)
 {
 	struct nfsd_readargs *argp = rqstp->rq_argp;
 	struct nfsd_readres *resp = rqstp->rq_resp;
+	unsigned int len;
 	u32 eof;
+	int v;
 
 	dprintk("nfsd: READ    %s %d bytes at %d\n",
 		SVCFH_fmt(&argp->fh),
 		argp->count, argp->offset);
 
+	argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2);
+
+	v = 0;
+	len = argp->count;
+	while (len > 0) {
+		struct page *page = *(rqstp->rq_next_page++);
+
+		rqstp->rq_vec[v].iov_base = page_address(page);
+		rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
+		len -= rqstp->rq_vec[v].iov_len;
+		v++;
+	}
+
 	/* Obtain buffer pointer for payload. 19 is 1 word for
 	 * status, 17 words for fattr, and 1 word for the byte count.
 	 */
-
-	if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
-		char buf[RPC_MAX_ADDRBUFLEN];
-		printk(KERN_NOTICE
-			"oversized read request from %s (%d bytes)\n",
-				svc_print_addr(rqstp, buf, sizeof(buf)),
-				argp->count);
-		argp->count = NFSSVC_MAXBLKSIZE_V2;
-	}
 	svc_reserve_auth(rqstp, (19<<2) + argp->count + 4);
 
 	resp->count = argp->count;
-	resp->status = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh),
-				 argp->offset,
-				 rqstp->rq_vec, argp->vlen,
-				 &resp->count,
-				 &eof);
+	fh_copy(&resp->fh, &argp->fh);
+	resp->status = nfsd_read(rqstp, &resp->fh, argp->offset,
+				 rqstp->rq_vec, v, &resp->count, &eof);
 	if (resp->status == nfs_ok)
 		resp->status = fh_getattr(&resp->fh, &resp->stat);
 	else if (resp->status == nfserr_jukebox)
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index f3189e1be20f..1eacaa2c13a9 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -246,33 +246,21 @@ nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_readargs *args = rqstp->rq_argp;
-	unsigned int len;
-	int v;
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
+	u32 totalcount;
 
-	args->offset    = ntohl(*p++);
-	len = args->count     = ntohl(*p++);
-	p++; /* totalcount - unused */
-
-	len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2);
+	if (!svcxdr_decode_fhandle(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->offset) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
+		return 0;
+	/* totalcount is ignored */
+	if (xdr_stream_decode_u32(xdr, &totalcount) < 0)
+		return 0;
 
-	/* set up somewhere to store response.
-	 * We take pages, put them on reslist and include in iovec
-	 */
-	v=0;
-	while (len > 0) {
-		struct page *p = *(rqstp->rq_next_page++);
-
-		rqstp->rq_vec[v].iov_base = page_address(p);
-		rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
-		len -= rqstp->rq_vec[v].iov_len;
-		v++;
-	}
-	args->vlen = v;
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 int
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index 84256a6a1ba1..d2ffda96975d 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -27,7 +27,6 @@ struct nfsd_readargs {
 	struct svc_fh		fh;
 	__u32			offset;
 	__u32			count;
-	int			vlen;
 };
 
 struct nfsd_writeargs {



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

* [PATCH v1 23/42] NFSD: Update the NFSv2 WRITE argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (21 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 22/42] NFSD: Update the NFSv2 READ " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 24/42] NFSD: Update the NFSv2 READLINK " Chuck Lever
                   ` (20 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   52 +++++++++++++++++++++-------------------------------
 1 file changed, 21 insertions(+), 31 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 1eacaa2c13a9..11d27b219cff 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -266,46 +266,36 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_writeargs *args = rqstp->rq_argp;
-	unsigned int len, hdr, dlen;
 	struct kvec *head = rqstp->rq_arg.head;
+	struct kvec *tail = rqstp->rq_arg.tail;
+	u32 beginoffset, totalcount;
+	size_t remaining;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_fhandle(xdr, &args->fh))
 		return 0;
-
-	p++;				/* beginoffset */
-	args->offset = ntohl(*p++);	/* offset */
-	p++;				/* totalcount */
-	len = args->len = ntohl(*p++);
-	/*
-	 * The protocol specifies a maximum of 8192 bytes.
-	 */
-	if (len > NFSSVC_MAXBLKSIZE_V2)
+	/* beginoffset is ignored */
+	if (xdr_stream_decode_u32(xdr, &beginoffset) < 0)
 		return 0;
-
-	/*
-	 * Check to make sure that we got the right number of
-	 * bytes.
-	 */
-	hdr = (void*)p - head->iov_base;
-	if (hdr > head->iov_len)
+	if (xdr_stream_decode_u32(xdr, &args->offset) < 0)
+		return 0;
+	/* totalcount is ignored */
+	if (xdr_stream_decode_u32(xdr, &totalcount) < 0)
 		return 0;
-	dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
 
-	/*
-	 * Round the length of the data which was specified up to
-	 * the next multiple of XDR units and then compare that
-	 * against the length which was actually received.
-	 * Note that when RPCSEC/GSS (for example) is used, the
-	 * data buffer can be padded so dlen might be larger
-	 * than required.  It must never be smaller.
-	 */
-	if (dlen < XDR_QUADLEN(len)*4)
+	/* opaque data */
+	if (xdr_stream_decode_u32(xdr, &args->len) < 0)
+		return 0;
+	if (args->len > NFSSVC_MAXBLKSIZE_V2)
+		return 0;
+	remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
+	remaining -= xdr_stream_pos(xdr);
+	if (remaining < xdr_align_size(args->len))
 		return 0;
+	args->first.iov_base = xdr->p;
+	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
 
-	args->first.iov_base = (void *)p;
-	args->first.iov_len = head->iov_len - hdr;
 	return 1;
 }
 



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

* [PATCH v1 24/42] NFSD: Update the NFSv2 READLINK argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (22 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 23/42] NFSD: Update the NFSv2 WRITE " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 25/42] NFSD: Add helper to set up the pages where the dirlist is encoded Chuck Lever
                   ` (19 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

If the code that sets up the sink buffer for nfsd_readlink() is
moved adjacent to the nfsd_readlink() call site that uses it, then
the only argument is a file handle, and the fhandle decoder can be
used instead.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsproc.c |    9 +++++----
 fs/nfsd/nfsxdr.c  |   13 -------------
 fs/nfsd/xdr.h     |    6 ------
 3 files changed, 5 insertions(+), 23 deletions(-)

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 814762793f9c..bdb47848f7fd 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -149,14 +149,15 @@ nfsd_proc_lookup(struct svc_rqst *rqstp)
 static __be32
 nfsd_proc_readlink(struct svc_rqst *rqstp)
 {
-	struct nfsd_readlinkargs *argp = rqstp->rq_argp;
+	struct nfsd_fhandle *argp = rqstp->rq_argp;
 	struct nfsd_readlinkres *resp = rqstp->rq_resp;
+	char *buffer = page_address(*(rqstp->rq_next_page++));
 
 	dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh));
 
 	/* Read the symlink. */
 	resp->len = NFS_MAXPATHLEN;
-	resp->status = nfsd_readlink(rqstp, &argp->fh, argp->buffer, &resp->len);
+	resp->status = nfsd_readlink(rqstp, &argp->fh, buffer, &resp->len);
 
 	fh_put(&argp->fh);
 	return rpc_success;
@@ -674,9 +675,9 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_READLINK] = {
 		.pc_func = nfsd_proc_readlink,
-		.pc_decode = nfssvc_decode_readlinkargs,
+		.pc_decode = nfssvc_decode_fhandleargs,
 		.pc_encode = nfssvc_encode_readlinkres,
-		.pc_argsize = sizeof(struct nfsd_readlinkargs),
+		.pc_argsize = sizeof(struct nfsd_fhandle),
 		.pc_ressize = sizeof(struct nfsd_readlinkres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST+1+NFS_MAXPATHLEN/4,
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 11d27b219cff..02dd9888d93b 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -326,19 +326,6 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
 	return xdr_argsize_check(rqstp, p);
 }
 
-int
-nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p)
-{
-	struct nfsd_readlinkargs *args = rqstp->rq_argp;
-
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
-	args->buffer = page_address(*(rqstp->rq_next_page++));
-
-	return xdr_argsize_check(rqstp, p);
-}
-
 int
 nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
 {
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index d2ffda96975d..288c29a999db 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -52,11 +52,6 @@ struct nfsd_renameargs {
 	unsigned int		tlen;
 };
 
-struct nfsd_readlinkargs {
-	struct svc_fh		fh;
-	char *			buffer;
-};
-	
 struct nfsd_linkargs {
 	struct svc_fh		ffh;
 	struct svc_fh		tfh;
@@ -150,7 +145,6 @@ int nfssvc_decode_readargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_createargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *);
-int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *);



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

* [PATCH v1 25/42] NFSD: Add helper to set up the pages where the dirlist is encoded
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (23 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 24/42] NFSD: Update the NFSv2 READLINK " Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:31 ` [PATCH v1 26/42] NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream Chuck Lever
                   ` (18 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

Add a helper similar to nfsd3_init_dirlist_pages().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsproc.c |   29 ++++++++++++++++++-----------
 fs/nfsd/nfsxdr.c  |    2 --
 fs/nfsd/xdr.h     |    1 -
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index bdb47848f7fd..b2f8035f166b 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -553,6 +553,20 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp)
 	return rpc_success;
 }
 
+static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp,
+				    struct nfsd_readdirres *resp,
+				    int count)
+{
+	count = min_t(u32, count, PAGE_SIZE);
+
+	/* Convert byte count to number of words (i.e. >> 2),
+	 * and reserve room for the NULL ptr & eof flag (-2 words) */
+	resp->buflen = (count >> 2) - 2;
+
+	resp->buffer = page_address(*rqstp->rq_next_page);
+	rqstp->rq_next_page++;
+}
+
 /*
  * Read a portion of a directory.
  */
@@ -561,31 +575,24 @@ nfsd_proc_readdir(struct svc_rqst *rqstp)
 {
 	struct nfsd_readdirargs *argp = rqstp->rq_argp;
 	struct nfsd_readdirres *resp = rqstp->rq_resp;
-	int		count;
 	loff_t		offset;
+	__be32		*buffer;
 
 	dprintk("nfsd: READDIR  %s %d bytes at %d\n",
 		SVCFH_fmt(&argp->fh),		
 		argp->count, argp->cookie);
 
-	/* Shrink to the client read size */
-	count = (argp->count >> 2) - 2;
-
-	/* Make sure we've room for the NULL ptr & eof flag */
-	count -= 2;
-	if (count < 0)
-		count = 0;
+	nfsd_init_dirlist_pages(rqstp, resp, argp->count);
+	buffer = resp->buffer;
 
-	resp->buffer = argp->buffer;
 	resp->offset = NULL;
-	resp->buflen = count;
 	resp->common.err = nfs_ok;
 	/* Read directory and encode entries on the fly */
 	offset = argp->cookie;
 	resp->status = nfsd_readdir(rqstp, &argp->fh, &offset,
 				    &resp->common, nfssvc_encode_entry);
 
-	resp->count = resp->buffer - argp->buffer;
+	resp->count = resp->buffer - buffer;
 	if (resp->offset)
 		*resp->offset = htonl(offset);
 
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 02dd9888d93b..3d72334e1673 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -388,8 +388,6 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 		return 0;
 	args->cookie = ntohl(*p++);
 	args->count  = ntohl(*p++);
-	args->count  = min_t(u32, args->count, PAGE_SIZE);
-	args->buffer = page_address(*(rqstp->rq_next_page++));
 
 	return xdr_argsize_check(rqstp, p);
 }
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index 288c29a999db..d700838f6512 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -73,7 +73,6 @@ struct nfsd_readdirargs {
 	struct svc_fh		fh;
 	__u32			cookie;
 	__u32			count;
-	__be32 *		buffer;
 };
 
 struct nfsd_stat {



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

* [PATCH v1 26/42] NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (24 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 25/42] NFSD: Add helper to set up the pages where the dirlist is encoded Chuck Lever
@ 2021-01-05 15:31 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 27/42] NFSD: Update NFSv2 diropargs decoding " Chuck Lever
                   ` (17 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:31 UTC (permalink / raw)
  To: linux-nfs

As an additional clean up, move code not related to XDR decoding
into readdir's .pc_func call out.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 3d72334e1673..7b33093f8d8b 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -381,15 +381,17 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_readdirargs *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_fhandle(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->cookie) < 0)
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
 		return 0;
-	args->cookie = ntohl(*p++);
-	args->count  = ntohl(*p++);
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 /*



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

* [PATCH v1 27/42] NFSD: Update NFSv2 diropargs decoding to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (25 preceding siblings ...)
  2021-01-05 15:31 ` [PATCH v1 26/42] NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 28/42] NFSD: Update the NFSv2 RENAME argument decoder " Chuck Lever
                   ` (16 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 7b33093f8d8b..00a7db8548eb 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -86,6 +86,38 @@ decode_filename(__be32 *p, char **namp, unsigned int *lenp)
 	return p;
 }
 
+static bool
+svcxdr_decode_filename(struct xdr_stream *xdr, char **name, unsigned int *len)
+{
+	u32 size, i;
+	__be32 *p;
+	char *c;
+
+	if (xdr_stream_decode_u32(xdr, &size) < 0)
+		return false;
+	if (size == 0 || size > NFS_MAXNAMLEN)
+		return false;
+	p = xdr_inline_decode(xdr, size);
+	if (!p)
+		return false;
+
+	*len = size;
+	*name = (char *)p;
+	for (i = 0, c = *name; i < size; i++, c++)
+		if (*c == '\0' || *c == '/')
+			return false;
+
+	return true;
+}
+
+static bool
+svcxdr_decode_diropargs(struct xdr_stream *xdr, struct svc_fh *fhp,
+			char **name, unsigned int *len)
+{
+	return svcxdr_decode_fhandle(xdr, fhp) &&
+		svcxdr_decode_filename(xdr, name, len);
+}
+
 static __be32 *
 decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)
 {
@@ -234,13 +266,10 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_diropargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->fh))
-	 || !(p = decode_filename(p, &args->name, &args->len)))
-		return 0;
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_diropargs(xdr, &args->fh, &args->name, &args->len);
 }
 
 int



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

* [PATCH v1 28/42] NFSD: Update the NFSv2 RENAME argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (26 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 27/42] NFSD: Update NFSv2 diropargs decoding " Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 29/42] NFSD: Update the NFSv2 LINK " Chuck Lever
                   ` (15 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 00a7db8548eb..d4f4729c7b1c 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -344,15 +344,13 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_renameargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->ffh))
-	 || !(p = decode_filename(p, &args->fname, &args->flen))
-	 || !(p = decode_fh(p, &args->tfh))
-	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
-		return 0;
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_diropargs(xdr, &args->ffh,
+				       &args->fname, &args->flen) &&
+		svcxdr_decode_diropargs(xdr, &args->tfh,
+					&args->tname, &args->tlen);
 }
 
 int



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

* [PATCH v1 29/42] NFSD: Update the NFSv2 LINK argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (27 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 28/42] NFSD: Update the NFSv2 RENAME argument decoder " Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 30/42] NFSD: Update the NFSv2 SETATTR " Chuck Lever
                   ` (14 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index d4f4729c7b1c..3d0fe03a3fb9 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -356,14 +356,12 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_linkargs *args = rqstp->rq_argp;
 
-	if (!(p = decode_fh(p, &args->ffh))
-	 || !(p = decode_fh(p, &args->tfh))
-	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
-		return 0;
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_fhandle(xdr, &args->ffh) &&
+		svcxdr_decode_diropargs(xdr, &args->tfh,
+					&args->tname, &args->tlen);
 }
 
 int



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

* [PATCH v1 30/42] NFSD: Update the NFSv2 SETATTR argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (28 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 29/42] NFSD: Update the NFSv2 LINK " Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 31/42] NFSD: Update the NFSv2 CREATE " Chuck Lever
                   ` (13 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 76 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 3d0fe03a3fb9..6c87ea8f3876 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -173,6 +173,79 @@ decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)
 	return p;
 }
 
+static bool
+svcxdr_decode_sattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
+		    struct iattr *iap)
+{
+	u32 tmp1, tmp2;
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, XDR_UNIT * 8);
+	if (!p)
+		return false;
+
+	iap->ia_valid = 0;
+
+	/*
+	 * Some Sun clients put 0xffff in the mode field when they
+	 * mean 0xffffffff.
+	 */
+	tmp1 = be32_to_cpup(p++);
+	if (tmp1 != (u32)-1 && tmp1 != 0xffff) {
+		iap->ia_valid |= ATTR_MODE;
+		iap->ia_mode = tmp1;
+	}
+
+	tmp1 = be32_to_cpup(p++);
+	if (tmp1 != (u32)-1) {
+		iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), tmp1);
+		if (uid_valid(iap->ia_uid))
+			iap->ia_valid |= ATTR_UID;
+	}
+
+	tmp1 = be32_to_cpup(p++);
+	if (tmp1 != (u32)-1) {
+		iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), tmp1);
+		if (gid_valid(iap->ia_gid))
+			iap->ia_valid |= ATTR_GID;
+	}
+
+	tmp1 = be32_to_cpup(p++);
+	if (tmp1 != (u32)-1) {
+		iap->ia_valid |= ATTR_SIZE;
+		iap->ia_size = tmp1;
+	}
+
+	tmp1 = be32_to_cpup(p++);
+	tmp2 = be32_to_cpup(p++);
+	if (tmp1 != (u32)-1 && tmp2 != (u32)-1) {
+		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
+		iap->ia_atime.tv_sec = tmp1;
+		iap->ia_atime.tv_nsec = tmp2 * NSEC_PER_USEC;
+	}
+
+	tmp1 = be32_to_cpup(p++);
+	tmp2 = be32_to_cpup(p++);
+	if (tmp1 != (u32)-1 && tmp2 != (u32)-1) {
+		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
+		iap->ia_mtime.tv_sec = tmp1;
+		iap->ia_mtime.tv_nsec = tmp2 * NSEC_PER_USEC;
+		/*
+		 * Passing the invalid value useconds=1000000 for mtime
+		 * is a Sun convention for "set both mtime and atime to
+		 * current server time".  It's needed to make permissions
+		 * checks for the "touch" program across v2 mounts to
+		 * Solaris and Irix boxes work correctly. See description of
+		 * sattr in section 6.1 of "NFS Illustrated" by
+		 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
+		 */
+		if (tmp2 == 1000000)
+			iap->ia_valid &= ~(ATTR_ATIME_SET|ATTR_MTIME_SET);
+	}
+
+	return true;
+}
+
 static __be32 *
 encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 	     struct kstat *stat)
@@ -253,14 +326,11 @@ nfssvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_sattrargs *args = rqstp->rq_argp;
 
-	p = decode_fh(p, &args->fh);
-	if (!p)
-		return 0;
-	p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_fhandle(xdr, &args->fh) &&
+		svcxdr_decode_sattr(rqstp, xdr, &args->attrs);
 }
 
 int



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

* [PATCH v1 31/42] NFSD: Update the NFSv2 CREATE argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (29 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 30/42] NFSD: Update the NFSv2 SETATTR " Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 32/42] NFSD: Update the NFSv2 SYMLINK " Chuck Lever
                   ` (12 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 6c87ea8f3876..2e2806cbe7b8 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -401,14 +401,12 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_createargs *args = rqstp->rq_argp;
 
-	if (   !(p = decode_fh(p, &args->fh))
-	    || !(p = decode_filename(p, &args->name, &args->len)))
-		return 0;
-	p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
-
-	return xdr_argsize_check(rqstp, p);
+	return svcxdr_decode_diropargs(xdr, &args->fh,
+				       &args->name, &args->len) &&
+		svcxdr_decode_sattr(rqstp, xdr, &args->attrs);
 }
 
 int



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

* [PATCH v1 32/42] NFSD: Update the NFSv2 SYMLINK argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (30 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 31/42] NFSD: Update the NFSv2 CREATE " Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 33/42] NFSD: Remove argument length checking in nfsd_dispatch() Chuck Lever
                   ` (11 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |  113 +++++-------------------------------------------------
 1 file changed, 10 insertions(+), 103 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 2e2806cbe7b8..f2cb4794aeaf 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -66,26 +66,6 @@ encode_fh(__be32 *p, struct svc_fh *fhp)
 	return p + (NFS_FHSIZE>> 2);
 }
 
-/*
- * Decode a file name and make sure that the path contains
- * no slashes or null bytes.
- */
-static __be32 *
-decode_filename(__be32 *p, char **namp, unsigned int *lenp)
-{
-	char		*name;
-	unsigned int	i;
-
-	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) {
-		for (i = 0, name = *namp; i < *lenp; i++, name++) {
-			if (*name == '\0' || *name == '/')
-				return NULL;
-		}
-	}
-
-	return p;
-}
-
 static bool
 svcxdr_decode_filename(struct xdr_stream *xdr, char **name, unsigned int *len)
 {
@@ -118,61 +98,6 @@ svcxdr_decode_diropargs(struct xdr_stream *xdr, struct svc_fh *fhp,
 		svcxdr_decode_filename(xdr, name, len);
 }
 
-static __be32 *
-decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)
-{
-	u32	tmp, tmp1;
-
-	iap->ia_valid = 0;
-
-	/* Sun client bug compatibility check: some sun clients seem to
-	 * put 0xffff in the mode field when they mean 0xffffffff.
-	 * Quoting the 4.4BSD nfs server code: Nah nah nah nah na nah.
-	 */
-	if ((tmp = ntohl(*p++)) != (u32)-1 && tmp != 0xffff) {
-		iap->ia_valid |= ATTR_MODE;
-		iap->ia_mode = tmp;
-	}
-	if ((tmp = ntohl(*p++)) != (u32)-1) {
-		iap->ia_uid = make_kuid(userns, tmp);
-		if (uid_valid(iap->ia_uid))
-			iap->ia_valid |= ATTR_UID;
-	}
-	if ((tmp = ntohl(*p++)) != (u32)-1) {
-		iap->ia_gid = make_kgid(userns, tmp);
-		if (gid_valid(iap->ia_gid))
-			iap->ia_valid |= ATTR_GID;
-	}
-	if ((tmp = ntohl(*p++)) != (u32)-1) {
-		iap->ia_valid |= ATTR_SIZE;
-		iap->ia_size = tmp;
-	}
-	tmp  = ntohl(*p++); tmp1 = ntohl(*p++);
-	if (tmp != (u32)-1 && tmp1 != (u32)-1) {
-		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
-		iap->ia_atime.tv_sec = tmp;
-		iap->ia_atime.tv_nsec = tmp1 * 1000; 
-	}
-	tmp  = ntohl(*p++); tmp1 = ntohl(*p++);
-	if (tmp != (u32)-1 && tmp1 != (u32)-1) {
-		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
-		iap->ia_mtime.tv_sec = tmp;
-		iap->ia_mtime.tv_nsec = tmp1 * 1000; 
-		/*
-		 * Passing the invalid value useconds=1000000 for mtime
-		 * is a Sun convention for "set both mtime and atime to
-		 * current server time".  It's needed to make permissions
-		 * checks for the "touch" program across v2 mounts to
-		 * Solaris and Irix boxes work correctly. See description of
-		 * sattr in section 6.1 of "NFS Illustrated" by
-		 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
-		 */
-		if (tmp1 == 1000000)
-			iap->ia_valid &= ~(ATTR_ATIME_SET|ATTR_MTIME_SET);
-	}
-	return p;
-}
-
 static bool
 svcxdr_decode_sattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
 		    struct iattr *iap)
@@ -435,40 +360,22 @@ nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
 int
 nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd_symlinkargs *args = rqstp->rq_argp;
-	char *base = (char *)p;
-	size_t xdrlen;
+	struct kvec *head = rqstp->rq_arg.head;
 
-	if (   !(p = decode_fh(p, &args->ffh))
-	    || !(p = decode_filename(p, &args->fname, &args->flen)))
+	if (!svcxdr_decode_diropargs(xdr, &args->ffh, &args->fname, &args->flen))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->tlen) < 0)
 		return 0;
-
-	args->tlen = ntohl(*p++);
 	if (args->tlen == 0)
 		return 0;
 
-	args->first.iov_base = p;
-	args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
-	args->first.iov_len -= (char *)p - base;
-
-	/* This request is never larger than a page. Therefore,
-	 * transport will deliver either:
-	 * 1. pathname in the pagelist -> sattr is in the tail.
-	 * 2. everything in the head buffer -> sattr is in the head.
-	 */
-	if (rqstp->rq_arg.page_len) {
-		if (args->tlen != rqstp->rq_arg.page_len)
-			return 0;
-		p = rqstp->rq_arg.tail[0].iov_base;
-	} else {
-		xdrlen = XDR_QUADLEN(args->tlen);
-		if (xdrlen > args->first.iov_len - (8 * sizeof(__be32)))
-			return 0;
-		p += xdrlen;
-	}
-	decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
-
-	return 1;
+	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
+	args->first.iov_base = xdr_inline_decode(xdr, args->tlen);
+	if (!args->first.iov_base)
+		return 0;
+	return svcxdr_decode_sattr(rqstp, xdr, &args->attrs);
 }
 
 int



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

* [PATCH v1 33/42] NFSD: Remove argument length checking in nfsd_dispatch()
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (31 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 32/42] NFSD: Update the NFSv2 SYMLINK " Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 34/42] NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream Chuck Lever
                   ` (10 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Now that the argument decoders for NFSv2 and NFSv3 use the
xdr_stream mechanism, the version-specific length checking logic in
nfsd_dispatch() is no longer necessary.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfssvc.c |   34 ----------------------------------
 1 file changed, 34 deletions(-)

diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index f9c9f4c63cc7..6de406322106 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -955,37 +955,6 @@ nfsd(void *vrqstp)
 	return 0;
 }
 
-/*
- * A write procedure can have a large argument, and a read procedure can
- * have a large reply, but no NFSv2 or NFSv3 procedure has argument and
- * reply that can both be larger than a page.  The xdr code has taken
- * advantage of this assumption to be a sloppy about bounds checking in
- * some cases.  Pending a rewrite of the NFSv2/v3 xdr code to fix that
- * problem, we enforce these assumptions here:
- */
-static bool nfs_request_too_big(struct svc_rqst *rqstp,
-				const struct svc_procedure *proc)
-{
-	/*
-	 * The ACL code has more careful bounds-checking and is not
-	 * susceptible to this problem:
-	 */
-	if (rqstp->rq_prog != NFS_PROGRAM)
-		return false;
-	/*
-	 * Ditto NFSv4 (which can in theory have argument and reply both
-	 * more than a page):
-	 */
-	if (rqstp->rq_vers >= 4)
-		return false;
-	/* The reply will be small, we're OK: */
-	if (proc->pc_xdrressize > 0 &&
-	    proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
-		return false;
-
-	return rqstp->rq_arg.len > PAGE_SIZE;
-}
-
 /**
  * nfsd_dispatch - Process an NFS or NFSACL Request
  * @rqstp: incoming request
@@ -1004,9 +973,6 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 	struct kvec *resv = &rqstp->rq_res.head[0];
 	__be32 *p;
 
-	if (nfs_request_too_big(rqstp, proc))
-		goto out_decode_err;
-
 	/*
 	 * Give the xdr decoder a chance to change this if it wants
 	 * (necessary in the NFSv4.0 compound case)



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

* [PATCH v1 34/42] NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (32 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 33/42] NFSD: Remove argument length checking in nfsd_dispatch() Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 35/42] NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs Chuck Lever
                   ` (9 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c |   10 +++++-----
 fs/nfsd/nfsxdr.c  |   11 ++++++++++-
 fs/nfsd/xdr.h     |    1 +
 fs/nfsd/xdr3.h    |    2 +-
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 899762da23c9..df2e145cfab0 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -188,17 +188,17 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
 
 static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_getaclargs *argp = rqstp->rq_argp;
 
-	p = nfs2svc_decode_fh(p, &argp->fh);
-	if (!p)
+	if (!svcxdr_decode_fhandle(xdr, &argp->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &argp->mask) < 0)
 		return 0;
-	argp->mask = ntohl(*p); p++;
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
-
 static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_setaclargs *argp = rqstp->rq_argp;
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index f2cb4794aeaf..5ab9fc14816c 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -38,7 +38,16 @@ decode_fh(__be32 *p, struct svc_fh *fhp)
 	return p + (NFS_FHSIZE >> 2);
 }
 
-static bool
+/**
+ * svcxdr_decode_fhandle - Decode an NFSv2 file handle
+ * @xdr: XDR stream positioned at an encoded NFSv2 FH
+ * @fhp: OUT: filled-in server file handle
+ *
+ * Return values:
+ *  %false: The encoded file handle was not valid
+ *  %true: @fhp has been initialized
+ */
+bool
 svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp)
 {
 	__be32 *p;
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index d700838f6512..035c99c7b384 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -165,5 +165,6 @@ void nfssvc_release_readres(struct svc_rqst *rqstp);
 /* Helper functions for NFSv2 ACL code */
 __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat);
 __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp);
+bool svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp);
 
 #endif /* LINUX_NFSD_H */
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 64af5b01c5d7..43db4206cd25 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -102,7 +102,7 @@ struct nfsd3_commitargs {
 
 struct nfsd3_getaclargs {
 	struct svc_fh		fh;
-	int			mask;
+	__u32			mask;
 };
 
 struct posix_acl;



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

* [PATCH v1 35/42] NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (33 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 34/42] NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 36/42] NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream Chuck Lever
                   ` (8 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfs_common/nfsacl.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/nfsacl.h |    3 +++
 2 files changed, 55 insertions(+)

diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index d056ad2fdefd..79c563c1a5e8 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -295,3 +295,55 @@ int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
 		   nfsacl_desc.desc.array_len;
 }
 EXPORT_SYMBOL_GPL(nfsacl_decode);
+
+/**
+ * nfs_stream_decode_acl - Decode an NFSv3 ACL
+ *
+ * @xdr: an xdr_stream positioned at an encoded ACL
+ * @aclcnt: OUT: count of ACEs in decoded posix_acl
+ * @pacl: OUT: a dynamically-allocated buffer containing the decoded posix_acl
+ *
+ * Return values:
+ *   %false: The encoded ACL is not valid
+ *   %true: @pacl contains a decoded ACL, and @xdr is advanced
+ *
+ * On a successful return, caller must release *pacl using posix_acl_release().
+ */
+bool nfs_stream_decode_acl(struct xdr_stream *xdr, unsigned int *aclcnt,
+			   struct posix_acl **pacl)
+{
+	const size_t elem_size = XDR_UNIT * 3;
+	struct nfsacl_decode_desc nfsacl_desc = {
+		.desc = {
+			.elem_size = elem_size,
+			.xcode = pacl ? xdr_nfsace_decode : NULL,
+		},
+	};
+	unsigned int base;
+	u32 entries;
+
+	if (xdr_stream_decode_u32(xdr, &entries) < 0)
+		return false;
+	if (entries > NFS_ACL_MAX_ENTRIES)
+		return false;
+
+	base = xdr_stream_pos(xdr);
+	if (!xdr_inline_decode(xdr, XDR_UNIT + elem_size * entries))
+		return false;
+	nfsacl_desc.desc.array_maxlen = entries;
+	if (xdr_decode_array2(xdr->buf, base, &nfsacl_desc.desc))
+		return false;
+
+	if (pacl) {
+		if (entries != nfsacl_desc.desc.array_len ||
+		    posix_acl_from_nfsacl(nfsacl_desc.acl) != 0) {
+			posix_acl_release(nfsacl_desc.acl);
+			return false;
+		}
+		*pacl = nfsacl_desc.acl;
+	}
+	if (aclcnt)
+		*aclcnt = entries;
+	return true;
+}
+EXPORT_SYMBOL_GPL(nfs_stream_decode_acl);
diff --git a/include/linux/nfsacl.h b/include/linux/nfsacl.h
index 103d44695323..0ba99c513649 100644
--- a/include/linux/nfsacl.h
+++ b/include/linux/nfsacl.h
@@ -38,5 +38,8 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
 extern int
 nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
 	      struct posix_acl **pacl);
+extern bool
+nfs_stream_decode_acl(struct xdr_stream *xdr, unsigned int *aclcnt,
+		      struct posix_acl **pacl);
 
 #endif  /* __LINUX_NFSACL_H */



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

* [PATCH v1 36/42] NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (34 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 35/42] NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:32 ` [PATCH v1 37/42] NFSD: Update the NFSv2 ACL GETATTR " Chuck Lever
                   ` (7 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c |   29 ++++++++++++-----------------
 fs/nfsd/xdr3.h    |    2 +-
 2 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index df2e145cfab0..123820ec79d3 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -201,28 +201,23 @@ static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)
 
 static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_setaclargs *argp = rqstp->rq_argp;
-	struct kvec *head = rqstp->rq_arg.head;
-	unsigned int base;
-	int n;
 
-	p = nfs2svc_decode_fh(p, &argp->fh);
-	if (!p)
+	if (!svcxdr_decode_fhandle(xdr, &argp->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &argp->mask) < 0)
+		return 0;
+	if (argp->mask & ~NFS_ACL_MASK)
 		return 0;
-	argp->mask = ntohl(*p++);
-	if (argp->mask & ~NFS_ACL_MASK ||
-	    !xdr_argsize_check(rqstp, p))
+	if (!nfs_stream_decode_acl(xdr, NULL, (argp->mask & NFS_ACL) ?
+				   &argp->acl_access : NULL))
+		return 0;
+	if (!nfs_stream_decode_acl(xdr, NULL, (argp->mask & NFS_DFACL) ?
+				   &argp->acl_default : NULL))
 		return 0;
 
-	base = (char *)p - (char *)head->iov_base;
-	n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
-			  (argp->mask & NFS_ACL) ?
-			  &argp->acl_access : NULL);
-	if (n > 0)
-		n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
-				  (argp->mask & NFS_DFACL) ?
-				  &argp->acl_default : NULL);
-	return (n > 0);
+	return 1;
 }
 
 static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 43db4206cd25..5afb3ce4f062 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -108,7 +108,7 @@ struct nfsd3_getaclargs {
 struct posix_acl;
 struct nfsd3_setaclargs {
 	struct svc_fh		fh;
-	int			mask;
+	__u32			mask;
 	struct posix_acl	*acl_access;
 	struct posix_acl	*acl_default;
 };



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

* [PATCH v1 37/42] NFSD: Update the NFSv2 ACL GETATTR argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (35 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 36/42] NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream Chuck Lever
@ 2021-01-05 15:32 ` Chuck Lever
  2021-01-05 15:33 ` [PATCH v1 38/42] NFSD: Update the NFSv2 ACL ACCESS " Chuck Lever
                   ` (6 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:32 UTC (permalink / raw)
  To: linux-nfs

Since the ACL GETATTR procedure is the same as the normal GETATTR
procedure, simply re-use nfssvc_decode_fhandleargs.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c |   12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 123820ec79d3..0274348f6679 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -220,16 +220,6 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
 	return 1;
 }
 
-static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p)
-{
-	struct nfsd_fhandle *argp = rqstp->rq_argp;
-
-	p = nfs2svc_decode_fh(p, &argp->fh);
-	if (!p)
-		return 0;
-	return xdr_argsize_check(rqstp, p);
-}
-
 static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_accessargs *argp = rqstp->rq_argp;
@@ -392,7 +382,7 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 	},
 	[ACLPROC2_GETATTR] = {
 		.pc_func = nfsacld_proc_getattr,
-		.pc_decode = nfsaclsvc_decode_fhandleargs,
+		.pc_decode = nfssvc_decode_fhandleargs,
 		.pc_encode = nfsaclsvc_encode_attrstatres,
 		.pc_release = nfsaclsvc_release_attrstat,
 		.pc_argsize = sizeof(struct nfsd_fhandle),



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

* [PATCH v1 38/42] NFSD: Update the NFSv2 ACL ACCESS argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (36 preceding siblings ...)
  2021-01-05 15:32 ` [PATCH v1 37/42] NFSD: Update the NFSv2 ACL GETATTR " Chuck Lever
@ 2021-01-05 15:33 ` Chuck Lever
  2021-01-05 15:33 ` [PATCH v1 39/42] NFSD: Clean up after updating NFSv2 ACL decoders Chuck Lever
                   ` (5 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:33 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 0274348f6679..7eeac5b81c20 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -222,14 +222,15 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
 
 static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
 {
-	struct nfsd3_accessargs *argp = rqstp->rq_argp;
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
+	struct nfsd3_accessargs *args = rqstp->rq_argp;
 
-	p = nfs2svc_decode_fh(p, &argp->fh);
-	if (!p)
+	if (!svcxdr_decode_fhandle(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->access) < 0)
 		return 0;
-	argp->access = ntohl(*p++);
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
 /*



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

* [PATCH v1 39/42] NFSD: Clean up after updating NFSv2 ACL decoders
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (37 preceding siblings ...)
  2021-01-05 15:33 ` [PATCH v1 38/42] NFSD: Update the NFSv2 ACL ACCESS " Chuck Lever
@ 2021-01-05 15:33 ` Chuck Lever
  2021-01-05 15:33 ` [PATCH v1 40/42] NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream Chuck Lever
                   ` (4 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:33 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfsxdr.c |   18 ------------------
 fs/nfsd/xdr.h    |    1 -
 2 files changed, 19 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 5ab9fc14816c..5d79ef6a0c7f 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -26,18 +26,6 @@ static u32	nfs_ftypes[] = {
  * Basic NFSv2 data types (RFC 1094 Section 2.3)
  */
 
-static __be32 *
-decode_fh(__be32 *p, struct svc_fh *fhp)
-{
-	fh_init(fhp, NFS_FHSIZE);
-	memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE);
-	fhp->fh_handle.fh_size = NFS_FHSIZE;
-
-	/* FIXME: Look up export pointer here and verify
-	 * Sun Secure RPC if requested */
-	return p + (NFS_FHSIZE >> 2);
-}
-
 /**
  * svcxdr_decode_fhandle - Decode an NFSv2 file handle
  * @xdr: XDR stream positioned at an encoded NFSv2 FH
@@ -62,12 +50,6 @@ svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp)
 	return true;
 }
 
-/* Helper function for NFSv2 ACL code */
-__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp)
-{
-	return decode_fh(p, fhp);
-}
-
 static __be32 *
 encode_fh(__be32 *p, struct svc_fh *fhp)
 {
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index 035c99c7b384..3018b52b6d5e 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -164,7 +164,6 @@ void nfssvc_release_readres(struct svc_rqst *rqstp);
 
 /* Helper functions for NFSv2 ACL code */
 __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat);
-__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp);
 bool svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp);
 
 #endif /* LINUX_NFSD_H */



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

* [PATCH v1 40/42] NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (38 preceding siblings ...)
  2021-01-05 15:33 ` [PATCH v1 39/42] NFSD: Clean up after updating NFSv2 ACL decoders Chuck Lever
@ 2021-01-05 15:33 ` Chuck Lever
  2021-01-05 15:33 ` [PATCH v1 41/42] NFSD: Update the NFSv2 SETACL " Chuck Lever
                   ` (3 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:33 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3acl.c |   11 ++++++-----
 fs/nfsd/nfs3xdr.c |   11 ++++++++++-
 fs/nfsd/xdr3.h    |    1 +
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 9e1a92fb9771..addb0d7d5500 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -124,19 +124,20 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp)
 /*
  * XDR decode functions
  */
+
 static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
 	struct nfsd3_getaclargs *args = rqstp->rq_argp;
 
-	p = nfs3svc_decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &args->mask) < 0)
 		return 0;
-	args->mask = ntohl(*p); p++;
 
-	return xdr_argsize_check(rqstp, p);
+	return 1;
 }
 
-
 static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd3_setaclargs *args = rqstp->rq_argp;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 5fb7e8a599c4..4be38599f331 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -53,7 +53,16 @@ svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)
 	return true;
 }
 
-static bool
+/**
+ * svcxdr_decode_nfs_fh3 - Decode an NFSv3 file handle
+ * @xdr: XDR stream positioned at an undecoded NFSv3 FH
+ * @fhp: OUT: filled-in server file handle
+ *
+ * Return values:
+ *  %false: The encoded file handle was not valid
+ *  %true: @fhp has been initialized
+ */
+bool
 svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
 {
 	__be32 *p;
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 5afb3ce4f062..7456aee74f3d 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -308,6 +308,7 @@ int nfs3svc_encode_entry_plus(void *, const char *name,
 __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p,
 				struct svc_fh *fhp);
 __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp);
+bool svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp);
 
 
 #endif /* _LINUX_NFSD_XDR3_H */



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

* [PATCH v1 41/42] NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (39 preceding siblings ...)
  2021-01-05 15:33 ` [PATCH v1 40/42] NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream Chuck Lever
@ 2021-01-05 15:33 ` Chuck Lever
  2021-01-05 15:33 ` [PATCH v1 42/42] NFSD: Clean up after updating NFSv3 ACL decoders Chuck Lever
                   ` (2 subsequent siblings)
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:33 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3acl.c |   31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index addb0d7d5500..a568b842e9eb 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -140,28 +140,23 @@ static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)
 
 static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
-	struct nfsd3_setaclargs *args = rqstp->rq_argp;
-	struct kvec *head = rqstp->rq_arg.head;
-	unsigned int base;
-	int n;
+	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
+	struct nfsd3_setaclargs *argp = rqstp->rq_argp;
 
-	p = nfs3svc_decode_fh(p, &args->fh);
-	if (!p)
+	if (!svcxdr_decode_nfs_fh3(xdr, &argp->fh))
+		return 0;
+	if (xdr_stream_decode_u32(xdr, &argp->mask) < 0)
 		return 0;
-	args->mask = ntohl(*p++);
-	if (args->mask & ~NFS_ACL_MASK ||
-	    !xdr_argsize_check(rqstp, p))
+	if (argp->mask & ~NFS_ACL_MASK)
+		return 0;
+	if (!nfs_stream_decode_acl(xdr, NULL, (argp->mask & NFS_ACL) ?
+				   &argp->acl_access : NULL))
+		return 0;
+	if (!nfs_stream_decode_acl(xdr, NULL, (argp->mask & NFS_DFACL) ?
+				   &argp->acl_default : NULL))
 		return 0;
 
-	base = (char *)p - (char *)head->iov_base;
-	n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
-			  (args->mask & NFS_ACL) ?
-			  &args->acl_access : NULL);
-	if (n > 0)
-		n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
-				  (args->mask & NFS_DFACL) ?
-				  &args->acl_default : NULL);
-	return (n > 0);
+	return 1;
 }
 
 /*



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

* [PATCH v1 42/42] NFSD: Clean up after updating NFSv3 ACL decoders
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (40 preceding siblings ...)
  2021-01-05 15:33 ` [PATCH v1 41/42] NFSD: Update the NFSv2 SETACL " Chuck Lever
@ 2021-01-05 15:33 ` Chuck Lever
  2021-01-08  3:18 ` [PATCH v1 00/42] Update NFSD XDR functions J. Bruce Fields
  2021-01-22 19:58 ` J. Bruce Fields
  43 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-05 15:33 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs3xdr.c |   20 --------------------
 fs/nfsd/xdr3.h    |    2 --
 2 files changed, 22 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 4be38599f331..023f310ba488 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -82,26 +82,6 @@ svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
 	return true;
 }
 
-static __be32 *
-decode_fh(__be32 *p, struct svc_fh *fhp)
-{
-	unsigned int size;
-	fh_init(fhp, NFS3_FHSIZE);
-	size = ntohl(*p++);
-	if (size > NFS3_FHSIZE)
-		return NULL;
-
-	memcpy(&fhp->fh_handle.fh_base, p, size);
-	fhp->fh_handle.fh_size = size;
-	return p + XDR_QUADLEN(size);
-}
-
-/* Helper function for NFSv3 ACL code */
-__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp)
-{
-	return decode_fh(p, fhp);
-}
-
 static __be32 *
 encode_fh(__be32 *p, struct svc_fh *fhp)
 {
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 7456aee74f3d..3e1578953f54 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -307,8 +307,6 @@ int nfs3svc_encode_entry_plus(void *, const char *name,
 /* Helper functions for NFSv3 ACL code */
 __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p,
 				struct svc_fh *fhp);
-__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp);
 bool svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp);
 
-
 #endif /* _LINUX_NFSD_XDR3_H */



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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (41 preceding siblings ...)
  2021-01-05 15:33 ` [PATCH v1 42/42] NFSD: Clean up after updating NFSv3 ACL decoders Chuck Lever
@ 2021-01-08  3:18 ` J. Bruce Fields
  2021-01-08 15:50   ` Chuck Lever
  2021-01-22 19:58 ` J. Bruce Fields
  43 siblings, 1 reply; 55+ messages in thread
From: J. Bruce Fields @ 2021-01-08  3:18 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

I haven't had a chance to review these, but thought I should mention I'm
seeing a failure in xfstests generic/465 that I don't *think* is
reproduceable before this series.  Unfortunately it's intermittent,
though, so I'm not certain yet.

--b.

On Tue, Jan 05, 2021 at 10:29:40AM -0500, Chuck Lever wrote:
> The long-term purpose is to convert the NFSD XDR encoder and decoder
> functions to use the struct xdr_stream API. This is a refactor and
> clean-up with few or no changes in behavior expected, but there are
> some long-term benefits:
> 
> - More robust input sanitization in the NFSD decoders.
> - Help make it possible to use common kernel library functions with
>   XDR stream APIs (for example, GSS-API).
> - Align the structure of the source code with the RFCs so it is
>   easier to learn, verify, and maintain our XDR implementation.
> - Removal of more than a hundred hidden dprintk() call sites.
> - Removal of as much explicit manipulation of pages as possible to
>   help make the eventual transition to xdr->bvecs smoother.
> 
> The current series focuses on NFSv2 and NFSv3 decoder changes. Please
> review and comment!
> 
> The full set of patches lives in a topic branch in my git repo:
> 
>  git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-xdr_stream
> 
> 
> ---
> 
> Chuck Lever (42):
>       SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
>       SUNRPC: Display RPC procedure names instead of proc numbers
>       SUNRPC: Move definition of XDR_UNIT
>       NFSD: Update GETATTR3args decoder to use struct xdr_stream
>       NFSD: Update ACCESS3arg decoder to use struct xdr_stream
>       NFSD: Update READ3arg decoder to use struct xdr_stream
>       NFSD: Update WRITE3arg decoder to use struct xdr_stream
>       NFSD: Update READLINK3arg decoder to use struct xdr_stream
>       NFSD: Fix returned READDIR offset cookie
>       NFSD: Add helper to set up the pages where the dirlist is encoded
>       NFSD: Update READDIR3args decoders to use struct xdr_stream
>       NFSD: Update COMMIT3arg decoder to use struct xdr_stream
>       NFSD: Update the NFSv3 DIROPargs decoder to use struct xdr_stream
>       NFSD: Update the RENAME3args decoder to use struct xdr_stream
>       NFSD: Update the LINK3args decoder to use struct xdr_stream
>       NFSD: Update the SETATTR3args decoder to use struct xdr_stream
>       NFSD: Update the CREATE3args decoder to use struct xdr_stream
>       NFSD: Update the MKDIR3args decoder to use struct xdr_stream
>       NFSD: Update the SYMLINK3args decoder to use struct xdr_stream
>       NFSD: Update the MKNOD3args decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 GETATTR argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 READ argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 WRITE argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 READLINK argument decoder to use struct xdr_stream
>       NFSD: Add helper to set up the pages where the dirlist is encoded
>       NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream
>       NFSD: Update NFSv2 diropargs decoding to use struct xdr_stream
>       NFSD: Update the NFSv2 RENAME argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 LINK argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 SETATTR argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 CREATE argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 SYMLINK argument decoder to use struct xdr_stream
>       NFSD: Remove argument length checking in nfsd_dispatch()
>       NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream
>       NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs
>       NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 ACL GETATTR argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 ACL ACCESS argument decoder to use struct xdr_stream
>       NFSD: Clean up after updating NFSv2 ACL decoders
>       NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
>       NFSD: Clean up after updating NFSv3 ACL decoders
> 
> 
>  fs/nfs_common/nfsacl.c          |  52 +++
>  fs/nfsd/nfs2acl.c               |  62 ++--
>  fs/nfsd/nfs3acl.c               |  42 ++-
>  fs/nfsd/nfs3proc.c              |  71 +++--
>  fs/nfsd/nfs3xdr.c               | 538 ++++++++++++++++++--------------
>  fs/nfsd/nfsproc.c               |  74 +++--
>  fs/nfsd/nfssvc.c                |  34 --
>  fs/nfsd/nfsxdr.c                | 350 ++++++++++-----------
>  fs/nfsd/xdr.h                   |  12 +-
>  fs/nfsd/xdr3.h                  |  20 +-
>  include/linux/nfsacl.h          |   3 +
>  include/linux/sunrpc/msg_prot.h |   3 -
>  include/linux/sunrpc/xdr.h      |  13 +-
>  include/trace/events/sunrpc.h   |  15 +-
>  include/uapi/linux/nfs3.h       |   6 +
>  15 files changed, 680 insertions(+), 615 deletions(-)
> 
> --
> Chuck Lever

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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08  3:18 ` [PATCH v1 00/42] Update NFSD XDR functions J. Bruce Fields
@ 2021-01-08 15:50   ` Chuck Lever
  2021-01-08 15:52     ` Bruce Fields
  0 siblings, 1 reply; 55+ messages in thread
From: Chuck Lever @ 2021-01-08 15:50 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Linux NFS Mailing List



> On Jan 7, 2021, at 10:18 PM, bfields@fieldses.org wrote:
> 
> I haven't had a chance to review these, but thought I should mention I'm
> seeing a failure in xfstests generic/465 that I don't *think* is
> reproduceable before this series.  Unfortunately it's intermittent,
> though, so I'm not certain yet.

Confirming: does that failure occur with NFSv3?

--
Chuck Lever




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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 15:50   ` Chuck Lever
@ 2021-01-08 15:52     ` Bruce Fields
  2021-01-08 15:56       ` Chuck Lever
  0 siblings, 1 reply; 55+ messages in thread
From: Bruce Fields @ 2021-01-08 15:52 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Linux NFS Mailing List

On Fri, Jan 08, 2021 at 10:50:09AM -0500, Chuck Lever wrote:
> 
> 
> > On Jan 7, 2021, at 10:18 PM, bfields@fieldses.org wrote:
> > 
> > I haven't had a chance to review these, but thought I should mention I'm
> > seeing a failure in xfstests generic/465 that I don't *think* is
> > reproduceable before this series.  Unfortunately it's intermittent,
> > though, so I'm not certain yet.
> 
> Confirming: does that failure occur with NFSv3?

I've only tried it over 4.2.

--b.

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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 15:52     ` Bruce Fields
@ 2021-01-08 15:56       ` Chuck Lever
  2021-01-08 16:01         ` Bruce Fields
  0 siblings, 1 reply; 55+ messages in thread
From: Chuck Lever @ 2021-01-08 15:56 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Linux NFS Mailing List



> On Jan 8, 2021, at 10:52 AM, Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Fri, Jan 08, 2021 at 10:50:09AM -0500, Chuck Lever wrote:
>> 
>> 
>>> On Jan 7, 2021, at 10:18 PM, bfields@fieldses.org wrote:
>>> 
>>> I haven't had a chance to review these, but thought I should mention I'm
>>> seeing a failure in xfstests generic/465 that I don't *think* is
>>> reproduceable before this series.  Unfortunately it's intermittent,
>>> though, so I'm not certain yet.
>> 
>> Confirming: does that failure occur with NFSv3?
> 
> I've only tried it over 4.2.

Interesting. This series shouldn't have any impact on NFSv4
direct I/O functionality:

fs/nfs_common/nfsacl.c          |  52 +++
fs/nfsd/nfs2acl.c               |  62 ++--
fs/nfsd/nfs3acl.c               |  42 ++-
fs/nfsd/nfs3proc.c              |  71 +++--
fs/nfsd/nfs3xdr.c               | 538 ++++++++++++++++++--------------
fs/nfsd/nfsproc.c               |  74 +++--
fs/nfsd/nfssvc.c                |  34 --
fs/nfsd/nfsxdr.c                | 350 ++++++++++-----------
fs/nfsd/xdr.h                   |  12 +-
fs/nfsd/xdr3.h                  |  20 +-
include/linux/nfsacl.h          |   3 +
include/linux/sunrpc/msg_prot.h |   3 -
include/linux/sunrpc/xdr.h      |  13 +-
include/trace/events/sunrpc.h   |  15 +-
include/uapi/linux/nfs3.h       |   6 +
15 files changed, 680 insertions(+), 615 deletions(-)

Can you try to nail it down a little?


--
Chuck Lever




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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 15:56       ` Chuck Lever
@ 2021-01-08 16:01         ` Bruce Fields
  2021-01-08 16:35           ` Trond Myklebust
  0 siblings, 1 reply; 55+ messages in thread
From: Bruce Fields @ 2021-01-08 16:01 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Linux NFS Mailing List

On Fri, Jan 08, 2021 at 10:56:14AM -0500, Chuck Lever wrote:
> 
> 
> > On Jan 8, 2021, at 10:52 AM, Bruce Fields <bfields@fieldses.org> wrote:
> > 
> > On Fri, Jan 08, 2021 at 10:50:09AM -0500, Chuck Lever wrote:
> >> 
> >> 
> >>> On Jan 7, 2021, at 10:18 PM, bfields@fieldses.org wrote:
> >>> 
> >>> I haven't had a chance to review these, but thought I should mention I'm
> >>> seeing a failure in xfstests generic/465 that I don't *think* is
> >>> reproduceable before this series.  Unfortunately it's intermittent,
> >>> though, so I'm not certain yet.
> >> 
> >> Confirming: does that failure occur with NFSv3?
> > 
> > I've only tried it over 4.2.
> 
> Interesting. This series shouldn't have any impact on NFSv4
> direct I/O functionality:
> 
> fs/nfs_common/nfsacl.c          |  52 +++
> fs/nfsd/nfs2acl.c               |  62 ++--
> fs/nfsd/nfs3acl.c               |  42 ++-
> fs/nfsd/nfs3proc.c              |  71 +++--
> fs/nfsd/nfs3xdr.c               | 538 ++++++++++++++++++--------------
> fs/nfsd/nfsproc.c               |  74 +++--
> fs/nfsd/nfssvc.c                |  34 --
> fs/nfsd/nfsxdr.c                | 350 ++++++++++-----------
> fs/nfsd/xdr.h                   |  12 +-
> fs/nfsd/xdr3.h                  |  20 +-
> include/linux/nfsacl.h          |   3 +
> include/linux/sunrpc/msg_prot.h |   3 -
> include/linux/sunrpc/xdr.h      |  13 +-
> include/trace/events/sunrpc.h   |  15 +-
> include/uapi/linux/nfs3.h       |   6 +
> 15 files changed, 680 insertions(+), 615 deletions(-)
> 
> Can you try to nail it down a little?

I took a look back through my testing history and realized I've seen it
fail previously.  So it was just coincidence that I saw it fail a couple
times after applying the series but not before yesterday.  Sorry for the
noise!

--b.

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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 16:01         ` Bruce Fields
@ 2021-01-08 16:35           ` Trond Myklebust
  2021-01-08 18:08             ` bfields
  0 siblings, 1 reply; 55+ messages in thread
From: Trond Myklebust @ 2021-01-08 16:35 UTC (permalink / raw)
  To: bfields, chuck.lever; +Cc: linux-nfs

On Fri, 2021-01-08 at 11:01 -0500, Bruce Fields wrote:
> On Fri, Jan 08, 2021 at 10:56:14AM -0500, Chuck Lever wrote:
> > 
> > 
> > > On Jan 8, 2021, at 10:52 AM, Bruce Fields <bfields@fieldses.org>
> > > wrote:
> > > 
> > > On Fri, Jan 08, 2021 at 10:50:09AM -0500, Chuck Lever wrote:
> > > > 
> > > > 
> > > > > On Jan 7, 2021, at 10:18 PM, bfields@fieldses.org wrote:
> > > > > 
> > > > > I haven't had a chance to review these, but thought I should
> > > > > mention I'm
> > > > > seeing a failure in xfstests generic/465 that I don't *think*
> > > > > is
> > > > > reproduceable before this series.  Unfortunately it's
> > > > > intermittent,
> > > > > though, so I'm not certain yet.
> > > > 
> > > > Confirming: does that failure occur with NFSv3?
> > > 
> > > I've only tried it over 4.2.
> > 
> > Interesting. This series shouldn't have any impact on NFSv4
> > direct I/O functionality:
> > 
> > fs/nfs_common/nfsacl.c          |  52 +++
> > fs/nfsd/nfs2acl.c               |  62 ++--
> > fs/nfsd/nfs3acl.c               |  42 ++-
> > fs/nfsd/nfs3proc.c              |  71 +++--
> > fs/nfsd/nfs3xdr.c               | 538 ++++++++++++++++++-----------
> > ---
> > fs/nfsd/nfsproc.c               |  74 +++--
> > fs/nfsd/nfssvc.c                |  34 --
> > fs/nfsd/nfsxdr.c                | 350 ++++++++++-----------
> > fs/nfsd/xdr.h                   |  12 +-
> > fs/nfsd/xdr3.h                  |  20 +-
> > include/linux/nfsacl.h          |   3 +
> > include/linux/sunrpc/msg_prot.h |   3 -
> > include/linux/sunrpc/xdr.h      |  13 +-
> > include/trace/events/sunrpc.h   |  15 +-
> > include/uapi/linux/nfs3.h       |   6 +
> > 15 files changed, 680 insertions(+), 615 deletions(-)
> > 
> > Can you try to nail it down a little?
> 
> I took a look back through my testing history and realized I've seen
> it
> fail previously.  So it was just coincidence that I saw it fail a
> couple
> times after applying the series but not before yesterday.  Sorry for
> the
> noise!
> 
> --b.

Just ignore generic/465. As far as NFS is concerned, the test has
utterly borked assumptions about O_DIRECT ordering.

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com



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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 16:35           ` Trond Myklebust
@ 2021-01-08 18:08             ` bfields
  2021-01-08 22:54               ` Trond Myklebust
  0 siblings, 1 reply; 55+ messages in thread
From: bfields @ 2021-01-08 18:08 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: chuck.lever, linux-nfs

On Fri, Jan 08, 2021 at 04:35:50PM +0000, Trond Myklebust wrote:
> Just ignore generic/465. As far as NFS is concerned, the test has
> utterly borked assumptions about O_DIRECT ordering.

Thanks, adding to my list of tests to skip.  Should we report it as an
xfstests bug?

(Is the test just wrong, or is this some non-standard but documented NFS
behavior, or something else?)

--b.

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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 18:08             ` bfields
@ 2021-01-08 22:54               ` Trond Myklebust
  2021-01-09 16:43                 ` Chuck Lever
  0 siblings, 1 reply; 55+ messages in thread
From: Trond Myklebust @ 2021-01-08 22:54 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, chuck.lever

On Fri, 2021-01-08 at 13:08 -0500, bfields@fieldses.org wrote:
> On Fri, Jan 08, 2021 at 04:35:50PM +0000, Trond Myklebust wrote:
> > Just ignore generic/465. As far as NFS is concerned, the test has
> > utterly borked assumptions about O_DIRECT ordering.
> 
> Thanks, adding to my list of tests to skip.  Should we report it as
> an
> xfstests bug?
> 
> (Is the test just wrong, or is this some non-standard but documented
> NFS
> behavior, or something else?)
> 
> --b.

I'm not sure who decided the ordering requirements for O_DIRECT, but in
order to fix the generic/465 case, I'd either have to order all reads
with all outstanding writes or implement some kind of range locking to
do it in a more fine-grained way.

We do order buffered I/O and O_DIRECT, so that backup programs can do
their thing on databases that use O_DIRECT. However we do assume that
anyone using O_DIRECT for I/O is doing their own synchronisation.

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com



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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-08 22:54               ` Trond Myklebust
@ 2021-01-09 16:43                 ` Chuck Lever
  0 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-09 16:43 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: Bruce Fields, Linux NFS Mailing List


> On Jan 8, 2021, at 5:54 PM, Trond Myklebust <trondmy@hammerspace.com> wrote:
> 
> On Fri, 2021-01-08 at 13:08 -0500, bfields@fieldses.org wrote:
>> On Fri, Jan 08, 2021 at 04:35:50PM +0000, Trond Myklebust wrote:
>>> Just ignore generic/465. As far as NFS is concerned, the test has
>>> utterly borked assumptions about O_DIRECT ordering.
>> 
>> Thanks, adding to my list of tests to skip.  Should we report it as
>> an
>> xfstests bug?
>> 
>> (Is the test just wrong, or is this some non-standard but documented
>> NFS
>> behavior, or something else?)
>> 
>> --b.
> 
> I'm not sure who decided the ordering requirements for O_DIRECT, but in
> order to fix the generic/465 case, I'd either have to order all reads
> with all outstanding writes or implement some kind of range locking to
> do it in a more fine-grained way.
> 
> We do order buffered I/O and O_DIRECT, so that backup programs can do
> their thing on databases that use O_DIRECT. However we do assume that
> anyone using O_DIRECT for I/O is doing their own synchronisation.

Perhaps the best approach would be to add generic/465 to the exempt-list
for NFS.


--
Chuck Lever




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

* Re: [PATCH v1 07/42] NFSD: Update WRITE3arg decoder to use struct xdr_stream
  2021-01-05 15:30 ` [PATCH v1 07/42] NFSD: Update WRITE3arg " Chuck Lever
@ 2021-01-22 18:47   ` J. Bruce Fields
  2021-01-22 18:55     ` Chuck Lever
  0 siblings, 1 reply; 55+ messages in thread
From: J. Bruce Fields @ 2021-01-22 18:47 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

On Tue, Jan 05, 2021 at 10:30:18AM -0500, Chuck Lever wrote:
> As part of the update, open code that sanity-checks the size of the
> data payload against the length of the RPC Call message has to be
> re-implemented to use xdr_stream infrastructure.

I'm having a little trouble parsing that.  Did you mean "write code"?

--b.

> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
>  fs/nfsd/nfs3xdr.c |   51 ++++++++++++++++++++-------------------------------
>  1 file changed, 20 insertions(+), 31 deletions(-)
> 
> diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
> index ff98eae5db81..0aafb096de91 100644
> --- a/fs/nfsd/nfs3xdr.c
> +++ b/fs/nfsd/nfs3xdr.c
> @@ -405,52 +405,41 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
>  int
>  nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
>  {
> +	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
>  	struct nfsd3_writeargs *args = rqstp->rq_argp;
> -	unsigned int len, hdr, dlen;
>  	u32 max_blocksize = svc_max_payload(rqstp);
>  	struct kvec *head = rqstp->rq_arg.head;
>  	struct kvec *tail = rqstp->rq_arg.tail;
> +	size_t remaining;
>  
> -	p = decode_fh(p, &args->fh);
> -	if (!p)
> +	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
>  		return 0;
> -	p = xdr_decode_hyper(p, &args->offset);
> -
> -	args->count = ntohl(*p++);
> -	args->stable = ntohl(*p++);
> -	len = args->len = ntohl(*p++);
> -	if ((void *)p > head->iov_base + head->iov_len)
> +	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
>  		return 0;
> -	/*
> -	 * The count must equal the amount of data passed.
> -	 */
> -	if (args->count != args->len)
> +	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
> +		return 0;
> +	if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
>  		return 0;
>  
> -	/*
> -	 * Check to make sure that we got the right number of
> -	 * bytes.
> -	 */
> -	hdr = (void*)p - head->iov_base;
> -	dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr;
> -	/*
> -	 * Round the length of the data which was specified up to
> -	 * the next multiple of XDR units and then compare that
> -	 * against the length which was actually received.
> -	 * Note that when RPCSEC/GSS (for example) is used, the
> -	 * data buffer can be padded so dlen might be larger
> -	 * than required.  It must never be smaller.
> -	 */
> -	if (dlen < XDR_QUADLEN(len)*4)
> +	/* opaque data */
> +	if (xdr_stream_decode_u32(xdr, &args->len) < 0)
>  		return 0;
>  
> +	/* request sanity */
> +	if (args->count != args->len)
> +		return 0;
> +	remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
> +	remaining -= xdr_stream_pos(xdr);
> +	if (remaining < xdr_align_size(args->len))
> +		return 0;
>  	if (args->count > max_blocksize) {
>  		args->count = max_blocksize;
> -		len = args->len = max_blocksize;
> +		args->len = max_blocksize;
>  	}
>  
> -	args->first.iov_base = (void *)p;
> -	args->first.iov_len = head->iov_len - hdr;
> +	args->first.iov_base = xdr->p;
> +	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
> +
>  	return 1;
>  }
>  
> 

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

* Re: [PATCH v1 07/42] NFSD: Update WRITE3arg decoder to use struct xdr_stream
  2021-01-22 18:47   ` J. Bruce Fields
@ 2021-01-22 18:55     ` Chuck Lever
  0 siblings, 0 replies; 55+ messages in thread
From: Chuck Lever @ 2021-01-22 18:55 UTC (permalink / raw)
  To: Bruce Fields; +Cc: Linux NFS Mailing List



> On Jan 22, 2021, at 1:47 PM, J. Bruce Fields <bfields@fieldses.org> wrote:
> 
> On Tue, Jan 05, 2021 at 10:30:18AM -0500, Chuck Lever wrote:
>> As part of the update, open code that sanity-checks the size of the
>> data payload against the length of the RPC Call message has to be
>> re-implemented to use xdr_stream infrastructure.
> 
> I'm having a little trouble parsing that.  Did you mean "write code"?

The WRITE payload size sanity-checking code has to be re-implemented.


> --b.
> 
>> 
>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>> ---
>> fs/nfsd/nfs3xdr.c |   51 ++++++++++++++++++++-------------------------------
>> 1 file changed, 20 insertions(+), 31 deletions(-)
>> 
>> diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
>> index ff98eae5db81..0aafb096de91 100644
>> --- a/fs/nfsd/nfs3xdr.c
>> +++ b/fs/nfsd/nfs3xdr.c
>> @@ -405,52 +405,41 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
>> int
>> nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
>> {
>> +	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
>> 	struct nfsd3_writeargs *args = rqstp->rq_argp;
>> -	unsigned int len, hdr, dlen;
>> 	u32 max_blocksize = svc_max_payload(rqstp);
>> 	struct kvec *head = rqstp->rq_arg.head;
>> 	struct kvec *tail = rqstp->rq_arg.tail;
>> +	size_t remaining;
>> 
>> -	p = decode_fh(p, &args->fh);
>> -	if (!p)
>> +	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
>> 		return 0;
>> -	p = xdr_decode_hyper(p, &args->offset);
>> -
>> -	args->count = ntohl(*p++);
>> -	args->stable = ntohl(*p++);
>> -	len = args->len = ntohl(*p++);
>> -	if ((void *)p > head->iov_base + head->iov_len)
>> +	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
>> 		return 0;
>> -	/*
>> -	 * The count must equal the amount of data passed.
>> -	 */
>> -	if (args->count != args->len)
>> +	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
>> +		return 0;
>> +	if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
>> 		return 0;
>> 
>> -	/*
>> -	 * Check to make sure that we got the right number of
>> -	 * bytes.
>> -	 */
>> -	hdr = (void*)p - head->iov_base;
>> -	dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr;
>> -	/*
>> -	 * Round the length of the data which was specified up to
>> -	 * the next multiple of XDR units and then compare that
>> -	 * against the length which was actually received.
>> -	 * Note that when RPCSEC/GSS (for example) is used, the
>> -	 * data buffer can be padded so dlen might be larger
>> -	 * than required.  It must never be smaller.
>> -	 */
>> -	if (dlen < XDR_QUADLEN(len)*4)
>> +	/* opaque data */
>> +	if (xdr_stream_decode_u32(xdr, &args->len) < 0)
>> 		return 0;
>> 
>> +	/* request sanity */
>> +	if (args->count != args->len)
>> +		return 0;
>> +	remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
>> +	remaining -= xdr_stream_pos(xdr);
>> +	if (remaining < xdr_align_size(args->len))
>> +		return 0;
>> 	if (args->count > max_blocksize) {
>> 		args->count = max_blocksize;
>> -		len = args->len = max_blocksize;
>> +		args->len = max_blocksize;
>> 	}
>> 
>> -	args->first.iov_base = (void *)p;
>> -	args->first.iov_len = head->iov_len - hdr;
>> +	args->first.iov_base = xdr->p;
>> +	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
>> +
>> 	return 1;
>> }
>> 
>> 

--
Chuck Lever




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

* Re: [PATCH v1 00/42] Update NFSD XDR functions
  2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
                   ` (42 preceding siblings ...)
  2021-01-08  3:18 ` [PATCH v1 00/42] Update NFSD XDR functions J. Bruce Fields
@ 2021-01-22 19:58 ` J. Bruce Fields
  43 siblings, 0 replies; 55+ messages in thread
From: J. Bruce Fields @ 2021-01-22 19:58 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

ACK to the patches, looks good to me.--b.

On Tue, Jan 05, 2021 at 10:29:40AM -0500, Chuck Lever wrote:
> The long-term purpose is to convert the NFSD XDR encoder and decoder
> functions to use the struct xdr_stream API. This is a refactor and
> clean-up with few or no changes in behavior expected, but there are
> some long-term benefits:
> 
> - More robust input sanitization in the NFSD decoders.
> - Help make it possible to use common kernel library functions with
>   XDR stream APIs (for example, GSS-API).
> - Align the structure of the source code with the RFCs so it is
>   easier to learn, verify, and maintain our XDR implementation.
> - Removal of more than a hundred hidden dprintk() call sites.
> - Removal of as much explicit manipulation of pages as possible to
>   help make the eventual transition to xdr->bvecs smoother.
> 
> The current series focuses on NFSv2 and NFSv3 decoder changes. Please
> review and comment!
> 
> The full set of patches lives in a topic branch in my git repo:
> 
>  git://git.linux-nfs.org/projects/cel/cel-2.6.git nfsd-xdr_stream
> 
> 
> ---
> 
> Chuck Lever (42):
>       SUNRPC: Make trace_svc_process() display the RPC procedure symbolically
>       SUNRPC: Display RPC procedure names instead of proc numbers
>       SUNRPC: Move definition of XDR_UNIT
>       NFSD: Update GETATTR3args decoder to use struct xdr_stream
>       NFSD: Update ACCESS3arg decoder to use struct xdr_stream
>       NFSD: Update READ3arg decoder to use struct xdr_stream
>       NFSD: Update WRITE3arg decoder to use struct xdr_stream
>       NFSD: Update READLINK3arg decoder to use struct xdr_stream
>       NFSD: Fix returned READDIR offset cookie
>       NFSD: Add helper to set up the pages where the dirlist is encoded
>       NFSD: Update READDIR3args decoders to use struct xdr_stream
>       NFSD: Update COMMIT3arg decoder to use struct xdr_stream
>       NFSD: Update the NFSv3 DIROPargs decoder to use struct xdr_stream
>       NFSD: Update the RENAME3args decoder to use struct xdr_stream
>       NFSD: Update the LINK3args decoder to use struct xdr_stream
>       NFSD: Update the SETATTR3args decoder to use struct xdr_stream
>       NFSD: Update the CREATE3args decoder to use struct xdr_stream
>       NFSD: Update the MKDIR3args decoder to use struct xdr_stream
>       NFSD: Update the SYMLINK3args decoder to use struct xdr_stream
>       NFSD: Update the MKNOD3args decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 GETATTR argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 READ argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 WRITE argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 READLINK argument decoder to use struct xdr_stream
>       NFSD: Add helper to set up the pages where the dirlist is encoded
>       NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream
>       NFSD: Update NFSv2 diropargs decoding to use struct xdr_stream
>       NFSD: Update the NFSv2 RENAME argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 LINK argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 SETATTR argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 CREATE argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 SYMLINK argument decoder to use struct xdr_stream
>       NFSD: Remove argument length checking in nfsd_dispatch()
>       NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream
>       NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs
>       NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 ACL GETATTR argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 ACL ACCESS argument decoder to use struct xdr_stream
>       NFSD: Clean up after updating NFSv2 ACL decoders
>       NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream
>       NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream
>       NFSD: Clean up after updating NFSv3 ACL decoders
> 
> 
>  fs/nfs_common/nfsacl.c          |  52 +++
>  fs/nfsd/nfs2acl.c               |  62 ++--
>  fs/nfsd/nfs3acl.c               |  42 ++-
>  fs/nfsd/nfs3proc.c              |  71 +++--
>  fs/nfsd/nfs3xdr.c               | 538 ++++++++++++++++++--------------
>  fs/nfsd/nfsproc.c               |  74 +++--
>  fs/nfsd/nfssvc.c                |  34 --
>  fs/nfsd/nfsxdr.c                | 350 ++++++++++-----------
>  fs/nfsd/xdr.h                   |  12 +-
>  fs/nfsd/xdr3.h                  |  20 +-
>  include/linux/nfsacl.h          |   3 +
>  include/linux/sunrpc/msg_prot.h |   3 -
>  include/linux/sunrpc/xdr.h      |  13 +-
>  include/trace/events/sunrpc.h   |  15 +-
>  include/uapi/linux/nfs3.h       |   6 +
>  15 files changed, 680 insertions(+), 615 deletions(-)
> 
> --
> Chuck Lever

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

end of thread, other threads:[~2021-01-22 22:17 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-05 15:29 [PATCH v1 00/42] Update NFSD XDR functions Chuck Lever
2021-01-05 15:29 ` [PATCH v1 01/42] SUNRPC: Make trace_svc_process() display the RPC procedure symbolically Chuck Lever
2021-01-05 15:29 ` [PATCH v1 02/42] SUNRPC: Display RPC procedure names instead of proc numbers Chuck Lever
2021-01-05 15:29 ` [PATCH v1 03/42] SUNRPC: Move definition of XDR_UNIT Chuck Lever
2021-01-05 15:30 ` [PATCH v1 04/42] NFSD: Update GETATTR3args decoder to use struct xdr_stream Chuck Lever
2021-01-05 15:30 ` [PATCH v1 05/42] NFSD: Update ACCESS3arg " Chuck Lever
2021-01-05 15:30 ` [PATCH v1 06/42] NFSD: Update READ3arg " Chuck Lever
2021-01-05 15:30 ` [PATCH v1 07/42] NFSD: Update WRITE3arg " Chuck Lever
2021-01-22 18:47   ` J. Bruce Fields
2021-01-22 18:55     ` Chuck Lever
2021-01-05 15:30 ` [PATCH v1 08/42] NFSD: Update READLINK3arg " Chuck Lever
2021-01-05 15:30 ` [PATCH v1 09/42] NFSD: Fix returned READDIR offset cookie Chuck Lever
2021-01-05 15:30 ` [PATCH v1 10/42] NFSD: Add helper to set up the pages where the dirlist is encoded Chuck Lever
2021-01-05 15:30 ` [PATCH v1 11/42] NFSD: Update READDIR3args decoders to use struct xdr_stream Chuck Lever
2021-01-05 15:30 ` [PATCH v1 12/42] NFSD: Update COMMIT3arg decoder " Chuck Lever
2021-01-05 15:30 ` [PATCH v1 13/42] NFSD: Update the NFSv3 DIROPargs " Chuck Lever
2021-01-05 15:30 ` [PATCH v1 14/42] NFSD: Update the RENAME3args " Chuck Lever
2021-01-05 15:30 ` [PATCH v1 15/42] NFSD: Update the LINK3args " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 16/42] NFSD: Update the SETATTR3args " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 17/42] NFSD: Update the CREATE3args " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 18/42] NFSD: Update the MKDIR3args " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 19/42] NFSD: Update the SYMLINK3args " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 20/42] NFSD: Update the MKNOD3args " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 21/42] NFSD: Update the NFSv2 GETATTR argument " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 22/42] NFSD: Update the NFSv2 READ " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 23/42] NFSD: Update the NFSv2 WRITE " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 24/42] NFSD: Update the NFSv2 READLINK " Chuck Lever
2021-01-05 15:31 ` [PATCH v1 25/42] NFSD: Add helper to set up the pages where the dirlist is encoded Chuck Lever
2021-01-05 15:31 ` [PATCH v1 26/42] NFSD: Update the NFSv2 READDIR argument decoder to use struct xdr_stream Chuck Lever
2021-01-05 15:32 ` [PATCH v1 27/42] NFSD: Update NFSv2 diropargs decoding " Chuck Lever
2021-01-05 15:32 ` [PATCH v1 28/42] NFSD: Update the NFSv2 RENAME argument decoder " Chuck Lever
2021-01-05 15:32 ` [PATCH v1 29/42] NFSD: Update the NFSv2 LINK " Chuck Lever
2021-01-05 15:32 ` [PATCH v1 30/42] NFSD: Update the NFSv2 SETATTR " Chuck Lever
2021-01-05 15:32 ` [PATCH v1 31/42] NFSD: Update the NFSv2 CREATE " Chuck Lever
2021-01-05 15:32 ` [PATCH v1 32/42] NFSD: Update the NFSv2 SYMLINK " Chuck Lever
2021-01-05 15:32 ` [PATCH v1 33/42] NFSD: Remove argument length checking in nfsd_dispatch() Chuck Lever
2021-01-05 15:32 ` [PATCH v1 34/42] NFSD: Update the NFSv2 GETACL argument decoder to use struct xdr_stream Chuck Lever
2021-01-05 15:32 ` [PATCH v1 35/42] NFSD: Add an xdr_stream-based decoder for NFSv2/3 ACLs Chuck Lever
2021-01-05 15:32 ` [PATCH v1 36/42] NFSD: Update the NFSv2 SETACL argument decoder to use struct xdr_stream Chuck Lever
2021-01-05 15:32 ` [PATCH v1 37/42] NFSD: Update the NFSv2 ACL GETATTR " Chuck Lever
2021-01-05 15:33 ` [PATCH v1 38/42] NFSD: Update the NFSv2 ACL ACCESS " Chuck Lever
2021-01-05 15:33 ` [PATCH v1 39/42] NFSD: Clean up after updating NFSv2 ACL decoders Chuck Lever
2021-01-05 15:33 ` [PATCH v1 40/42] NFSD: Update the NFSv3 GETACL argument decoder to use struct xdr_stream Chuck Lever
2021-01-05 15:33 ` [PATCH v1 41/42] NFSD: Update the NFSv2 SETACL " Chuck Lever
2021-01-05 15:33 ` [PATCH v1 42/42] NFSD: Clean up after updating NFSv3 ACL decoders Chuck Lever
2021-01-08  3:18 ` [PATCH v1 00/42] Update NFSD XDR functions J. Bruce Fields
2021-01-08 15:50   ` Chuck Lever
2021-01-08 15:52     ` Bruce Fields
2021-01-08 15:56       ` Chuck Lever
2021-01-08 16:01         ` Bruce Fields
2021-01-08 16:35           ` Trond Myklebust
2021-01-08 18:08             ` bfields
2021-01-08 22:54               ` Trond Myklebust
2021-01-09 16:43                 ` Chuck Lever
2021-01-22 19:58 ` J. Bruce Fields

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