Linux-NFS Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v1 00/61] Update NFSD XDR functions
@ 2020-11-13 15:02 Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 01/61] NFSD: Fix returned READDIR offset cookie Chuck Lever
                   ` (60 more replies)
  0 siblings, 61 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

The purpose of this series is to convert the NFSD XDR encoder and
decoder functions to use the struct xdr_stream API. This is largely
a refactor/clean-up, but there are some long-term benefits:

- More robust input sanitization in the NFSD decoders
- Ability to use common kernel library functions with XDR stream
  APIs: for example GSS-API
- Align the code itself with the RFCs so it is easier to learn,
  understand, and verify our XDR implementation
- Removal of as much explicit manipulation of pages as possible to
  help make the transition to xdr->bvecs smoother

With this initial posting, I'm starting with just the NFSv4 decoder 
face lift to make it easier to review. However, these posted patches
and more are available in a topic branch in my git repo:

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

---

Chuck Lever (61):
      NFSD: Fix returned READDIR offset cookie
      SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer()
      SUNRPC: Prepare for xdr_stream-style decoding on the server-side
      NFSD: Add common helpers to decode void args and encode void results
      NFSD: Replace the internals of the READ_BUF() macro
      NFSD: Replace READ* macros in nfsd4_decode_access()
      NFSD: Replace READ* macros in nfsd4_decode_close()
      NFSD: Replace READ* macros in nfsd4_decode_commit()
      NFSD: Replace READ* macros in nfsd4_decode_create()
      NFSD: Replace READ* macros in nfsd4_decode_bitmap()
      NFSD: Replace READ* macros in nfsd4_decode_link()
      NFSD: Relocate nfsd4_decode_opaque()
      NFSD: Replace READ* macros in nfsd4_decode_lock()
      NFSD: Replace READ* macros in nfsd4_decode_lockt()
      NFSD: Replace READ* macros in nfsd4_decode_locku()
      NFSD: Replace READ* macros in nfsd4_decode_lookup()
      NFSD: Replace READ* macros in nfsd4_decode_time()
      NFSD: Replace READ* macros in nfsd4_decode_fattr()
      NFSD: Replace READ* macros in nfsd4_decode_open()
      NFSD: Replace READ* macros in nfsd4_decode_open_confirm()
      NFSD: Replace READ* macros in nfsd4_decode_open_downgrade()
      NFSD: Replace READ* macros in nfsd4_decode_putfh()
      NFSD: Replace READ* macros in nfsd4_decode_read()
      NFSD: Replace READ* macros in nfsd4_decode_readdir()
      NFSD: Replace READ* macros in nfsd4_decode_remove()
      NFSD: Replace READ* macros in nfsd4_decode_rename()
      NFSD: Replace READ* macros in nfsd4_decode_renew()
      NFSD: Replace READ* macros in nfsd4_decode_secinfo()
      NFSD: Replace READ* macros in nfsd4_decode_setclientid()
      NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm()
      NFSD: Replace READ* macros in nfsd4_decode_verify()
      NFSD: Replace READ* macros in nfsd4_decode_write()
      NFSD: Replace READ* macros in nfsd4_decode_release_lockowner()
      NFSD: Replace READ* macros in nfsd4_decode_cb_sec()
      NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl()
      NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session()
      NFSD: Add a separate decoder to handle state_protect_ops
      NFSD: Add a separate decoder for ssv_sp_parms
      NFSD: Add a helper to decode state_protect4_a
      NFSD: Replace READ* macros in nfsd4_decode_exchange_id()
      NFSD: Replace READ* macros in nfsd4_decode_create_session()
      NFSD: Replace READ* macros in nfsd4_decode_destroy_session()
      NFSD: Replace READ* macros in nfsd4_decode_free_stateid()
      NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo()
      NFSD: Replace READ* macros in nfsd4_decode_layoutcommit()
      NFSD: Replace READ* macros in nfsd4_decode_layoutget()
      NFSD: Replace READ* macros in nfsd4_decode_layoutreturn()
      NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name()
      NFSD: Replace READ* macros in nfsd4_decode_sequence()
      NFSD: Replace READ* macros in nfsd4_decode_test_stateid()
      NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid()
      NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete()
      NFSD: Replace READ* macros in nfsd4_decode_fallocate()
      NFSD: Replace READ* macros in nfsd4_decode_clone()
      NFSD: Replace READ* macros in nfsd4_decode_copy()
      NFSD: Replace READ* macros in nfsd4_decode_seek()
      NFSD: Replace READ* macros in nfsd4_decode_xattr_name()
      NFSD: Replace READ* macros in nfsd4_decode_setxattr()
      NFSD: Replace READ* macros in nfsd4_decode_listxattrs()
      NFSD: Replace READ* macros in nfsd4_decode_compound()
      NFSD: Remove macros that are no longer used


 fs/nfs/blocklayout/blocklayout.c          |    2 +-
 fs/nfs/blocklayout/dev.c                  |    2 +-
 fs/nfs/dir.c                              |    2 +-
 fs/nfs/filelayout/filelayout.c            |    2 +-
 fs/nfs/filelayout/filelayoutdev.c         |    2 +-
 fs/nfs/flexfilelayout/flexfilelayout.c    |    2 +-
 fs/nfs/flexfilelayout/flexfilelayoutdev.c |    2 +-
 fs/nfs/nfs42xdr.c                         |    2 +-
 fs/nfs/nfs4xdr.c                          |    6 +-
 fs/nfsd/nfs2acl.c                         |   21 +-
 fs/nfsd/nfs3acl.c                         |    8 +-
 fs/nfsd/nfs3proc.c                        |   10 +-
 fs/nfsd/nfs3xdr.c                         |   11 -
 fs/nfsd/nfs4proc.c                        |   24 +-
 fs/nfsd/nfs4state.c                       |    2 +-
 fs/nfsd/nfs4xdr.c                         | 2253 +++++++++++----------
 fs/nfsd/nfsd.h                            |    8 +
 fs/nfsd/nfsproc.c                         |   25 +-
 fs/nfsd/nfssvc.c                          |   27 +-
 fs/nfsd/nfsxdr.c                          |   10 -
 fs/nfsd/xdr.h                             |    2 -
 fs/nfsd/xdr3.h                            |    2 -
 fs/nfsd/xdr4.h                            |   28 +-
 include/linux/sunrpc/svc.h                |   16 +
 include/linux/sunrpc/xdr.h                |   71 +-
 include/uapi/linux/nfs4.h                 |    1 +
 net/sunrpc/auth_gss/gss_rpc_xdr.c         |    2 +-
 net/sunrpc/svc.c                          |    5 +
 net/sunrpc/xdr.c                          |   72 +-
 29 files changed, 1451 insertions(+), 1169 deletions(-)

--
Chuck Lever


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

* [PATCH v1 01/61] NFSD: Fix returned READDIR offset cookie
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
@ 2020-11-13 15:02 ` Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 02/61] SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer() Chuck Lever
                   ` (59 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

Code inspection shows that the server's NFSv3 READDIR implementation
returns the same offset cookie as the client sent, instead of the
last cookie it returns in the reply's dirlist. This is unlike the
NFSv2 READDIR, NFSv3 READDIRPLUS, and NFSv4 READDIR implementations,
and it's been like this since the beginning of kernel git history.

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 d9be589fed15..e0ad18d6b5a8 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -430,6 +430,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;
 
@@ -448,7 +449,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;
@@ -464,8 +467,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	[flat|nested] 70+ messages in thread

* [PATCH v1 02/61] SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 01/61] NFSD: Fix returned READDIR offset cookie Chuck Lever
@ 2020-11-13 15:02 ` Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 03/61] SUNRPC: Prepare for xdr_stream-style decoding on the server-side Chuck Lever
                   ` (58 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

Clean up: De-duplicate some frequently-used code.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfs/blocklayout/blocklayout.c          |    2 +
 fs/nfs/blocklayout/dev.c                  |    2 +
 fs/nfs/dir.c                              |    2 +
 fs/nfs/filelayout/filelayout.c            |    2 +
 fs/nfs/filelayout/filelayoutdev.c         |    2 +
 fs/nfs/flexfilelayout/flexfilelayout.c    |    2 +
 fs/nfs/flexfilelayout/flexfilelayoutdev.c |    2 +
 fs/nfs/nfs42xdr.c                         |    2 +
 fs/nfs/nfs4xdr.c                          |    6 +---
 fs/nfsd/nfs4proc.c                        |    2 +
 include/linux/sunrpc/xdr.h                |   43 ++++++++++++++++++++++++++++-
 net/sunrpc/auth_gss/gss_rpc_xdr.c         |    2 +
 net/sunrpc/xdr.c                          |   28 +++----------------
 13 files changed, 58 insertions(+), 39 deletions(-)

diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 08108b6d2fa1..3be6836074ae 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -697,7 +697,7 @@ bl_alloc_lseg(struct pnfs_layout_hdr *lo, struct nfs4_layoutget_res *lgr,
 
 	xdr_init_decode_pages(&xdr, &buf,
 			lgr->layoutp->pages, lgr->layoutp->len);
-	xdr_set_scratch_buffer(&xdr, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&xdr, scratch);
 
 	status = -EIO;
 	p = xdr_inline_decode(&xdr, 4);
diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c
index dec5880ac6de..acb1d22907da 100644
--- a/fs/nfs/blocklayout/dev.c
+++ b/fs/nfs/blocklayout/dev.c
@@ -510,7 +510,7 @@ bl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 		goto out;
 
 	xdr_init_decode_pages(&xdr, &buf, pdev->pages, pdev->pglen);
-	xdr_set_scratch_buffer(&xdr, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&xdr, scratch);
 
 	p = xdr_inline_decode(&xdr, sizeof(__be32));
 	if (!p)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index cb52db9a0cfb..2b1a680d7f3d 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -576,7 +576,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
 		goto out_nopages;
 
 	xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	do {
 		if (entry->label)
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 7f5aa0403e16..d158a500c25c 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -666,7 +666,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
 		return -ENOMEM;
 
 	xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8),
 	 * num_fh (4) */
diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c
index d913e818858f..86c3f7e69ec4 100644
--- a/fs/nfs/filelayout/filelayoutdev.c
+++ b/fs/nfs/filelayout/filelayoutdev.c
@@ -82,7 +82,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 		goto out_err;
 
 	xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* Get the stripe count (number of stripe index) */
 	p = xdr_inline_decode(&stream, 4);
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index a163533446fa..d7010686d39a 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -378,7 +378,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
 
 	xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages,
 			      lgr->layoutp->len);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* stripe unit and mirror_array_cnt */
 	rc = -EIO;
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 3eda40a320a5..c9b61b818ec1 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -69,7 +69,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
 	INIT_LIST_HEAD(&dsaddrs);
 
 	xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen);
-	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(&stream, scratch);
 
 	/* multipath count */
 	p = xdr_inline_decode(&stream, 4);
diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index 0dc31ad2362e..a7e513e2ec42 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -1540,7 +1540,7 @@ static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
 	struct compound_hdr hdr;
 	int status;
 
-	xdr_set_scratch_buffer(xdr, page_address(res->scratch), PAGE_SIZE);
+	xdr_set_scratch_page(xdr, res->scratch);
 
 	status = decode_compound_hdr(xdr, &hdr);
 	if (status)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index c6dbfcae7517..2eabe5add344 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -6403,10 +6403,8 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
 	struct compound_hdr hdr;
 	int status;
 
-	if (res->acl_scratch != NULL) {
-		void *p = page_address(res->acl_scratch);
-		xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
-	}
+	if (res->acl_scratch != NULL)
+		xdr_set_scratch_page(xdr, res->acl_scratch);
 	status = decode_compound_hdr(xdr, &hdr);
 	if (status)
 		goto out;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index ad2fa1a8e7ad..5fbda469fbfe 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -2275,7 +2275,7 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,
 	xdr->end = head->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
 	/* Tail and page_len should be zero at this point: */
 	buf->len = buf->head[0].iov_len;
-	xdr->scratch.iov_len = 0;
+	xdr_reset_scratch_buffer(xdr);
 	xdr->page_ptr = buf->pages - 1;
 	buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages)
 		- rqstp->rq_auth_slack;
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index ec2a22ccdc2a..6e9edb4dcc0f 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -248,7 +248,6 @@ extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf,
 			    __be32 *p, struct rpc_rqst *rqst);
 extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf,
 		struct page **pages, unsigned int len);
-extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen);
 extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
 extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
 extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
@@ -256,6 +255,48 @@ extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned in
 extern uint64_t xdr_align_data(struct xdr_stream *, uint64_t, uint32_t);
 extern uint64_t xdr_expand_hole(struct xdr_stream *, uint64_t, uint64_t);
 
+/**
+ * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
+ * @xdr: pointer to xdr_stream struct
+ * @buf: pointer to an empty buffer
+ * @buflen: size of 'buf'
+ *
+ * The scratch buffer is used when decoding from an array of pages.
+ * If an xdr_inline_decode() call spans across page boundaries, then
+ * we copy the data into the scratch buffer in order to allow linear
+ * access.
+ */
+static inline void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf,
+					  size_t buflen)
+{
+	xdr->scratch.iov_base = buf;
+	xdr->scratch.iov_len = buflen;
+}
+
+/**
+ * xdr_set_scratch_page - Attach a scratch buffer for decoding data
+ * @xdr: pointer to xdr_stream struct
+ * @page: an anonymous page
+ *
+ * See xdr_set_scratch_buffer().
+ */
+static inline void xdr_set_scratch_page(struct xdr_stream *xdr,
+					struct page *page)
+{
+	xdr_set_scratch_buffer(xdr, page_address(page), PAGE_SIZE);
+}
+
+/**
+ * xdr_reset_scratch_buffer - Clear scratch buffer information
+ * @xdr: pointer to xdr_stream struct
+ *
+ * See xdr_set_scratch_buffer().
+ */
+static inline void xdr_reset_scratch_buffer(struct xdr_stream *xdr)
+{
+	xdr_set_scratch_buffer(xdr, NULL, 0);
+}
+
 /**
  * xdr_stream_remaining - Return the number of bytes remaining in the stream
  * @xdr: pointer to struct xdr_stream
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
index 2ff7b7083eba..c636c648849b 100644
--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
@@ -789,7 +789,7 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
 	scratch = alloc_page(GFP_KERNEL);
 	if (!scratch)
 		return -ENOMEM;
-	xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE);
+	xdr_set_scratch_page(xdr, scratch);
 
 	/* res->status */
 	err = gssx_dec_status(xdr, &res->status);
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 28f81769a27c..c607744b3ea8 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -669,7 +669,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 	struct kvec *iov = buf->head;
 	int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
 
-	xdr_set_scratch_buffer(xdr, NULL, 0);
+	xdr_reset_scratch_buffer(xdr);
 	BUG_ON(scratch_len < 0);
 	xdr->buf = buf;
 	xdr->iov = iov;
@@ -713,7 +713,7 @@ inline void xdr_commit_encode(struct xdr_stream *xdr)
 	page = page_address(*xdr->page_ptr);
 	memcpy(xdr->scratch.iov_base, page, shift);
 	memmove(page, page + shift, (void *)xdr->p - page);
-	xdr->scratch.iov_len = 0;
+	xdr_reset_scratch_buffer(xdr);
 }
 EXPORT_SYMBOL_GPL(xdr_commit_encode);
 
@@ -743,8 +743,7 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr,
 	 * the "scratch" iov to track any temporarily unused fragment of
 	 * space at the end of the previous buffer:
 	 */
-	xdr->scratch.iov_base = xdr->p;
-	xdr->scratch.iov_len = frag1bytes;
+	xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes);
 	p = page_address(*xdr->page_ptr);
 	/*
 	 * Note this is where the next encode will start after we've
@@ -1052,8 +1051,7 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p,
 		     struct rpc_rqst *rqst)
 {
 	xdr->buf = buf;
-	xdr->scratch.iov_base = NULL;
-	xdr->scratch.iov_len = 0;
+	xdr_reset_scratch_buffer(xdr);
 	xdr->nwords = XDR_QUADLEN(buf->len);
 	if (buf->head[0].iov_len != 0)
 		xdr_set_iov(xdr, buf->head, buf->len);
@@ -1101,24 +1099,6 @@ static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
 	return p;
 }
 
-/**
- * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
- * @xdr: pointer to xdr_stream struct
- * @buf: pointer to an empty buffer
- * @buflen: size of 'buf'
- *
- * The scratch buffer is used when decoding from an array of pages.
- * If an xdr_inline_decode() call spans across page boundaries, then
- * we copy the data into the scratch buffer in order to allow linear
- * access.
- */
-void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen)
-{
-	xdr->scratch.iov_base = buf;
-	xdr->scratch.iov_len = buflen;
-}
-EXPORT_SYMBOL_GPL(xdr_set_scratch_buffer);
-
 static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes)
 {
 	__be32 *p;



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

* [PATCH v1 03/61] SUNRPC: Prepare for xdr_stream-style decoding on the server-side
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 01/61] NFSD: Fix returned READDIR offset cookie Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 02/61] SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer() Chuck Lever
@ 2020-11-13 15:02 ` Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 04/61] NFSD: Add common helpers to decode void args and encode void results Chuck Lever
                   ` (57 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

A "permanent" struct xdr_stream is allocated in struct svc_rqst so
that it is usable by all server-side decoders. A per-rqst scratch
buffer is also allocated to handle decoding XDR data items that
cross page boundaries.

To demonstrate how it will be used, add the first call site for the
new svcxdr_init_decode() API.

As an additional part of the overall conversion, add symbolic
constants for successful and failed XDR operations. Returning "0" is
overloaded. Sometimes it means something failed, but sometimes it
means success. To make it more clear when XDR decoding functions
succeed or fail, introduce symbolic constants.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4xdr.c          |    3 ++-
 fs/nfsd/nfssvc.c           |    4 +++-
 include/linux/sunrpc/svc.h |   16 ++++++++++++++++
 include/linux/sunrpc/xdr.h |    5 +++++
 net/sunrpc/svc.c           |    5 +++++
 5 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index e3c6bea83bd6..66274ad05a9c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5321,7 +5321,8 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 	args->ops = args->iops;
 	args->rqstp = rqstp;
 
-	return !nfsd4_decode_compound(args);
+	return nfsd4_decode_compound(args) == nfs_ok ?	XDR_DECODE_DONE :
+							XDR_DECODE_FAILED;
 }
 
 int
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 27b1ad136150..daeab72975a3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -1020,7 +1020,9 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 	 * (necessary in the NFSv4.0 compound case)
 	 */
 	rqstp->rq_cachetype = proc->pc_cachetype;
-	if (!proc->pc_decode(rqstp, argv->iov_base))
+
+	svcxdr_init_decode(rqstp, argv->iov_base);
+	if (proc->pc_decode(rqstp, argv->iov_base) == XDR_DECODE_FAILED)
 		goto out_decode_err;
 
 	switch (nfsd_cache_lookup(rqstp)) {
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index c220b734fa69..bb6c93283697 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -248,6 +248,8 @@ struct svc_rqst {
 	size_t			rq_xprt_hlen;	/* xprt header len */
 	struct xdr_buf		rq_arg;
 	struct xdr_buf		rq_res;
+	struct xdr_stream	rq_xdr_stream;
+	struct page		*rq_scratch_page;
 	struct page		*rq_pages[RPCSVC_MAXPAGES + 1];
 	struct page *		*rq_respages;	/* points into rq_pages */
 	struct page *		*rq_next_page; /* next reply page to use */
@@ -557,4 +559,18 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
 	svc_reserve(rqstp, space + rqstp->rq_auth_slack);
 }
 
+/**
+ * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding
+ * @rqstp: controlling server RPC transaction context
+ * @p: Starting position
+ *
+ */
+static inline void svcxdr_init_decode(struct svc_rqst *rqstp, __be32 *p)
+{
+	struct xdr_stream *xdr = &rqstp->rq_xdr_stream;
+
+	xdr_init_decode(xdr, &rqstp->rq_arg, p, NULL);
+	xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
+}
+
 #endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 6e9edb4dcc0f..3fffd7f15c3a 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -19,6 +19,11 @@
 struct bio_vec;
 struct rpc_rqst;
 
+enum xdr_decode_result {
+	XDR_DECODE_FAILED = 0,
+	XDR_DECODE_DONE = 1,
+};
+
 /*
  * Buffer adjustment
  */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index b41500645c3f..4187745887f0 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -614,6 +614,10 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node)
 	rqstp->rq_server = serv;
 	rqstp->rq_pool = pool;
 
+	rqstp->rq_scratch_page = alloc_pages_node(node, GFP_KERNEL, 0);
+	if (!rqstp->rq_scratch_page)
+		goto out_enomem;
+
 	rqstp->rq_argp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node);
 	if (!rqstp->rq_argp)
 		goto out_enomem;
@@ -842,6 +846,7 @@ void
 svc_rqst_free(struct svc_rqst *rqstp)
 {
 	svc_release_buffer(rqstp);
+	put_page(rqstp->rq_scratch_page);
 	kfree(rqstp->rq_resp);
 	kfree(rqstp->rq_argp);
 	kfree(rqstp->rq_auth_data);



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

* [PATCH v1 04/61] NFSD: Add common helpers to decode void args and encode void results
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (2 preceding siblings ...)
  2020-11-13 15:02 ` [PATCH v1 03/61] SUNRPC: Prepare for xdr_stream-style decoding on the server-side Chuck Lever
@ 2020-11-13 15:02 ` Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 05/61] NFSD: Replace the internals of the READ_BUF() macro Chuck Lever
                   ` (56 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

Start off the conversion to xdr_stream by de-duplicating the functions
that decode void arguments and encode void results.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs2acl.c  |   21 ++++-----------------
 fs/nfsd/nfs3acl.c  |    8 ++++----
 fs/nfsd/nfs3proc.c |   10 ++++------
 fs/nfsd/nfs3xdr.c  |   11 -----------
 fs/nfsd/nfs4proc.c |    8 ++++----
 fs/nfsd/nfs4xdr.c  |   12 ------------
 fs/nfsd/nfsd.h     |    8 ++++++++
 fs/nfsd/nfsproc.c  |   25 ++++++++++++-------------
 fs/nfsd/nfssvc.c   |   23 +++++++++++++++++++++++
 fs/nfsd/nfsxdr.c   |   10 ----------
 fs/nfsd/xdr.h      |    2 --
 fs/nfsd/xdr3.h     |    2 --
 fs/nfsd/xdr4.h     |    2 --
 13 files changed, 59 insertions(+), 83 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 6a900f770dd2..b0f66604532a 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -185,10 +185,6 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
 /*
  * XDR decode functions
  */
-static int nfsaclsvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
-{
-	return 1;
-}
 
 static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p)
 {
@@ -255,15 +251,6 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
  * XDR encode functions
  */
 
-/*
- * There must be an encoding function for void results so svc_process
- * will work properly.
- */
-static int nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_ressize_check(rqstp, p);
-}
-
 /* GETACL */
 static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
 {
@@ -378,10 +365,10 @@ struct nfsd3_voidargs { int dummy; };
 static const struct svc_procedure nfsd_acl_procedures2[5] = {
 	[ACLPROC2_NULL] = {
 		.pc_func = nfsacld_proc_null,
-		.pc_decode = nfsaclsvc_decode_voidarg,
-		.pc_encode = nfsaclsvc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd3_voidargs),
-		.pc_ressize = sizeof(struct nfsd3_voidargs),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
 	},
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 34a394e50e1d..7c30876a31a1 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -245,10 +245,10 @@ struct nfsd3_voidargs { int dummy; };
 static const struct svc_procedure nfsd_acl_procedures3[3] = {
 	[ACLPROC3_NULL] = {
 		.pc_func = nfsd3_proc_null,
-		.pc_decode = nfs3svc_decode_voidarg,
-		.pc_encode = nfs3svc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd3_voidargs),
-		.pc_ressize = sizeof(struct nfsd3_voidargs),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
 	},
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index e0ad18d6b5a8..581a93b17bee 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -693,8 +693,6 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
 #define nfsd3_attrstatres		nfsd3_attrstat
 #define nfsd3_wccstatres		nfsd3_attrstat
 #define nfsd3_createres			nfsd3_diropres
-#define nfsd3_voidres			nfsd3_voidargs
-struct nfsd3_voidargs { int dummy; };
 
 #define ST 1		/* status*/
 #define FH 17		/* filehandle with length */
@@ -705,10 +703,10 @@ struct nfsd3_voidargs { int dummy; };
 static const struct svc_procedure nfsd_procedures3[22] = {
 	[NFS3PROC_NULL] = {
 		.pc_func = nfsd3_proc_null,
-		.pc_decode = nfs3svc_decode_voidarg,
-		.pc_encode = nfs3svc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd3_voidargs),
-		.pc_ressize = sizeof(struct nfsd3_voidres),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = ST,
 	},
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 186b07a72373..a6718b952975 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -304,11 +304,6 @@ void fill_post_wcc(struct svc_fh *fhp)
 /*
  * XDR decode functions
  */
-int
-nfs3svc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
-{
-	return 1;
-}
 
 int
 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
@@ -642,12 +637,6 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p)
  * XDR encode functions
  */
 
-int
-nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_ressize_check(rqstp, p);
-}
-
 /* GETATTR */
 int
 nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 5fbda469fbfe..7295b8eeb43f 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -3300,10 +3300,10 @@ struct nfsd4_voidargs { int dummy; };
 static const struct svc_procedure nfsd_procedures4[2] = {
 	[NFSPROC4_NULL] = {
 		.pc_func = nfsd4_proc_null,
-		.pc_decode = nfs4svc_decode_voidarg,
-		.pc_encode = nfs4svc_encode_voidres,
-		.pc_argsize = sizeof(struct nfsd4_voidargs),
-		.pc_ressize = sizeof(struct nfsd4_voidres),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 1,
 	},
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 66274ad05a9c..6c3d45f68b75 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5271,12 +5271,6 @@ nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
 	p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
 }
 
-int
-nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
-{
-        return xdr_ressize_check(rqstp, p);
-}
-
 void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
 {
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
@@ -5294,12 +5288,6 @@ void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
 	}
 }
 
-int
-nfs4svc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
-{
-	return 1;
-}
-
 int
 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 {
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index cb742e17e04a..7907de3f2ee6 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -73,6 +73,14 @@ extern unsigned long		nfsd_drc_mem_used;
 
 extern const struct seq_operations nfs_exports_op;
 
+/*
+ * Common void argument and result helpers
+ */
+struct nfsd_voidargs { };
+struct nfsd_voidres { };
+int		nfssvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p);
+int		nfssvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p);
+
 /*
  * Function prototypes.
  */
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 0d71549f9d42..9473d048efec 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -609,7 +609,6 @@ nfsd_proc_statfs(struct svc_rqst *rqstp)
  * NFSv2 Server procedures.
  * Only the results of non-idempotent operations are cached.
  */
-struct nfsd_void { int dummy; };
 
 #define ST 1		/* status */
 #define FH 8		/* filehandle */
@@ -618,10 +617,10 @@ struct nfsd_void { int dummy; };
 static const struct svc_procedure nfsd_procedures2[18] = {
 	[NFSPROC_NULL] = {
 		.pc_func = nfsd_proc_null,
-		.pc_decode = nfssvc_decode_void,
-		.pc_encode = nfssvc_encode_void,
-		.pc_argsize = sizeof(struct nfsd_void),
-		.pc_ressize = sizeof(struct nfsd_void),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
 	},
@@ -647,10 +646,10 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_ROOT] = {
 		.pc_func = nfsd_proc_root,
-		.pc_decode = nfssvc_decode_void,
-		.pc_encode = nfssvc_encode_void,
-		.pc_argsize = sizeof(struct nfsd_void),
-		.pc_ressize = sizeof(struct nfsd_void),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
 	},
@@ -685,10 +684,10 @@ static const struct svc_procedure nfsd_procedures2[18] = {
 	},
 	[NFSPROC_WRITECACHE] = {
 		.pc_func = nfsd_proc_writecache,
-		.pc_decode = nfssvc_decode_void,
-		.pc_encode = nfssvc_encode_void,
-		.pc_argsize = sizeof(struct nfsd_void),
-		.pc_ressize = sizeof(struct nfsd_void),
+		.pc_decode = nfssvc_decode_voidarg,
+		.pc_encode = nfssvc_encode_voidres,
+		.pc_argsize = sizeof(struct nfsd_voidargs),
+		.pc_ressize = sizeof(struct nfsd_voidres),
 		.pc_cachetype = RC_NOCACHE,
 		.pc_xdrressize = 0,
 	},
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index daeab72975a3..cae6fbf10514 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -28,6 +28,7 @@
 #include "vfs.h"
 #include "netns.h"
 #include "filecache.h"
+#include "xdr.h"
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
 
@@ -1075,6 +1076,28 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 	return 1;
 }
 
+/**
+ * nfssvc_decode_voidarg - Decode void arguments
+ * @rqstp: Server RPC transaction context
+ * @p: buffer containing arguments to decode
+ *
+ */
+int nfssvc_decode_voidarg(struct svc_rqst *rqstp, __be32 *p)
+{
+	return XDR_DECODE_DONE;
+}
+
+/**
+ * nfssvc_encode_voidres - Encode void results
+ * @rqstp: Server RPC transaction context
+ * @p: buffer in which to encode results
+ *
+ */
+int nfssvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
+{
+        return xdr_ressize_check(rqstp, p);
+}
+
 int nfsd_pool_stats_open(struct inode *inode, struct file *file)
 {
 	int ret;
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 9e00a902113e..7aa6e8aca2c1 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -192,11 +192,6 @@ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *f
 /*
  * XDR decode functions
  */
-int
-nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_argsize_check(rqstp, p);
-}
 
 int
 nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
@@ -423,11 +418,6 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 /*
  * XDR encode functions
  */
-int
-nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p)
-{
-	return xdr_ressize_check(rqstp, p);
-}
 
 int
 nfssvc_encode_stat(struct svc_rqst *rqstp, __be32 *p)
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h
index 0ff336b0b25f..ad77387734cc 100644
--- a/fs/nfsd/xdr.h
+++ b/fs/nfsd/xdr.h
@@ -144,7 +144,6 @@ union nfsd_xdrstore {
 #define NFS2_SVC_XDRSIZE	sizeof(union nfsd_xdrstore)
 
 
-int nfssvc_decode_void(struct svc_rqst *, __be32 *);
 int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *);
 int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *);
 int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *);
@@ -156,7 +155,6 @@ 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 *);
-int nfssvc_encode_void(struct svc_rqst *, __be32 *);
 int nfssvc_encode_stat(struct svc_rqst *, __be32 *);
 int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *);
 int nfssvc_encode_diropres(struct svc_rqst *, __be32 *);
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index ae6fa6c9cb46..456fcd7a1038 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -273,7 +273,6 @@ union nfsd3_xdrstore {
 
 #define NFS3_SVC_XDRSIZE		sizeof(union nfsd3_xdrstore)
 
-int nfs3svc_decode_voidarg(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *);
@@ -290,7 +289,6 @@ int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *);
 int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *);
-int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *);
 int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *);
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 679d40af1bbb..37f89ad5e992 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -781,8 +781,6 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 
 
 bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp);
-int nfs4svc_decode_voidarg(struct svc_rqst *, __be32 *);
-int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *);
 int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *);
 int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *);
 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);



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

* [PATCH v1 05/61] NFSD: Replace the internals of the READ_BUF() macro
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (3 preceding siblings ...)
  2020-11-13 15:02 ` [PATCH v1 04/61] NFSD: Add common helpers to decode void args and encode void results Chuck Lever
@ 2020-11-13 15:02 ` Chuck Lever
  2020-11-13 15:02 ` [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access() Chuck Lever
                   ` (55 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

Convert the READ_BUF macro in nfs4xdr.c from open code to instead
use the new xdr_stream-style decoders already in use by the encode
side (and by the in-kernel NFS client implementation). Once this
conversion is done, each individual NFSv4 argument decoder can be
independently cleaned up to replace these macros with C code.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c         |    4 -
 fs/nfsd/nfs4xdr.c          |  181 ++++++--------------------------------------
 fs/nfsd/xdr4.h             |   10 --
 include/linux/sunrpc/xdr.h |    2 
 net/sunrpc/xdr.c           |   44 +++++++++++
 5 files changed, 76 insertions(+), 165 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 7295b8eeb43f..91197626d0d2 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1023,8 +1023,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	write->wr_how_written = write->wr_stable_how;
 
-	nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
-				      &write->wr_head, write->wr_buflen);
+	nvecs = svc_fill_write_vector(rqstp, write->wr_payload.pages,
+				      write->wr_payload.head, write->wr_buflen);
 	WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
 
 	status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6c3d45f68b75..26265d649c39 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -129,90 +129,13 @@ xdr_error:					\
 	memcpy((x), p, nbytes);			\
 	p += XDR_QUADLEN(nbytes);		\
 } while (0)
-
-/* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
-#define READ_BUF(nbytes)  do {			\
-	if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) {	\
-		p = argp->p;			\
-		argp->p += XDR_QUADLEN(nbytes);	\
-	} else if (!(p = read_buf(argp, nbytes))) { \
-		dprintk("NFSD: xdr error (%s:%d)\n", \
-				__FILE__, __LINE__); \
-		goto xdr_error;			\
-	}					\
-} while (0)
-
-static void next_decode_page(struct nfsd4_compoundargs *argp)
-{
-	argp->p = page_address(argp->pagelist[0]);
-	argp->pagelist++;
-	if (argp->pagelen < PAGE_SIZE) {
-		argp->end = argp->p + XDR_QUADLEN(argp->pagelen);
-		argp->pagelen = 0;
-	} else {
-		argp->end = argp->p + (PAGE_SIZE>>2);
-		argp->pagelen -= PAGE_SIZE;
-	}
-}
-
-static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
-{
-	/* We want more bytes than seem to be available.
-	 * Maybe we need a new page, maybe we have just run out
-	 */
-	unsigned int avail = (char *)argp->end - (char *)argp->p;
-	__be32 *p;
-
-	if (argp->pagelen == 0) {
-		struct kvec *vec = &argp->rqstp->rq_arg.tail[0];
-
-		if (!argp->tail) {
-			argp->tail = true;
-			avail = vec->iov_len;
-			argp->p = vec->iov_base;
-			argp->end = vec->iov_base + avail;
-		}
-
-		if (avail < nbytes)
-			return NULL;
-
-		p = argp->p;
-		argp->p += XDR_QUADLEN(nbytes);
-		return p;
-	}
-
-	if (avail + argp->pagelen < nbytes)
-		return NULL;
-	if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
-		return NULL;
-	/* ok, we can do it with the current plus the next page */
-	if (nbytes <= sizeof(argp->tmp))
-		p = argp->tmp;
-	else {
-		kfree(argp->tmpp);
-		p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
-		if (!p)
-			return NULL;
-		
-	}
-	/*
-	 * The following memcpy is safe because read_buf is always
-	 * called with nbytes > avail, and the two cases above both
-	 * guarantee p points to at least nbytes bytes.
-	 */
-	memcpy(p, argp->p, avail);
-	next_decode_page(argp);
-	memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
-	argp->p += XDR_QUADLEN(nbytes - avail);
-	return p;
-}
-
-static unsigned int compoundargs_bytes_left(struct nfsd4_compoundargs *argp)
-{
-	unsigned int this = (char *)argp->end - (char *)argp->p;
-
-	return this + argp->pagelen;
-}
+#define READ_BUF(nbytes)			\
+	do {					\
+		p = xdr_inline_decode(argp->xdr,\
+				      nbytes);	\
+		if (!p)				\
+			goto xdr_error;		\
+	} while (0)
 
 static int zero_clientid(clientid_t *clid)
 {
@@ -259,44 +182,6 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
 	return p;
 }
 
-static __be32
-svcxdr_construct_vector(struct nfsd4_compoundargs *argp, struct kvec *head,
-			struct page ***pagelist, u32 buflen)
-{
-	int avail;
-	int len;
-	int pages;
-
-	/* Sorry .. no magic macros for this.. *
-	 * READ_BUF(write->wr_buflen);
-	 * SAVEMEM(write->wr_buf, write->wr_buflen);
-	 */
-	avail = (char *)argp->end - (char *)argp->p;
-	if (avail + argp->pagelen < buflen) {
-		dprintk("NFSD: xdr error (%s:%d)\n",
-			       __FILE__, __LINE__);
-		return nfserr_bad_xdr;
-	}
-	head->iov_base = argp->p;
-	head->iov_len = avail;
-	*pagelist = argp->pagelist;
-
-	len = XDR_QUADLEN(buflen) << 2;
-	if (len >= avail) {
-		len -= avail;
-
-		pages = len >> PAGE_SHIFT;
-		argp->pagelist += pages;
-		argp->pagelen -= pages * PAGE_SIZE;
-		len -= pages * PAGE_SIZE;
-
-		next_decode_page(argp);
-	}
-	argp->p += XDR_QUADLEN(len);
-
-	return 0;
-}
-
 /**
  * savemem - duplicate a chunk of memory for later processing
  * @argp: NFSv4 compound argument structure to be freed with
@@ -396,7 +281,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		READ_BUF(4); len += 4;
 		nace = be32_to_cpup(p++);
 
-		if (nace > compoundargs_bytes_left(argp)/20)
+		if (nace > xdr_stream_remaining(argp->xdr) / sizeof(struct nfs4_ace))
 			/*
 			 * Even with 4-byte names there wouldn't be
 			 * space for that many aces; something fishy is
@@ -927,7 +812,7 @@ static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 
 static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
 {
-	__be32 *p;
+	DECODE_HEAD;
 
 	READ_BUF(4);
 	o->len = be32_to_cpup(p++);
@@ -937,9 +822,8 @@ static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_ne
 
 	READ_BUF(o->len);
 	SAVEMEM(o->data, o->len);
-	return nfs_ok;
-xdr_error:
-	return nfserr_bad_xdr;
+
+	DECODE_TAIL;
 }
 
 static __be32
@@ -1317,10 +1201,8 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 		goto xdr_error;
 	write->wr_buflen = be32_to_cpup(p++);
 
-	status = svcxdr_construct_vector(argp, &write->wr_head,
-					 &write->wr_pagelist, write->wr_buflen);
-	if (status)
-		return status;
+	if (!xdr_stream_subsegment(argp->xdr, &write->wr_payload, write->wr_buflen))
+		goto xdr_error;
 
 	DECODE_TAIL;
 }
@@ -1889,13 +1771,14 @@ nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
  */
 
 /*
- * Decode data into buffer. Uses head and pages constructed by
- * svcxdr_construct_vector.
+ * Decode data into buffer.
  */
 static __be32
-nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct kvec *head,
-		       struct page **pages, char **bufp, u32 buflen)
+nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
+		       char **bufp, u32 buflen)
 {
+	struct page **pages = xdr->pages;
+	struct kvec *head = xdr->head;
 	char *tmp, *dp;
 	u32 len;
 
@@ -2010,8 +1893,6 @@ nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 {
 	DECODE_HEAD;
 	u32 flags, maxcount, size;
-	struct kvec head;
-	struct page **pagelist;
 
 	READ_BUF(4);
 	flags = be32_to_cpup(p++);
@@ -2034,12 +1915,12 @@ nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 
 	setxattr->setxa_len = size;
 	if (size > 0) {
-		status = svcxdr_construct_vector(argp, &head, &pagelist, size);
-		if (status)
-			return status;
+		struct xdr_buf payload;
 
-		status = nfsd4_vbuf_from_vector(argp, &head, pagelist,
-		    &setxattr->setxa_buf, size);
+		if (!xdr_stream_subsegment(argp->xdr, &payload, size))
+			goto xdr_error;
+		status = nfsd4_vbuf_from_vector(argp, &payload,
+						&setxattr->setxa_buf, size);
 	}
 
 	DECODE_TAIL;
@@ -5279,8 +5160,6 @@ void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
 		kfree(args->ops);
 		args->ops = args->iops;
 	}
-	kfree(args->tmpp);
-	args->tmpp = NULL;
 	while (args->to_free) {
 		struct svcxdr_tmpbuf *tb = args->to_free;
 		args->to_free = tb->next;
@@ -5293,19 +5172,11 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 {
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
 
-	if (rqstp->rq_arg.head[0].iov_len % 4) {
-		/* client is nuts */
-		dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)",
-			__func__, svc_addr(rqstp), be32_to_cpu(rqstp->rq_xid));
-		return 0;
-	}
-	args->p = p;
-	args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
-	args->pagelist = rqstp->rq_arg.pages;
-	args->pagelen = rqstp->rq_arg.page_len;
-	args->tail = false;
+	/* svcxdr_tmp_alloc */
 	args->tmpp = NULL;
 	args->to_free = NULL;
+
+	args->xdr = &rqstp->rq_xdr_stream;
 	args->ops = args->iops;
 	args->rqstp = rqstp;
 
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 37f89ad5e992..0eb13bd603ea 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -419,8 +419,7 @@ struct nfsd4_write {
 	u64		wr_offset;          /* request */
 	u32		wr_stable_how;      /* request */
 	u32		wr_buflen;          /* request */
-	struct kvec	wr_head;
-	struct page **	wr_pagelist;        /* request */
+	struct xdr_buf	wr_payload;         /* request */
 
 	u32		wr_bytes_written;   /* response */
 	u32		wr_how_written;     /* response */
@@ -696,15 +695,10 @@ struct svcxdr_tmpbuf {
 
 struct nfsd4_compoundargs {
 	/* scratch variables for XDR decode */
-	__be32 *			p;
-	__be32 *			end;
-	struct page **			pagelist;
-	int				pagelen;
-	bool				tail;
 	__be32				tmp[8];
 	__be32 *			tmpp;
+	struct xdr_stream		*xdr;
 	struct svcxdr_tmpbuf		*to_free;
-
 	struct svc_rqst			*rqstp;
 
 	u32				taglen;
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 3fffd7f15c3a..579beeb0dac2 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -259,6 +259,8 @@ extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len);
 extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data);
 extern uint64_t xdr_align_data(struct xdr_stream *, uint64_t, uint32_t);
 extern uint64_t xdr_expand_hole(struct xdr_stream *, uint64_t, uint64_t);
+extern bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
+				  unsigned int len);
 
 /**
  * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data.
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index c607744b3ea8..272c9d566e6a 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1407,6 +1407,50 @@ int xdr_buf_subsegment(const struct xdr_buf *buf, struct xdr_buf *subbuf,
 }
 EXPORT_SYMBOL_GPL(xdr_buf_subsegment);
 
+/**
+ * xdr_stream_subsegment - set @subbuf to a portion of @xdr
+ * @xdr: an xdr_stream set up for decoding
+ * @subbuf: the result buffer
+ * @nbytes: length of @xdr to extract, in bytes
+ *
+ * Sets up @subbuf to represent a portion of @xdr. The portion
+ * starts at the current offset in @xdr, and extends for a length
+ * of @nbytes. If this is successful, @xdr is advanced to the next
+ * position following that portion.
+ *
+ * Return values:
+ *   %true: @subbuf has been initialized, and @xdr has been advanced.
+ *   %false: a bounds error occurred; @xdr is unchanged.
+ */
+bool xdr_stream_subsegment(struct xdr_stream *xdr, struct xdr_buf *subbuf,
+			   unsigned int nbytes)
+{
+	unsigned int len, remaining, offset;
+
+	if (xdr_buf_subsegment(xdr->buf, subbuf, xdr_stream_pos(xdr), nbytes))
+		return false;
+
+	if (subbuf->head[0].iov_len)
+		__xdr_inline_decode(xdr, subbuf->head[0].iov_len);
+
+	remaining = subbuf->page_len;
+	offset = subbuf->page_base;
+	while (remaining) {
+		len = min_t(unsigned int, remaining, PAGE_SIZE);
+		len -= offset;
+
+		if (xdr->p == xdr->end)
+			xdr_set_next_buffer(xdr);
+		__xdr_inline_decode(xdr, len);
+
+		remaining -= len;
+		offset = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(xdr_stream_subsegment);
+
 /**
  * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
  * @buf: buf to be trimmed



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

* [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (4 preceding siblings ...)
  2020-11-13 15:02 ` [PATCH v1 05/61] NFSD: Replace the internals of the READ_BUF() macro Chuck Lever
@ 2020-11-13 15:02 ` Chuck Lever
  2020-11-14  9:28   ` Christoph Hellwig
  2020-11-13 15:03 ` [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close() Chuck Lever
                   ` (54 subsequent siblings)
  60 siblings, 1 reply; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:02 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 26265d649c39..ee9ba5f0faff 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -437,17 +437,6 @@ nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
 	DECODE_TAIL;
 }
 
-static __be32
-nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	access->ac_req_access = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 {
 	DECODE_HEAD;
@@ -529,6 +518,18 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
 	DECODE_TAIL;
 }
 
+/*
+ * NFSv4 operation argument decoders
+ */
+
+static __be32
+nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &access->ac_req_access) < 0)
+		return nfserr_bad_xdr;
+	return nfs_ok;
+}
+
 static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
 {
 	DECODE_HEAD;



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

* [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (5 preceding siblings ...)
  2020-11-13 15:02 ` [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-14  9:29   ` Christoph Hellwig
  2020-11-13 15:03 ` [PATCH v1 08/61] NFSD: Replace READ* macros in nfsd4_decode_commit() Chuck Lever
                   ` (53 subsequent siblings)
  60 siblings, 1 reply; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ee9ba5f0faff..b04407d492bb 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -426,15 +426,18 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 }
 
 static __be32
-nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
+nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 {
-	DECODE_HEAD;
+	__be32 *p;
 
-	READ_BUF(sizeof(stateid_t));
+	p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
+	if (!p)
+		goto xdr_error;
 	sid->si_generation = be32_to_cpup(p++);
-	COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
-
-	DECODE_TAIL;
+	memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
@@ -556,13 +559,12 @@ static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	close->cl_seqid = be32_to_cpup(p++);
-	return nfsd4_decode_stateid(argp, &close->cl_stateid);
+	if (xdr_stream_decode_u32(argp->xdr, &close->cl_seqid) < 0)
+		goto xdr_error;
+	return nfsd4_decode_stateid4(argp, &close->cl_stateid);
 
-	DECODE_TAIL;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 
@@ -626,7 +628,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 static inline __be32
 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
 {
-	return nfsd4_decode_stateid(argp, &dr->dr_stateid);
+	return nfsd4_decode_stateid4(argp, &dr->dr_stateid);
 }
 
 static inline __be32
@@ -670,7 +672,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 	if (lock->lk_is_new) {
 		READ_BUF(4);
 		lock->lk_new_open_seqid = be32_to_cpup(p++);
-		status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
+		status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
 		if (status)
 			return status;
 		READ_BUF(8 + sizeof(clientid_t));
@@ -680,7 +682,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 		READ_BUF(lock->lk_new_owner.len);
 		READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
 	} else {
-		status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
+		status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
 		if (status)
 			return status;
 		READ_BUF(4);
@@ -719,7 +721,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 	if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
 		goto xdr_error;
 	locku->lu_seqid = be32_to_cpup(p++);
-	status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
+	status = nfsd4_decode_stateid4(argp, &locku->lu_stateid);
 	if (status)
 		return status;
 	READ_BUF(16);
@@ -912,7 +914,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 		open->op_delegate_type = be32_to_cpup(p++);
 		break;
 	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
-		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
+		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
 		if (status)
 			return status;
 		READ_BUF(4);
@@ -931,7 +933,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
 		if (argp->minorversion < 1)
 			goto xdr_error;
-		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
+		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
 		if (status)
 			return status;
 		break;
@@ -950,7 +952,7 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
+	status = nfsd4_decode_stateid4(argp, &open_conf->oc_req_stateid);
 	if (status)
 		return status;
 	READ_BUF(4);
@@ -964,7 +966,7 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
 {
 	DECODE_HEAD;
 		    
-	status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
+	status = nfsd4_decode_stateid4(argp, &open_down->od_stateid);
 	if (status)
 		return status;
 	READ_BUF(4);
@@ -1007,7 +1009,7 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 {
 	DECODE_HEAD;
 
-	status = nfsd4_decode_stateid(argp, &read->rd_stateid);
+	status = nfsd4_decode_stateid4(argp, &read->rd_stateid);
 	if (status)
 		return status;
 	READ_BUF(12);
@@ -1115,7 +1117,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
 {
 	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
+	status = nfsd4_decode_stateid4(argp, &setattr->sa_stateid);
 	if (status)
 		return status;
 	return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
@@ -1192,7 +1194,7 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 {
 	DECODE_HEAD;
 
-	status = nfsd4_decode_stateid(argp, &write->wr_stateid);
+	status = nfsd4_decode_stateid4(argp, &write->wr_stateid);
 	if (status)
 		return status;
 	READ_BUF(16);
@@ -1437,7 +1439,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta
 		INIT_LIST_HEAD(&stateid->ts_id_list);
 		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
 
-		status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
+		status = nfsd4_decode_stateid4(argp, &stateid->ts_id_stateid);
 		if (status)
 			goto out;
 	}
@@ -1513,7 +1515,7 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 	p = xdr_decode_hyper(p, &lgp->lg_seg.length);
 	p = xdr_decode_hyper(p, &lgp->lg_minlength);
 
-	status = nfsd4_decode_stateid(argp, &lgp->lg_sid);
+	status = nfsd4_decode_stateid4(argp, &lgp->lg_sid);
 	if (status)
 		return status;
 
@@ -1535,7 +1537,7 @@ nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
 	p = xdr_decode_hyper(p, &lcp->lc_seg.length);
 	lcp->lc_reclaim = be32_to_cpup(p++);
 
-	status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
+	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
 	if (status)
 		return status;
 
@@ -1587,7 +1589,7 @@ nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
 		p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
 		p = xdr_decode_hyper(p, &lrp->lr_seg.length);
 
-		status = nfsd4_decode_stateid(argp, &lrp->lr_sid);
+		status = nfsd4_decode_stateid4(argp, &lrp->lr_sid);
 		if (status)
 			return status;
 
@@ -1612,7 +1614,7 @@ nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 {
 	DECODE_HEAD;
 
-	status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
+	status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid);
 	if (status)
 		return status;
 
@@ -1628,10 +1630,10 @@ nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
 {
 	DECODE_HEAD;
 
-	status = nfsd4_decode_stateid(argp, &clone->cl_src_stateid);
+	status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid);
 	if (status)
 		return status;
-	status = nfsd4_decode_stateid(argp, &clone->cl_dst_stateid);
+	status = nfsd4_decode_stateid4(argp, &clone->cl_dst_stateid);
 	if (status)
 		return status;
 
@@ -1684,10 +1686,10 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 	struct nl4_server *ns_dummy;
 	int i, count;
 
-	status = nfsd4_decode_stateid(argp, &copy->cp_src_stateid);
+	status = nfsd4_decode_stateid4(argp, &copy->cp_src_stateid);
 	if (status)
 		return status;
-	status = nfsd4_decode_stateid(argp, &copy->cp_dst_stateid);
+	status = nfsd4_decode_stateid4(argp, &copy->cp_dst_stateid);
 	if (status)
 		return status;
 
@@ -1731,7 +1733,7 @@ static __be32
 nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
 			    struct nfsd4_offload_status *os)
 {
-	return nfsd4_decode_stateid(argp, &os->stateid);
+	return nfsd4_decode_stateid4(argp, &os->stateid);
 }
 
 static __be32
@@ -1740,7 +1742,7 @@ nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
 {
 	__be32 status;
 
-	status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid);
+	status = nfsd4_decode_stateid4(argp, &cn->cpn_src_stateid);
 	if (status)
 		return status;
 	return nfsd4_decode_nl4_server(argp, &cn->cpn_dst);
@@ -1751,7 +1753,7 @@ nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 {
 	DECODE_HEAD;
 
-	status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
+	status = nfsd4_decode_stateid4(argp, &seek->seek_stateid);
 	if (status)
 		return status;
 



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

* [PATCH v1 08/61] NFSD: Replace READ* macros in nfsd4_decode_commit()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (6 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 09/61] NFSD: Replace READ* macros in nfsd4_decode_create() Chuck Lever
                   ` (52 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4xdr.c          |   14 +++++++-------
 include/linux/sunrpc/xdr.h |   21 +++++++++++++++++++++
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b04407d492bb..2c69bf10d556 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -571,13 +571,13 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 static __be32
 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
 {
-	DECODE_HEAD;
-
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &commit->co_offset);
-	commit->co_count = be32_to_cpup(p++);
-
-	DECODE_TAIL;
+	if (xdr_stream_decode_u64(argp->xdr, &commit->co_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &commit->co_count) < 0)
+		goto xdr_error;
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 579beeb0dac2..0bee0a6dfc07 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -575,6 +575,27 @@ xdr_stream_decode_u32(struct xdr_stream *xdr, __u32 *ptr)
 	return 0;
 }
 
+/**
+ * xdr_stream_decode_u64 - Decode a 64-bit integer
+ * @xdr: pointer to xdr_stream
+ * @ptr: location to store 64-bit integer
+ *
+ * Return values:
+ *   %0 on success
+ *   %-EBADMSG on XDR buffer overflow
+ */
+static inline ssize_t
+xdr_stream_decode_u64(struct xdr_stream *xdr, __u64 *ptr)
+{
+	const size_t count = sizeof(*ptr);
+	__be32 *p = xdr_inline_decode(xdr, count);
+
+	if (unlikely(!p))
+		return -EBADMSG;
+	xdr_decode_hyper(p, ptr);
+	return 0;
+}
+
 /**
  * xdr_stream_decode_opaque_fixed - Decode fixed length opaque xdr data
  * @xdr: pointer to xdr_stream



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

* [PATCH v1 09/61] NFSD: Replace READ* macros in nfsd4_decode_create()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (7 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 08/61] NFSD: Replace READ* macros in nfsd4_decode_commit() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 10/61] NFSD: Replace READ* macros in nfsd4_decode_bitmap() Chuck Lever
                   ` (51 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 2c69bf10d556..3cd5b2c843d8 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -90,6 +90,8 @@ check_filename(char *str, int len)
 
 	if (len == 0)
 		return nfserr_inval;
+	if (len > NFS4_MAXNAMLEN)
+		return nfserr_nametoolong;
 	if (isdotent(str, len))
 		return nfserr_badname;
 	for (i = 0; i < len; i++)
@@ -203,6 +205,32 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 	return ret;
 }
 
+static __be32 nfsd4_decode_component4(struct nfsd4_compoundargs *argp,
+				      char **namp, u32 *lenp)
+{
+	__be32 *p, status;
+
+	if (xdr_stream_decode_u32(argp->xdr, lenp) < 0)
+		goto xdr_error;
+	p = xdr_inline_decode(argp->xdr, *lenp);
+	if (!p)
+		goto xdr_error;
+	status = check_filename((char *)p, *lenp);
+	if (status)
+		goto out;
+	*namp = svcxdr_tmpalloc(argp, *lenp);
+	if (!*namp)
+		goto nomem;
+	memcpy(*namp, p, *lenp);
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
+}
+
 static __be32
 nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 {
@@ -583,24 +611,27 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit
 static __be32
 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
-	READ_BUF(4);
-	create->cr_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &create->cr_type) < 0)
+		goto xdr_error;
 	switch (create->cr_type) {
 	case NF4LNK:
-		READ_BUF(4);
-		create->cr_datalen = be32_to_cpup(p++);
-		READ_BUF(create->cr_datalen);
+		if (xdr_stream_decode_u32(argp->xdr, &create->cr_datalen) < 0)
+			goto xdr_error;
+		p = xdr_inline_decode(argp->xdr, create->cr_datalen);
+		if (!p)
+			goto xdr_error;
 		create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
 		if (!create->cr_data)
 			return nfserr_jukebox;
 		break;
 	case NF4BLK:
 	case NF4CHR:
-		READ_BUF(8);
-		create->cr_specdata1 = be32_to_cpup(p++);
-		create->cr_specdata2 = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata1) < 0)
+			goto xdr_error;
+		if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata2) < 0)
+			goto xdr_error;
 		break;
 	case NF4SOCK:
 	case NF4FIFO:
@@ -609,20 +640,20 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 		break;
 	}
 
-	READ_BUF(4);
-	create->cr_namelen = be32_to_cpup(p++);
-	READ_BUF(create->cr_namelen);
-	SAVEMEM(create->cr_name, create->cr_namelen);
-	if ((status = check_filename(create->cr_name, create->cr_namelen)))
-		return status;
-
+	status = nfsd4_decode_component4(argp, &create->cr_name,
+					 &create->cr_namelen);
+	if (status)
+		goto out;
 	status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
 				    &create->cr_acl, &create->cr_label,
 				    &create->cr_umask);
 	if (status)
 		goto out;
 
-	DECODE_TAIL;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static inline __be32



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

* [PATCH v1 10/61] NFSD: Replace READ* macros in nfsd4_decode_bitmap()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (8 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 09/61] NFSD: Replace READ* macros in nfsd4_decode_create() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 11/61] NFSD: Replace READ* macros in nfsd4_decode_link() Chuck Lever
                   ` (50 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3cd5b2c843d8..bc36c746b293 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -246,29 +246,29 @@ nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 }
 
 static __be32
-nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
+nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval,
+		     u32 bmlen)
 {
-	u32 bmlen;
-	DECODE_HEAD;
+	__be32 *p;
+	u32 len, i;
 
-	bmval[0] = 0;
-	bmval[1] = 0;
-	bmval[2] = 0;
+	for (i = 0; i < bmlen; i++)
+		bmval[i] = 0;
 
-	READ_BUF(4);
-	bmlen = be32_to_cpup(p++);
-	if (bmlen > 1000)
+	if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
+		goto xdr_error;
+	if (len > 1000)
 		goto xdr_error;
 
-	READ_BUF(bmlen << 2);
-	if (bmlen > 0)
-		bmval[0] = be32_to_cpup(p++);
-	if (bmlen > 1)
-		bmval[1] = be32_to_cpup(p++);
-	if (bmlen > 2)
-		bmval[2] = be32_to_cpup(p++);
+	p = xdr_inline_decode(argp->xdr, len << 2);
+	if (!p)
+		goto xdr_error;
+	for (i = 0; i < len && i < bmlen; i++)
+		bmval[i] = be32_to_cpup(p++);
 
-	DECODE_TAIL;
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32
@@ -282,8 +282,9 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 
 	DECODE_HEAD;
 	iattr->ia_valid = 0;
-	if ((status = nfsd4_decode_bitmap(argp, bmval)))
-		return status;
+	status = nfsd4_decode_bitmap4(argp, bmval, 3);
+	if (status)
+		goto out;
 
 	if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
 	    || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
@@ -665,7 +666,8 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu
 static inline __be32
 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 {
-	return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
+	return nfsd4_decode_bitmap4(argp, getattr->ga_bmval,
+				    ARRAY_SIZE(getattr->ga_bmval));
 }
 
 static __be32
@@ -1060,7 +1062,9 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
 	COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
 	readdir->rd_dircount = be32_to_cpup(p++);
 	readdir->rd_maxcount = be32_to_cpup(p++);
-	if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
+	status = nfsd4_decode_bitmap4(argp, readdir->rd_bmval,
+				      ARRAY_SIZE(readdir->rd_bmval));
+	if (status)
 		goto out;
 
 	DECODE_TAIL;
@@ -1206,7 +1210,9 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
 {
 	DECODE_HEAD;
 
-	if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
+	status = nfsd4_decode_bitmap4(argp, verify->ve_bmval,
+				      ARRAY_SIZE(verify->ve_bmval));
+	if (status)
 		goto out;
 
 	/* For convenience's sake, we compare raw xdr'd attributes in
@@ -1285,12 +1291,13 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 		break;
 	case SP4_MACH_CRED:
 		/* spo_must_enforce */
-		status = nfsd4_decode_bitmap(argp,
-					exid->spo_must_enforce);
+		status = nfsd4_decode_bitmap4(argp, exid->spo_must_enforce,
+					      ARRAY_SIZE(exid->spo_must_enforce));
 		if (status)
 			goto out;
 		/* spo_must_allow */
-		status = nfsd4_decode_bitmap(argp, exid->spo_must_allow);
+		status = nfsd4_decode_bitmap4(argp, exid->spo_must_allow,
+					      ARRAY_SIZE(exid->spo_must_allow));
 		if (status)
 			goto out;
 		break;



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

* [PATCH v1 11/61] NFSD: Replace READ* macros in nfsd4_decode_link()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (9 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 10/61] NFSD: Replace READ* macros in nfsd4_decode_bitmap() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 12/61] NFSD: Relocate nfsd4_decode_opaque() Chuck Lever
                   ` (49 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bc36c746b293..970c647f8df6 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -673,16 +673,7 @@ nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *geta
 static __be32
 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	link->li_namelen = be32_to_cpup(p++);
-	READ_BUF(link->li_namelen);
-	SAVEMEM(link->li_name, link->li_namelen);
-	if ((status = check_filename(link->li_name, link->li_namelen)))
-		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
 }
 
 static __be32



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

* [PATCH v1 12/61] NFSD: Relocate nfsd4_decode_opaque()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (10 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 11/61] NFSD: Replace READ* macros in nfsd4_decode_link() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 13/61] NFSD: Replace READ* macros in nfsd4_decode_lock() Chuck Lever
                   ` (48 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

Enable nfsd4_decode_opaque() to be used in more decoders, and
replace the READ* macros in nfsd4_decode_opaque().

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 970c647f8df6..c621a38e7874 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -205,6 +205,36 @@ static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 	return ret;
 }
 
+
+/*
+ * NFSv4 basic data type decoders
+ */
+
+static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
+{
+	__be32 *p;
+	u32 len;
+
+	if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
+		goto xdr_error;
+	if (len == 0 || len > NFS4_OPAQUE_LIMIT)
+		return nfserr_bad_xdr;
+	p = xdr_inline_decode(argp->xdr, len);
+	if (!p)
+		goto xdr_error;
+	o->data = svcxdr_tmpalloc(argp, len);
+	if (!o->data)
+		goto nomem;
+	o->len = len;
+	memcpy(o->data, p, len);
+
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
+}
+
 static __be32 nfsd4_decode_component4(struct nfsd4_compoundargs *argp,
 				      char **namp, u32 *lenp)
 {
@@ -837,22 +867,6 @@ static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 	return nfserr_bad_xdr;
 }
 
-static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	o->len = be32_to_cpup(p++);
-
-	if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
-		return nfserr_bad_xdr;
-
-	READ_BUF(o->len);
-	SAVEMEM(o->data, o->len);
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {



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

* [PATCH v1 13/61] NFSD: Replace READ* macros in nfsd4_decode_lock()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (11 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 12/61] NFSD: Relocate nfsd4_decode_opaque() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 14/61] NFSD: Replace READ* macros in nfsd4_decode_lockt() Chuck Lever
                   ` (47 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4xdr.c         |  121 +++++++++++++++++++++++++++++++++------------
 include/uapi/linux/nfs4.h |    1 
 2 files changed, 91 insertions(+), 31 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c621a38e7874..35329e3d1339 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -484,6 +484,32 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	DECODE_TAIL;
 }
 
+static __be32 nfsd4_decode_clientid4(struct nfsd4_compoundargs *argp,
+				     clientid_t *clientid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_CLIENTID_SIZE);
+	if (!p)
+		goto xdr_error;
+	memcpy(clientid, p, sizeof(*clientid));
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
+static __be32 nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
+					clientid_t *clientid,
+					struct xdr_netobj *owner)
+{
+	__be32 status;
+
+	status = nfsd4_decode_clientid4(argp, clientid);
+	if (status)
+		return status;
+	return nfsd4_decode_opaque(argp, owner);
+}
+
 static __be32
 nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 {
@@ -706,44 +732,77 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 	return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
 }
 
+static __be32
+nfsd4_decode_open_to_lock_owner4(struct nfsd4_compoundargs *argp,
+				 struct nfsd4_lock *lock)
+{
+	__be32 status;
+
+	lock->lk_is_new = 1;
+
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_open_seqid) < 0)
+		goto xdr_error;
+	status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
+	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_lock_seqid) < 0)
+		goto xdr_error;
+	status = nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
+					   &lock->lk_new_owner);
+
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
+static __be32
+nfsd4_decode_exist_lock_owner4(struct nfsd4_compoundargs *argp,
+			       struct nfsd4_lock *lock)
+{
+	__be32 status;
+
+	lock->lk_is_new = 0;
+
+	status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
+	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_old_lock_seqid) < 0)
+		goto xdr_error;
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 {
-	DECODE_HEAD;
+	__be32 *p;
 
-	/*
-	* type, reclaim(boolean), offset, length, new_lock_owner(boolean)
-	*/
-	READ_BUF(28);
-	lock->lk_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_type) < 0)
+		goto xdr_error;
 	if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
 		goto xdr_error;
-	lock->lk_reclaim = be32_to_cpup(p++);
-	p = xdr_decode_hyper(p, &lock->lk_offset);
-	p = xdr_decode_hyper(p, &lock->lk_length);
-	lock->lk_is_new = be32_to_cpup(p++);
-
-	if (lock->lk_is_new) {
-		READ_BUF(4);
-		lock->lk_new_open_seqid = be32_to_cpup(p++);
-		status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
-		if (status)
-			return status;
-		READ_BUF(8 + sizeof(clientid_t));
-		lock->lk_new_lock_seqid = be32_to_cpup(p++);
-		COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
-		lock->lk_new_owner.len = be32_to_cpup(p++);
-		READ_BUF(lock->lk_new_owner.len);
-		READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
-	} else {
-		status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
-		if (status)
-			return status;
-		READ_BUF(4);
-		lock->lk_old_lock_seqid = be32_to_cpup(p++);
-	}
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32));
+	if (!p)
+		goto xdr_error;
+	lock->lk_reclaim = (*p == xdr_zero) ? 0 : 1;
+	if (xdr_stream_decode_u64(argp->xdr, &lock->lk_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lock->lk_length) < 0)
+		goto xdr_error;
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32));
+	if (!p)
+		goto xdr_error;
+	if (*p != xdr_zero)
+		return nfsd4_decode_open_to_lock_owner4(argp, lock);
+	return nfsd4_decode_exist_lock_owner4(argp, lock);
 
-	DECODE_TAIL;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32
diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h
index ed5415e0f1c1..31072a653436 100644
--- a/include/uapi/linux/nfs4.h
+++ b/include/uapi/linux/nfs4.h
@@ -21,6 +21,7 @@
 #define NFS4_STATEID_SEQID_SIZE 4
 #define NFS4_STATEID_OTHER_SIZE 12
 #define NFS4_STATEID_SIZE	(NFS4_STATEID_SEQID_SIZE + NFS4_STATEID_OTHER_SIZE)
+#define NFS4_CLIENTID_SIZE	8
 #define NFS4_FHSIZE		128
 #define NFS4_MAXPATHLEN		PATH_MAX
 #define NFS4_MAXNAMLEN		NAME_MAX



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

* [PATCH v1 14/61] NFSD: Replace READ* macros in nfsd4_decode_lockt()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (12 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 13/61] NFSD: Replace READ* macros in nfsd4_decode_lock() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 15/61] NFSD: Replace READ* macros in nfsd4_decode_locku() Chuck Lever
                   ` (46 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 35329e3d1339..3c4777cb4d38 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -808,20 +808,19 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 static __be32
 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 {
-	DECODE_HEAD;
-		        
-	READ_BUF(32);
-	lockt->lt_type = be32_to_cpup(p++);
-	if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
+	if (xdr_stream_decode_u32(argp->xdr, &lockt->lt_type) < 0)
+		goto xdr_error;
+	if ((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_length) < 0)
 		goto xdr_error;
-	p = xdr_decode_hyper(p, &lockt->lt_offset);
-	p = xdr_decode_hyper(p, &lockt->lt_length);
-	COPYMEM(&lockt->lt_clientid, 8);
-	lockt->lt_owner.len = be32_to_cpup(p++);
-	READ_BUF(lockt->lt_owner.len);
-	READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
+	return nfsd4_decode_state_owner4(argp, &lockt->lt_clientid,
+					 &lockt->lt_owner);
 
-	DECODE_TAIL;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 15/61] NFSD: Replace READ* macros in nfsd4_decode_locku()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (13 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 14/61] NFSD: Replace READ* macros in nfsd4_decode_lockt() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 16/61] NFSD: Replace READ* macros in nfsd4_decode_lookup() Chuck Lever
                   ` (45 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3c4777cb4d38..88a8d002303c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -826,21 +826,27 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 static __be32
 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	READ_BUF(8);
-	locku->lu_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &locku->lu_type) < 0)
+		goto xdr_error;
 	if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
 		goto xdr_error;
-	locku->lu_seqid = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &locku->lu_seqid) < 0)
+		goto xdr_error;
 	status = nfsd4_decode_stateid4(argp, &locku->lu_stateid);
 	if (status)
-		return status;
-	READ_BUF(16);
-	p = xdr_decode_hyper(p, &locku->lu_offset);
-	p = xdr_decode_hyper(p, &locku->lu_length);
+		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &locku->lu_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &locku->lu_length) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 16/61] NFSD: Replace READ* macros in nfsd4_decode_lookup()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (14 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 15/61] NFSD: Replace READ* macros in nfsd4_decode_locku() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 17/61] NFSD: Replace READ* macros in nfsd4_decode_time() Chuck Lever
                   ` (44 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 88a8d002303c..6bb6ffa676b7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -852,16 +852,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 static __be32
 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	lookup->lo_len = be32_to_cpup(p++);
-	READ_BUF(lookup->lo_len);
-	SAVEMEM(lookup->lo_name, lookup->lo_len);
-	if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
-		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len);
 }
 
 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)



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

* [PATCH v1 17/61] NFSD: Replace READ* macros in nfsd4_decode_time()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (15 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 16/61] NFSD: Replace READ* macros in nfsd4_decode_lookup() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:03 ` [PATCH v1 18/61] NFSD: Replace READ* macros in nfsd4_decode_fattr() Chuck Lever
                   ` (43 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6bb6ffa676b7..69ff666a5695 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -262,17 +262,22 @@ static __be32 nfsd4_decode_component4(struct nfsd4_compoundargs *argp,
 }
 
 static __be32
-nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
+nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 {
-	DECODE_HEAD;
+	__be32 *p;
 
-	READ_BUF(12);
+	p = xdr_inline_decode(argp->xdr, sizeof(__be64) + sizeof(__be32));
+	if (!p)
+		goto xdr_error;
 	p = xdr_decode_hyper(p, &tv->tv_sec);
 	tv->tv_nsec = be32_to_cpup(p++);
 	if (tv->tv_nsec >= (u32)1000000000)
-		return nfserr_inval;
-
-	DECODE_TAIL;
+		goto inval_arg;
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+inval_arg:
+	return nfserr_inval;
 }
 
 static __be32
@@ -413,7 +418,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		switch (dummy32) {
 		case NFS4_SET_TO_CLIENT_TIME:
 			len += 12;
-			status = nfsd4_decode_time(argp, &iattr->ia_atime);
+			status = nfsd4_decode_nfstime4(argp, &iattr->ia_atime);
 			if (status)
 				return status;
 			iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
@@ -432,7 +437,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		switch (dummy32) {
 		case NFS4_SET_TO_CLIENT_TIME:
 			len += 12;
-			status = nfsd4_decode_time(argp, &iattr->ia_mtime);
+			status = nfsd4_decode_nfstime4(argp, &iattr->ia_mtime);
 			if (status)
 				return status;
 			iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
@@ -1417,7 +1422,7 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			goto xdr_error;
 
 		/* nii_date */
-		status = nfsd4_decode_time(argp, &exid->nii_time);
+		status = nfsd4_decode_nfstime4(argp, &exid->nii_time);
 		if (status)
 			goto xdr_error;
 	}
@@ -1649,7 +1654,7 @@ nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
 	READ_BUF(4);
 	timechange = be32_to_cpup(p++);
 	if (timechange) {
-		status = nfsd4_decode_time(argp, &lcp->lc_mtime);
+		status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
 		if (status)
 			return status;
 	} else {



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

* [PATCH v1 18/61] NFSD: Replace READ* macros in nfsd4_decode_fattr()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (16 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 17/61] NFSD: Replace READ* macros in nfsd4_decode_time() Chuck Lever
@ 2020-11-13 15:03 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 19/61] NFSD: Replace READ* macros in nfsd4_decode_open() Chuck Lever
                   ` (42 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:03 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 69ff666a5695..9a6116cee94b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -307,17 +307,15 @@ nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval,
 }
 
 static __be32
-nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
-		   struct iattr *iattr, struct nfs4_acl **acl,
-		   struct xdr_netobj *label, int *umask)
+nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen,
+		    struct iattr *iattr, struct nfs4_acl **acl,
+		    struct xdr_netobj *label, int *umask)
 {
-	int expected_len, len = 0;
-	u32 dummy32;
-	char *buf;
+	u32 dummy32, expected_len, len;
+	__be32 *p, status;
 
-	DECODE_HEAD;
 	iattr->ia_valid = 0;
-	status = nfsd4_decode_bitmap4(argp, bmval, 3);
+	status = nfsd4_decode_bitmap4(argp, bmval, bmlen);
 	if (status)
 		goto out;
 
@@ -329,21 +327,25 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		return nfserr_attrnotsupp;
 	}
 
-	READ_BUF(4);
-	expected_len = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &expected_len) < 0)
+		goto xdr_error;
+	len = 0;
 
 	if (bmval[0] & FATTR4_WORD0_SIZE) {
-		READ_BUF(8);
-		len += 8;
-		p = xdr_decode_hyper(p, &iattr->ia_size);
+		p = xdr_inline_decode(argp->xdr, sizeof(__be64));
+		if (!p)
+			goto xdr_error;
+		len += sizeof(__be64);
+		xdr_decode_hyper(p, &iattr->ia_size);
 		iattr->ia_valid |= ATTR_SIZE;
 	}
 	if (bmval[0] & FATTR4_WORD0_ACL) {
 		u32 nace;
 		struct nfs4_ace *ace;
 
-		READ_BUF(4); len += 4;
-		nace = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &nace) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
 
 		if (nace > xdr_stream_remaining(argp->xdr) / sizeof(struct nfs4_ace))
 			/*
@@ -355,72 +357,83 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 
 		*acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
 		if (*acl == NULL)
-			return nfserr_jukebox;
+			goto nomem;
 
 		(*acl)->naces = nace;
 		for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
-			READ_BUF(16); len += 16;
+			p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 4);
+			if (!p)
+				goto xdr_error;
+			len += sizeof(__be32) * 4;
 			ace->type = be32_to_cpup(p++);
 			ace->flag = be32_to_cpup(p++);
 			ace->access_mask = be32_to_cpup(p++);
-			dummy32 = be32_to_cpup(p++);
-			READ_BUF(dummy32);
-			len += XDR_QUADLEN(dummy32) << 2;
-			READMEM(buf, dummy32);
-			ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
+			dummy32 = be32_to_cpup(p);
+			p = xdr_inline_decode(argp->xdr, dummy32);
+			if (!p)
+				goto xdr_error;
+			len += xdr_align_size(dummy32);
+			ace->whotype = nfs4_acl_get_whotype((char *)p, dummy32);
 			status = nfs_ok;
 			if (ace->whotype != NFS4_ACL_WHO_NAMED)
 				;
 			else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
 				status = nfsd_map_name_to_gid(argp->rqstp,
-						buf, dummy32, &ace->who_gid);
+						(char *)p, dummy32, &ace->who_gid);
 			else
 				status = nfsd_map_name_to_uid(argp->rqstp,
-						buf, dummy32, &ace->who_uid);
+						(char *)p, dummy32, &ace->who_uid);
 			if (status)
 				return status;
 		}
 	} else
 		*acl = NULL;
 	if (bmval[1] & FATTR4_WORD1_MODE) {
-		READ_BUF(4);
-		len += 4;
-		iattr->ia_mode = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
+		iattr->ia_mode = dummy32;
 		iattr->ia_mode &= (S_IFMT | S_IALLUGO);
 		iattr->ia_valid |= ATTR_MODE;
 	}
 	if (bmval[1] & FATTR4_WORD1_OWNER) {
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++);
-		READ_BUF(dummy32);
-		len += (XDR_QUADLEN(dummy32) << 2);
-		READMEM(buf, dummy32);
-		if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
+		p = xdr_inline_decode(argp->xdr, dummy32);
+		if (!p)
+			goto xdr_error;
+		len += xdr_align_size(dummy32);
+		status = nfsd_map_name_to_uid(argp->rqstp, (char *)p, dummy32,
+					      &iattr->ia_uid);
+		if (status)
 			return status;
 		iattr->ia_valid |= ATTR_UID;
 	}
 	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++);
-		READ_BUF(dummy32);
-		len += (XDR_QUADLEN(dummy32) << 2);
-		READMEM(buf, dummy32);
-		if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
+		p = xdr_inline_decode(argp->xdr, dummy32);
+		if (!p)
+			goto xdr_error;
+		len += xdr_align_size(dummy32);
+		status = nfsd_map_name_to_gid(argp->rqstp, (char *)p, dummy32,
+					      &iattr->ia_gid);
+		if (status)
 			return status;
 		iattr->ia_valid |= ATTR_GID;
 	}
 	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
 		switch (dummy32) {
 		case NFS4_SET_TO_CLIENT_TIME:
-			len += 12;
 			status = nfsd4_decode_nfstime4(argp, &iattr->ia_atime);
 			if (status)
 				return status;
+			len += sizeof(__be64) + sizeof(__be32);
 			iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
 			break;
 		case NFS4_SET_TO_SERVER_TIME:
@@ -431,15 +444,15 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 		}
 	}
 	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
 		switch (dummy32) {
 		case NFS4_SET_TO_CLIENT_TIME:
-			len += 12;
 			status = nfsd4_decode_nfstime4(argp, &iattr->ia_mtime);
 			if (status)
 				return status;
+			len += sizeof(__be64) + sizeof(__be32);
 			iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
 			break;
 		case NFS4_SET_TO_SERVER_TIME:
@@ -453,40 +466,51 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 	label->len = 0;
 	if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
 	    bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
-		READ_BUF(4);
-		len += 4;
-		dummy32 = be32_to_cpup(p++);
-		READ_BUF(dummy32);
+		/* lfs is ignored */
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
+		/* pi is ignored */
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
 		if (dummy32 > NFS4_MAXLABELLEN)
 			return nfserr_badlabel;
-		len += (XDR_QUADLEN(dummy32) << 2);
-		READMEM(buf, dummy32);
+		len += sizeof(__be32);
+		p = xdr_inline_decode(argp->xdr, dummy32);
+		if (!p)
+			goto xdr_error;
+		len += xdr_align_size(dummy32);
 		label->len = dummy32;
-		label->data = svcxdr_dupstr(argp, buf, dummy32);
+		label->data = svcxdr_dupstr(argp, p, dummy32);
 		if (!label->data)
-			return nfserr_jukebox;
+			goto nomem;
 	}
 	if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
 		if (!umask)
 			goto xdr_error;
-		READ_BUF(8);
-		len += 8;
-		dummy32 = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
 		iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
-		dummy32 = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy32) < 0)
+			goto xdr_error;
+		len += sizeof(__be32);
 		*umask = dummy32 & S_IRWXUGO;
 		iattr->ia_valid |= ATTR_MODE;
 	}
 	if (len != expected_len)
 		goto xdr_error;
+	status = nfs_ok;
 
-	DECODE_TAIL;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
 static __be32 nfsd4_decode_clientid4(struct nfsd4_compoundargs *argp,
@@ -706,9 +730,10 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
 					 &create->cr_namelen);
 	if (status)
 		goto out;
-	status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
-				    &create->cr_acl, &create->cr_label,
-				    &create->cr_umask);
+	status = nfsd4_decode_fattr4(argp, create->cr_bmval,
+				    ARRAY_SIZE(create->cr_bmval),
+				    &create->cr_iattr, &create->cr_acl,
+				    &create->cr_label, &create->cr_umask);
 	if (status)
 		goto out;
 
@@ -965,9 +990,10 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 		switch (open->op_createmode) {
 		case NFS4_CREATE_UNCHECKED:
 		case NFS4_CREATE_GUARDED:
-			status = nfsd4_decode_fattr(argp, open->op_bmval,
-				&open->op_iattr, &open->op_acl, &open->op_label,
-				&open->op_umask);
+			status = nfsd4_decode_fattr4(argp, open->op_bmval,
+						     ARRAY_SIZE(open->op_bmval),
+						     &open->op_iattr, &open->op_acl,
+						     &open->op_label, &open->op_umask);
 			if (status)
 				goto out;
 			break;
@@ -980,9 +1006,10 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 				goto xdr_error;
 			READ_BUF(NFS4_VERIFIER_SIZE);
 			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
-			status = nfsd4_decode_fattr(argp, open->op_bmval,
-				&open->op_iattr, &open->op_acl, &open->op_label,
-				&open->op_umask);
+			status = nfsd4_decode_fattr4(argp, open->op_bmval,
+						     ARRAY_SIZE(open->op_bmval),
+						     &open->op_iattr, &open->op_acl,
+						     &open->op_label, &open->op_umask);
 			if (status)
 				goto out;
 			break;
@@ -1220,8 +1247,10 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
 	status = nfsd4_decode_stateid4(argp, &setattr->sa_stateid);
 	if (status)
 		return status;
-	return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
-				  &setattr->sa_acl, &setattr->sa_label, NULL);
+	return nfsd4_decode_fattr4(argp, setattr->sa_bmval,
+				   ARRAY_SIZE(setattr->sa_bmval),
+				   &setattr->sa_iattr, &setattr->sa_acl,
+				   &setattr->sa_label, NULL);
 }
 
 static __be32



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

* [PATCH v1 19/61] NFSD: Replace READ* macros in nfsd4_decode_open()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (17 preceding siblings ...)
  2020-11-13 15:03 ` [PATCH v1 18/61] NFSD: Replace READ* macros in nfsd4_decode_fattr() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 20/61] NFSD: Replace READ* macros in nfsd4_decode_open_confirm() Chuck Lever
                   ` (41 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

Note that op_fname is the only instance of an NFSv4 filename stored
in a struct xdr_netobj. Convert it to a u32/char * pair so that the
new nfsd4_decode_filename() helper can be used.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c |    8 +--
 fs/nfsd/nfs4xdr.c  |  160 +++++++++++++++++++++++++++++++---------------------
 fs/nfsd/xdr4.h     |    3 +
 3 files changed, 100 insertions(+), 71 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 91197626d0d2..b810d048c5f8 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -257,8 +257,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 		 * in NFSv4 as in v3 except EXCLUSIVE4_1.
 		 */
 		current->fs->umask = open->op_umask;
-		status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
-					open->op_fname.len, &open->op_iattr,
+		status = do_nfsd_create(rqstp, current_fh, open->op_fname,
+					open->op_fnamelen, &open->op_iattr,
 					*resfh, open->op_createmode,
 					(u32 *)open->op_verf.data,
 					&open->op_truncate, &open->op_created);
@@ -283,7 +283,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 		 * a chance to an acquire a delegation if appropriate.
 		 */
 		status = nfsd_lookup(rqstp, current_fh,
-				     open->op_fname.data, open->op_fname.len, *resfh);
+				     open->op_fname, open->op_fnamelen, *resfh);
 	if (status)
 		goto out;
 	status = nfsd_check_obj_isreg(*resfh);
@@ -360,7 +360,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	bool reclaim = false;
 
 	dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
-		(int)open->op_fname.len, open->op_fname.data,
+		(int)open->op_fnamelen, open->op_fname,
 		open->op_openowner);
 
 	/* This check required by spec. */
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9a6116cee94b..2ff3dfaca4a1 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -261,6 +261,20 @@ static __be32 nfsd4_decode_component4(struct nfsd4_compoundargs *argp,
 	return nfserr_jukebox;
 }
 
+static __be32 nfsd4_decode_verifier4(struct nfsd4_compoundargs *argp,
+				     nfs4_verifier *verf)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_VERIFIER_SIZE);
+	if (!p)
+		goto xdr_error;
+	memcpy(verf->data, p, sizeof(verf->data));
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 {
@@ -887,11 +901,10 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
 
 static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 {
-	__be32 *p;
 	u32 w;
 
-	READ_BUF(4);
-	w = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &w) < 0)
+		goto xdr_error;
 	*share_access = w & NFS4_SHARE_ACCESS_MASK;
 	*deleg_want = w & NFS4_SHARE_WANT_MASK;
 	if (deleg_when)
@@ -940,22 +953,66 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *sh
 
 static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 {
-	__be32 *p;
-
-	READ_BUF(4);
-	*x = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, x) < 0)
+		goto xdr_error;
 	/* Note: unlinke access bits, deny bits may be zero. */
 	if (*x & ~NFS4_SHARE_DENY_BOTH)
-		return nfserr_bad_xdr;
+		goto xdr_error;
 	return nfs_ok;
 xdr_error:
 	return nfserr_bad_xdr;
 }
 
+static __be32
+nfsd4_decode_createhow4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
+{
+	__be32 status;
+
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_createmode) < 0)
+		goto xdr_error;
+	switch (open->op_createmode) {
+	case NFS4_CREATE_UNCHECKED:
+	case NFS4_CREATE_GUARDED:
+		status = nfsd4_decode_fattr4(argp, open->op_bmval,
+					     ARRAY_SIZE(open->op_bmval),
+					     &open->op_iattr, &open->op_acl,
+					     &open->op_label, &open->op_umask);
+		if (status)
+			goto out;
+		break;
+	case NFS4_CREATE_EXCLUSIVE:
+		status = nfsd4_decode_verifier4(argp, &open->op_verf);
+		if (status)
+			goto out;
+		break;
+	case NFS4_CREATE_EXCLUSIVE4_1:
+		if (argp->minorversion < 1)
+			goto xdr_error;
+		status = nfsd4_decode_verifier4(argp, &open->op_verf);
+		if (status)
+			goto out;
+		status = nfsd4_decode_fattr4(argp, open->op_bmval,
+					     ARRAY_SIZE(open->op_bmval),
+					     &open->op_iattr, &open->op_acl,
+					     &open->op_label, &open->op_umask);
+		if (status)
+			goto out;
+		break;
+	default:
+		goto xdr_error;
+	}
+	status = nfs_ok;
+
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
-	DECODE_HEAD;
+	__be32 status;
 	u32 dummy;
 
 	memset(open->op_bmval, 0, sizeof(open->op_bmval));
@@ -964,8 +1021,8 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 
 	open->op_xdr_error = 0;
 	/* seqid, share_access, share_deny, clientid, ownerlen */
-	READ_BUF(4);
-	open->op_seqid = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_seqid) < 0)
+		goto xdr_error;
 	/* decode, yet ignore deleg_when until supported */
 	status = nfsd4_decode_share_access(argp, &open->op_share_access,
 					   &open->op_deleg_want, &dummy);
@@ -974,80 +1031,47 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
 	if (status)
 		goto xdr_error;
-	READ_BUF(sizeof(clientid_t));
-	COPYMEM(&open->op_clientid, sizeof(clientid_t));
-	status = nfsd4_decode_opaque(argp, &open->op_owner);
+	status = nfsd4_decode_state_owner4(argp, &open->op_clientid,
+					   &open->op_owner);
 	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_create) < 0)
 		goto xdr_error;
-	READ_BUF(4);
-	open->op_create = be32_to_cpup(p++);
 	switch (open->op_create) {
 	case NFS4_OPEN_NOCREATE:
 		break;
 	case NFS4_OPEN_CREATE:
-		READ_BUF(4);
-		open->op_createmode = be32_to_cpup(p++);
-		switch (open->op_createmode) {
-		case NFS4_CREATE_UNCHECKED:
-		case NFS4_CREATE_GUARDED:
-			status = nfsd4_decode_fattr4(argp, open->op_bmval,
-						     ARRAY_SIZE(open->op_bmval),
-						     &open->op_iattr, &open->op_acl,
-						     &open->op_label, &open->op_umask);
-			if (status)
-				goto out;
-			break;
-		case NFS4_CREATE_EXCLUSIVE:
-			READ_BUF(NFS4_VERIFIER_SIZE);
-			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
-			break;
-		case NFS4_CREATE_EXCLUSIVE4_1:
-			if (argp->minorversion < 1)
-				goto xdr_error;
-			READ_BUF(NFS4_VERIFIER_SIZE);
-			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
-			status = nfsd4_decode_fattr4(argp, open->op_bmval,
-						     ARRAY_SIZE(open->op_bmval),
-						     &open->op_iattr, &open->op_acl,
-						     &open->op_label, &open->op_umask);
-			if (status)
-				goto out;
-			break;
-		default:
-			goto xdr_error;
-		}
+		status = nfsd4_decode_createhow4(argp, open);
+		if (status)
+			goto out;
 		break;
 	default:
 		goto xdr_error;
 	}
 
 	/* open_claim */
-	READ_BUF(4);
-	open->op_claim_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &open->op_claim_type) < 0)
+		goto xdr_error;
 	switch (open->op_claim_type) {
 	case NFS4_OPEN_CLAIM_NULL:
 	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
-		READ_BUF(4);
-		open->op_fname.len = be32_to_cpup(p++);
-		READ_BUF(open->op_fname.len);
-		SAVEMEM(open->op_fname.data, open->op_fname.len);
-		if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
-			return status;
+		status = nfsd4_decode_component4(argp, &open->op_fname,
+						 &open->op_fnamelen);
+		if (status)
+			goto out;
 		break;
 	case NFS4_OPEN_CLAIM_PREVIOUS:
-		READ_BUF(4);
-		open->op_delegate_type = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &open->op_delegate_type) < 0)
+			goto xdr_error;
 		break;
 	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
 		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
 		if (status)
-			return status;
-		READ_BUF(4);
-		open->op_fname.len = be32_to_cpup(p++);
-		READ_BUF(open->op_fname.len);
-		SAVEMEM(open->op_fname.data, open->op_fname.len);
-		if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
-			return status;
+			goto out;
+		status = nfsd4_decode_component4(argp, &open->op_fname,
+						 &open->op_fnamelen);
+		if (status)
+			goto out;
 		break;
 	case NFS4_OPEN_CLAIM_FH:
 	case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
@@ -1060,13 +1084,17 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 			goto xdr_error;
 		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
 		if (status)
-			return status;
+			goto out;
 		break;
 	default:
 		goto xdr_error;
 	}
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 0eb13bd603ea..6245004a9993 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -252,7 +252,8 @@ struct nfsd4_listxattrs {
 
 struct nfsd4_open {
 	u32		op_claim_type;      /* request */
-	struct xdr_netobj op_fname;	    /* request - everything but CLAIM_PREV */
+	u32		op_fnamelen;
+	char *		op_fname;	    /* request - everything but CLAIM_PREV */
 	u32		op_delegate_type;   /* request - CLAIM_PREV only */
 	stateid_t       op_delegate_stateid; /* request - response */
 	u32		op_why_no_deleg;    /* response - DELEG_NONE_EXT only */



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

* [PATCH v1 20/61] NFSD: Replace READ* macros in nfsd4_decode_open_confirm()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (18 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 19/61] NFSD: Replace READ* macros in nfsd4_decode_open() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 21/61] NFSD: Replace READ* macros in nfsd4_decode_open_downgrade() Chuck Lever
                   ` (40 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 2ff3dfaca4a1..b4f23d1fd85e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1100,18 +1100,22 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 static __be32
 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
 	status = nfsd4_decode_stateid4(argp, &open_conf->oc_req_stateid);
 	if (status)
-		return status;
-	READ_BUF(4);
-	open_conf->oc_seqid = be32_to_cpup(p++);
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &open_conf->oc_seqid) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 21/61] NFSD: Replace READ* macros in nfsd4_decode_open_downgrade()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (19 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 20/61] NFSD: Replace READ* macros in nfsd4_decode_open_confirm() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 22/61] NFSD: Replace READ* macros in nfsd4_decode_putfh() Chuck Lever
                   ` (39 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b4f23d1fd85e..c7e7854b5e19 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1121,21 +1121,26 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
 static __be32
 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
 {
-	DECODE_HEAD;
-		    
+	__be32 status;
+
 	status = nfsd4_decode_stateid4(argp, &open_down->od_stateid);
 	if (status)
-		return status;
-	READ_BUF(4);
-	open_down->od_seqid = be32_to_cpup(p++);
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &open_down->od_seqid) < 0)
+		goto xdr_error;
 	status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
 					   &open_down->od_deleg_want, NULL);
 	if (status)
-		return status;
+		goto out;
 	status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
 	if (status)
-		return status;
-	DECODE_TAIL;
+		goto out;
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 22/61] NFSD: Replace READ* macros in nfsd4_decode_putfh()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (20 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 21/61] NFSD: Replace READ* macros in nfsd4_decode_open_downgrade() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 23/61] NFSD: Replace READ* macros in nfsd4_decode_read() Chuck Lever
                   ` (38 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c7e7854b5e19..c7f4040efd40 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1146,16 +1146,24 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
 static __be32
 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
 {
-	DECODE_HEAD;
+	__be32 *p;
 
-	READ_BUF(4);
-	putfh->pf_fhlen = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &putfh->pf_fhlen) < 0)
+		goto xdr_error;
 	if (putfh->pf_fhlen > NFS4_FHSIZE)
 		goto xdr_error;
-	READ_BUF(putfh->pf_fhlen);
-	SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
-
-	DECODE_TAIL;
+	p = xdr_inline_decode(argp->xdr, putfh->pf_fhlen);
+	if (!p)
+		goto xdr_error;
+	putfh->pf_fhval = svcxdr_tmpalloc(argp, putfh->pf_fhlen);
+	if (!putfh->pf_fhval)
+		goto nomem;
+	memcpy(putfh->pf_fhval, p, putfh->pf_fhlen);
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
 static __be32



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

* [PATCH v1 23/61] NFSD: Replace READ* macros in nfsd4_decode_read()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (21 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 22/61] NFSD: Replace READ* macros in nfsd4_decode_putfh() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 24/61] NFSD: Replace READ* macros in nfsd4_decode_readdir() Chuck Lever
                   ` (37 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c7f4040efd40..1f00fe6febf9 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1177,16 +1177,21 @@ nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
 static __be32
 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	status = nfsd4_decode_stateid4(argp, &read->rd_stateid);
 	if (status)
-		return status;
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &read->rd_offset);
-	read->rd_length = be32_to_cpup(p++);
+		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &read->rd_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &read->rd_length) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 24/61] NFSD: Replace READ* macros in nfsd4_decode_readdir()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (22 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 23/61] NFSD: Replace READ* macros in nfsd4_decode_read() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 25/61] NFSD: Replace READ* macros in nfsd4_decode_remove() Chuck Lever
                   ` (36 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1f00fe6febf9..2e163c23d013 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1197,19 +1197,27 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 static __be32
 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	READ_BUF(24);
-	p = xdr_decode_hyper(p, &readdir->rd_cookie);
-	COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
-	readdir->rd_dircount = be32_to_cpup(p++);
-	readdir->rd_maxcount = be32_to_cpup(p++);
+	if (xdr_stream_decode_u64(argp->xdr, &readdir->rd_cookie) < 0)
+		goto xdr_error;
+	status = nfsd4_decode_verifier4(argp, &readdir->rd_verf);
+	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_dircount) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_maxcount) < 0)
+		goto xdr_error;
 	status = nfsd4_decode_bitmap4(argp, readdir->rd_bmval,
 				      ARRAY_SIZE(readdir->rd_bmval));
 	if (status)
 		goto out;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 25/61] NFSD: Replace READ* macros in nfsd4_decode_remove()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (23 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 24/61] NFSD: Replace READ* macros in nfsd4_decode_readdir() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 26/61] NFSD: Replace READ* macros in nfsd4_decode_rename() Chuck Lever
                   ` (35 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 2e163c23d013..58342971fd6b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1223,16 +1223,7 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
 static __be32
 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	remove->rm_namelen = be32_to_cpup(p++);
-	READ_BUF(remove->rm_namelen);
-	SAVEMEM(remove->rm_name, remove->rm_namelen);
-	if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
-		return status;
-
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &remove->rm_name, &remove->rm_namelen);
 }
 
 static __be32



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

* [PATCH v1 26/61] NFSD: Replace READ* macros in nfsd4_decode_rename()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (24 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 25/61] NFSD: Replace READ* macros in nfsd4_decode_remove() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 27/61] NFSD: Replace READ* macros in nfsd4_decode_renew() Chuck Lever
                   ` (34 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 58342971fd6b..aa71baacabba 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1229,22 +1229,18 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove
 static __be32
 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
 {
-	DECODE_HEAD;
+	__be32 status;
 
-	READ_BUF(4);
-	rename->rn_snamelen = be32_to_cpup(p++);
-	READ_BUF(rename->rn_snamelen);
-	SAVEMEM(rename->rn_sname, rename->rn_snamelen);
-	READ_BUF(4);
-	rename->rn_tnamelen = be32_to_cpup(p++);
-	READ_BUF(rename->rn_tnamelen);
-	SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
-	if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
-		return status;
-	if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen)))
-		return status;
+	status = nfsd4_decode_component4(argp, &rename->rn_sname, &rename->rn_snamelen);
+	if (status)
+		goto out;
+	status = nfsd4_decode_component4(argp, &rename->rn_tname, &rename->rn_tnamelen);
+	if (status)
+		goto out;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
 }
 
 static __be32



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

* [PATCH v1 27/61] NFSD: Replace READ* macros in nfsd4_decode_renew()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (25 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 26/61] NFSD: Replace READ* macros in nfsd4_decode_rename() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 28/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo() Chuck Lever
                   ` (33 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index aa71baacabba..e7b43bc69af9 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1246,15 +1246,7 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename
 static __be32
 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
 {
-	DECODE_HEAD;
-
-	if (argp->minorversion >= 1)
-		return nfserr_notsupp;
-
-	READ_BUF(sizeof(clientid_t));
-	COPYMEM(clientid, sizeof(clientid_t));
-
-	DECODE_TAIL;
+	return nfsd4_decode_clientid4(argp, clientid);
 }
 
 static __be32



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

* [PATCH v1 28/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (26 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 27/61] NFSD: Replace READ* macros in nfsd4_decode_renew() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:04 ` [PATCH v1 29/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid() Chuck Lever
                   ` (32 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index e7b43bc69af9..bbae2b1726ac 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1253,16 +1253,7 @@ static __be32
 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
 		     struct nfsd4_secinfo *secinfo)
 {
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	secinfo->si_namelen = be32_to_cpup(p++);
-	READ_BUF(secinfo->si_namelen);
-	SAVEMEM(secinfo->si_name, secinfo->si_namelen);
-	status = check_filename(secinfo->si_name, secinfo->si_namelen);
-	if (status)
-		return status;
-	DECODE_TAIL;
+	return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen);
 }
 
 static __be32



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

* [PATCH v1 29/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (27 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 28/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo() Chuck Lever
@ 2020-11-13 15:04 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 30/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm() Chuck Lever
                   ` (31 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:04 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bbae2b1726ac..82d599887f92 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1284,31 +1284,52 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
 static __be32
 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	READ_BUF(NFS4_VERIFIER_SIZE);
-	COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
-
+	status = nfsd4_decode_verifier4(argp, &setclientid->se_verf);
+	if (status)
+		goto out;
 	status = nfsd4_decode_opaque(argp, &setclientid->se_name);
 	if (status)
-		return nfserr_bad_xdr;
-	READ_BUF(8);
-	setclientid->se_callback_prog = be32_to_cpup(p++);
-	setclientid->se_callback_netid_len = be32_to_cpup(p++);
-	READ_BUF(setclientid->se_callback_netid_len);
-	SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
-	READ_BUF(4);
-	setclientid->se_callback_addr_len = be32_to_cpup(p++);
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_prog) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_netid_len) < 0)
+		goto xdr_error;
+	p = xdr_inline_decode(argp->xdr, setclientid->se_callback_netid_len);
+	if (!p)
+		goto xdr_error;
+	setclientid->se_callback_netid_val = svcxdr_tmpalloc(argp,
+						setclientid->se_callback_netid_len);
+	if (!setclientid->se_callback_netid_val)
+		goto nomem;
+	memcpy(setclientid->se_callback_netid_val, p,
+	       setclientid->se_callback_netid_len);
 
-	READ_BUF(setclientid->se_callback_addr_len);
-	SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
-	READ_BUF(4);
-	setclientid->se_callback_ident = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_addr_len) < 0)
+		goto xdr_error;
+	p = xdr_inline_decode(argp->xdr, setclientid->se_callback_addr_len);
+	if (!p)
+		goto xdr_error;
+	setclientid->se_callback_addr_val = svcxdr_tmpalloc(argp,
+						setclientid->se_callback_addr_len);
+	if (!setclientid->se_callback_addr_val)
+		goto nomem;
+	memcpy(setclientid->se_callback_addr_val, p,
+	       setclientid->se_callback_addr_len);
+	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_ident) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
 static __be32



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

* [PATCH v1 30/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (28 preceding siblings ...)
  2020-11-13 15:04 ` [PATCH v1 29/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 31/61] NFSD: Replace READ* macros in nfsd4_decode_verify() Chuck Lever
                   ` (30 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 82d599887f92..a6d6f999433c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1335,16 +1335,21 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
 static __be32
 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	READ_BUF(8 + NFS4_VERIFIER_SIZE);
-	COPYMEM(&scd_c->sc_clientid, 8);
-	COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
+	status = nfsd4_decode_clientid4(argp, &scd_c->sc_clientid);
+	if (status)
+		goto out;
+	status = nfsd4_decode_verifier4(argp, &scd_c->sc_confirm);
+	if (status)
+		goto out;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
 }
 
 /* Also used for NVERIFY */



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

* [PATCH v1 31/61] NFSD: Replace READ* macros in nfsd4_decode_verify()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (29 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 30/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 32/61] NFSD: Replace READ* macros in nfsd4_decode_write() Chuck Lever
                   ` (29 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index a6d6f999433c..71a9bdb67d06 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1356,7 +1356,7 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
 static __be32
 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
 	status = nfsd4_decode_bitmap4(argp, verify->ve_bmval,
 				      ARRAY_SIZE(verify->ve_bmval));
@@ -1366,12 +1366,22 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
 	/* For convenience's sake, we compare raw xdr'd attributes in
 	 * nfsd4_proc_verify */
 
-	READ_BUF(4);
-	verify->ve_attrlen = be32_to_cpup(p++);
-	READ_BUF(verify->ve_attrlen);
-	SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
-
-	DECODE_TAIL;
+	if (xdr_stream_decode_u32(argp->xdr, &verify->ve_attrlen) < 0)
+		goto xdr_error;
+	p = xdr_inline_decode(argp->xdr, verify->ve_attrlen);
+	if (!p)
+		goto xdr_error;
+	verify->ve_attrval = svcxdr_tmpalloc(argp, verify->ve_attrlen);
+	if (!verify->ve_attrval)
+		goto nomem;
+	memcpy(verify->ve_attrval, p, verify->ve_attrlen);
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
 static __be32



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

* [PATCH v1 32/61] NFSD: Replace READ* macros in nfsd4_decode_write()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (30 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 31/61] NFSD: Replace READ* macros in nfsd4_decode_verify() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 33/61] NFSD: Replace READ* macros in nfsd4_decode_release_lockowner() Chuck Lever
                   ` (28 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 71a9bdb67d06..db63cd46b9b1 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1387,22 +1387,27 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
 static __be32
 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	status = nfsd4_decode_stateid4(argp, &write->wr_stateid);
 	if (status)
-		return status;
-	READ_BUF(16);
-	p = xdr_decode_hyper(p, &write->wr_offset);
-	write->wr_stable_how = be32_to_cpup(p++);
+		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &write->wr_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &write->wr_stable_how) < 0)
+		goto xdr_error;
 	if (write->wr_stable_how > NFS_FILE_SYNC)
 		goto xdr_error;
-	write->wr_buflen = be32_to_cpup(p++);
-
+	if (xdr_stream_decode_u32(argp->xdr, &write->wr_buflen) < 0)
+		goto xdr_error;
 	if (!xdr_stream_subsegment(argp->xdr, &write->wr_payload, write->wr_buflen))
 		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 33/61] NFSD: Replace READ* macros in nfsd4_decode_release_lockowner()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (31 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 32/61] NFSD: Replace READ* macros in nfsd4_decode_write() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 34/61] NFSD: Replace READ* macros in nfsd4_decode_cb_sec() Chuck Lever
                   ` (27 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index db63cd46b9b1..4a71346dcd9a 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1413,20 +1413,24 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 static __be32
 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	if (argp->minorversion >= 1)
 		return nfserr_notsupp;
 
-	READ_BUF(12);
-	COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
-	rlockowner->rl_owner.len = be32_to_cpup(p++);
-	READ_BUF(rlockowner->rl_owner.len);
-	READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
+	status = nfsd4_decode_state_owner4(argp, &rlockowner->rl_clientid,
+					   &rlockowner->rl_owner);
+	if (status)
+		goto out;
 
 	if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
-		return nfserr_inval;
-	DECODE_TAIL;
+		goto inval_arg;
+
+	status = nfs_ok;
+out:
+	return status;
+inval_arg:
+	return nfserr_inval;
 }
 
 static __be32



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

* [PATCH v1 34/61] NFSD: Replace READ* macros in nfsd4_decode_cb_sec()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (32 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 33/61] NFSD: Replace READ* macros in nfsd4_decode_release_lockowner() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 35/61] NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl() Chuck Lever
                   ` (26 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4a71346dcd9a..2d2034d7f48e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -570,24 +570,22 @@ nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 {
-	DECODE_HEAD;
 	struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
-	u32 dummy, uid, gid;
+	u32 dummy, uid, gid, i, nr_secflavs;
 	char *machine_name;
-	int i;
-	int nr_secflavs;
+	__be32 *p;
 
 	/* callback_sec_params4 */
-	READ_BUF(4);
-	nr_secflavs = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &nr_secflavs) < 0)
+		goto xdr_error;
 	if (nr_secflavs)
 		cbs->flavor = (u32)(-1);
 	else
 		/* Is this legal? Be generous, take it to mean AUTH_NONE: */
 		cbs->flavor = 0;
 	for (i = 0; i < nr_secflavs; ++i) {
-		READ_BUF(4);
-		dummy = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+			goto xdr_error;
 		switch (dummy) {
 		case RPC_AUTH_NULL:
 			/* Nothing to read */
@@ -595,24 +593,32 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
 				cbs->flavor = RPC_AUTH_NULL;
 			break;
 		case RPC_AUTH_UNIX:
-			READ_BUF(8);
 			/* stamp */
-			dummy = be32_to_cpup(p++);
+			if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+				goto xdr_error;
 
 			/* machine name */
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			SAVEMEM(machine_name, dummy);
+			if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+				goto xdr_error;
+			p = xdr_inline_decode(argp->xdr, dummy);
+			if (!p)
+				goto xdr_error;
+			machine_name = svcxdr_tmpalloc(argp, dummy);
+			if (!machine_name)
+				goto nomem;
+			memcpy(machine_name, p, dummy);
 
-			/* uid, gid */
-			READ_BUF(8);
+			/* uid, gid, gidcount */
+			p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 3);
+			if (!p)
+				goto xdr_error;
 			uid = be32_to_cpup(p++);
 			gid = be32_to_cpup(p++);
 
-			/* more gids */
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy * 4);
+			dummy = be32_to_cpup(p);
+			p = xdr_inline_decode(argp->xdr, dummy << 2);
+			if (!p)
+				goto xdr_error;
 			if (cbs->flavor == (u32)(-1)) {
 				kuid_t kuid = make_kuid(userns, uid);
 				kgid_t kgid = make_kgid(userns, gid);
@@ -629,26 +635,37 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
 		case RPC_AUTH_GSS:
 			dprintk("RPC_AUTH_GSS callback secflavor "
 				"not supported!\n");
-			READ_BUF(8);
+
 			/* gcbp_service */
-			dummy = be32_to_cpup(p++);
+			if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+				goto xdr_error;
+
 			/* gcbp_handle_from_server */
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			p += XDR_QUADLEN(dummy);
+			if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+				goto xdr_error;
+			if (!xdr_inline_decode(argp->xdr, dummy))
+				goto xdr_error;
+
 			/* gcbp_handle_from_client */
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
+			if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+				goto xdr_error;
+			if (!xdr_inline_decode(argp->xdr, dummy))
+				goto xdr_error;
 			break;
 		default:
 			dprintk("Illegal callback secflavor\n");
 			return nfserr_inval;
 		}
 	}
-	DECODE_TAIL;
+
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
+
 /*
  * NFSv4 operation argument decoders
  */



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

* [PATCH v1 35/61] NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (33 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 34/61] NFSD: Replace READ* macros in nfsd4_decode_cb_sec() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 36/61] NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session() Chuck Lever
                   ` (25 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 2d2034d7f48e..ff466bea0084 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -678,17 +678,6 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
 	return nfs_ok;
 }
 
-static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	bc->bc_cb_program = be32_to_cpup(p++);
-	nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
-
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
 {
 	DECODE_HEAD;
@@ -1450,6 +1439,15 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
 	return nfserr_inval;
 }
 
+static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &bc->bc_cb_program) < 0)
+		goto xdr_error;
+	return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)



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

* [PATCH v1 36/61] NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (34 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 35/61] NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 37/61] NFSD: Add a separate decoder to handle state_protect_ops Chuck Lever
                   ` (24 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ff466bea0084..73a4b23849e2 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -568,6 +568,20 @@ nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 	return nfserr_bad_xdr;
 }
 
+static __be32 nfsd4_decode_sessionid(struct nfsd4_compoundargs *argp,
+				     struct nfs4_sessionid *sessionid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_MAX_SESSIONID_LEN);
+	if (!p)
+		goto xdr_error;
+	memcpy(sessionid->data, p, sizeof(sessionid->data));
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 {
 	struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
@@ -678,18 +692,6 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
 	return nfs_ok;
 }
 
-static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
-{
-	DECODE_HEAD;
-
-	READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
-	COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
-	bcts->dir = be32_to_cpup(p++);
-	/* XXX: skipping ctsa_use_conn_in_rdma_mode.  Perhaps Tom Tucker
-	 * could help us figure out we should be using it. */
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
@@ -1448,6 +1450,26 @@ static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, stru
 	return nfserr_bad_xdr;
 }
 
+static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
+{
+	__be32 *p, status;
+
+	status = nfsd4_decode_sessionid(argp, &bcts->sessionid);
+	if (status)
+		goto out;
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 2);
+	if (!p)
+		goto xdr_error;
+	bcts->dir = be32_to_cpup(p);
+	/* ctsa_use_conn_in_rdma_mode is ignored */
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)



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

* [PATCH v1 37/61] NFSD: Add a separate decoder to handle state_protect_ops
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (35 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 36/61] NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 38/61] NFSD: Add a separate decoder for ssv_sp_parms Chuck Lever
                   ` (23 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

Refactor for clarity and de-duplication of code.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 73a4b23849e2..ece4e8afe19e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1470,12 +1470,25 @@ static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp,
 	return nfserr_bad_xdr;
 }
 
+static __be32 nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
+					     u32 *must_enforce, u32 me_len,
+					     u32 *must_allow, u32 ma_len)
+{
+	__be32 status;
+
+	status = nfsd4_decode_bitmap4(argp, must_enforce, me_len);
+	if (status)
+		return status;
+	return nfsd4_decode_bitmap4(argp, must_allow, ma_len);
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
 {
 	int dummy, tmp;
 	DECODE_HEAD;
+	u32 bm[3];
 
 	READ_BUF(NFS4_VERIFIER_SIZE);
 	COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
@@ -1494,28 +1507,20 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 	case SP4_NONE:
 		break;
 	case SP4_MACH_CRED:
-		/* spo_must_enforce */
-		status = nfsd4_decode_bitmap4(argp, exid->spo_must_enforce,
-					      ARRAY_SIZE(exid->spo_must_enforce));
-		if (status)
-			goto out;
-		/* spo_must_allow */
-		status = nfsd4_decode_bitmap4(argp, exid->spo_must_allow,
-					      ARRAY_SIZE(exid->spo_must_allow));
+		status = nfsd4_decode_state_protect_ops(argp,
+							exid->spo_must_enforce,
+							ARRAY_SIZE(exid->spo_must_enforce),
+							exid->spo_must_allow,
+							ARRAY_SIZE(exid->spo_must_allow));
 		if (status)
 			goto out;
 		break;
 	case SP4_SSV:
 		/* ssp_ops */
-		READ_BUF(4);
-		dummy = be32_to_cpup(p++);
-		READ_BUF(dummy * 4);
-		p += dummy;
-
-		READ_BUF(4);
-		dummy = be32_to_cpup(p++);
-		READ_BUF(dummy * 4);
-		p += dummy;
+		status = nfsd4_decode_state_protect_ops(argp, bm, ARRAY_SIZE(bm),
+							bm, ARRAY_SIZE(bm));
+		if (status)
+			goto out;
 
 		/* ssp_hash_algs<> */
 		READ_BUF(4);



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

* [PATCH v1 38/61] NFSD: Add a separate decoder for ssv_sp_parms
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (36 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 37/61] NFSD: Add a separate decoder to handle state_protect_ops Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 39/61] NFSD: Add a helper to decode state_protect4_a Chuck Lever
                   ` (22 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

Refactor for clarity.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ece4e8afe19e..4d666e2f8583 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -222,11 +222,13 @@ static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_ne
 	p = xdr_inline_decode(argp->xdr, len);
 	if (!p)
 		goto xdr_error;
-	o->data = svcxdr_tmpalloc(argp, len);
-	if (!o->data)
-		goto nomem;
-	o->len = len;
-	memcpy(o->data, p, len);
+	if (o) {
+		o->data = svcxdr_tmpalloc(argp, len);
+		if (!o->data)
+			goto nomem;
+		o->len = len;
+		memcpy(o->data, p, len);
+	}
 
 	return nfs_ok;
 xdr_error:
@@ -1482,13 +1484,56 @@ static __be32 nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_bitmap4(argp, must_allow, ma_len);
 }
 
+/*
+ * This implementation currently does not support SP4_SSV.
+ * This decoder simply skips over these arguments.
+ */
+static __be32 nfsd4_decode_ssv_sp_parms(struct nfsd4_compoundargs *argp)
+{
+	u32 bm[3], count;
+	__be32 status;
+
+	/* ssp_ops */
+	status = nfsd4_decode_state_protect_ops(argp, bm, ARRAY_SIZE(bm),
+						bm, ARRAY_SIZE(bm));
+	if (status)
+		goto out;
+
+	/* ssp_hash_algs<> */
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		goto xdr_error;
+	while (count--) {
+		status = nfsd4_decode_opaque(argp, NULL);
+		if (status)
+			goto out;
+	}
+
+	/* ssp_encr_algs<> */
+	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
+		goto xdr_error;
+	while (count--) {
+		status = nfsd4_decode_opaque(argp, NULL);
+		if (status)
+			goto out;
+	}
+
+	/* ssp_window and ssp_num_gss_handles are ignored */
+	if (!xdr_inline_decode(argp->xdr, sizeof(__be32) * 2))
+		goto xdr_error;
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
 {
-	int dummy, tmp;
 	DECODE_HEAD;
-	u32 bm[3];
+	int dummy;
 
 	READ_BUF(NFS4_VERIFIER_SIZE);
 	COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
@@ -1516,34 +1561,9 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			goto out;
 		break;
 	case SP4_SSV:
-		/* ssp_ops */
-		status = nfsd4_decode_state_protect_ops(argp, bm, ARRAY_SIZE(bm),
-							bm, ARRAY_SIZE(bm));
+		status = nfsd4_decode_ssv_sp_parms(argp);
 		if (status)
 			goto out;
-
-		/* ssp_hash_algs<> */
-		READ_BUF(4);
-		tmp = be32_to_cpup(p++);
-		while (tmp--) {
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			p += XDR_QUADLEN(dummy);
-		}
-
-		/* ssp_encr_algs<> */
-		READ_BUF(4);
-		tmp = be32_to_cpup(p++);
-		while (tmp--) {
-			READ_BUF(4);
-			dummy = be32_to_cpup(p++);
-			READ_BUF(dummy);
-			p += XDR_QUADLEN(dummy);
-		}
-
-		/* ignore ssp_window and ssp_num_gss_handles: */
-		READ_BUF(8);
 		break;
 	default:
 		goto xdr_error;



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

* [PATCH v1 39/61] NFSD: Add a helper to decode state_protect4_a
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (37 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 38/61] NFSD: Add a separate decoder for ssv_sp_parms Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 40/61] NFSD: Replace READ* macros in nfsd4_decode_exchange_id() Chuck Lever
                   ` (21 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

Refactor for clarity.

Also, remove a stale comment. Commit ed94164398c9 ("nfsd: implement
machine credential support for some operations") added support for
SP4_MACH_CRED, so state_protect_a is no longer completely ignored.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4state.c |    2 +-
 fs/nfsd/nfs4xdr.c   |   51 +++++++++++++++++++++++++++++++++------------------
 fs/nfsd/xdr4.h      |    2 +-
 3 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d7f27ed6b794..be6dcc4c2ab0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3066,7 +3066,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	rpc_ntop(sa, addr_str, sizeof(addr_str));
 	dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
-		"ip_addr=%s flags %x, spa_how %d\n",
+		"ip_addr=%s flags %x, spa_how %u\n",
 		__func__, rqstp, exid, exid->clname.len, exid->clname.data,
 		addr_str, exid->flags, exid->spa_how);
 
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4d666e2f8583..d3e238b538d0 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1528,26 +1528,13 @@ static __be32 nfsd4_decode_ssv_sp_parms(struct nfsd4_compoundargs *argp)
 	return nfserr_bad_xdr;
 }
 
-static __be32
-nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
-			 struct nfsd4_exchange_id *exid)
+static __be32 nfsd4_decode_state_protect4_a(struct nfsd4_compoundargs *argp,
+					    struct nfsd4_exchange_id *exid)
 {
-	DECODE_HEAD;
-	int dummy;
-
-	READ_BUF(NFS4_VERIFIER_SIZE);
-	COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
-
-	status = nfsd4_decode_opaque(argp, &exid->clname);
-	if (status)
-		return nfserr_bad_xdr;
-
-	READ_BUF(4);
-	exid->flags = be32_to_cpup(p++);
+	__be32 status;
 
-	/* Ignore state_protect4_a */
-	READ_BUF(4);
-	exid->spa_how = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &exid->spa_how) < 0)
+		goto xdr_error;
 	switch (exid->spa_how) {
 	case SP4_NONE:
 		break;
@@ -1569,6 +1556,34 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 		goto xdr_error;
 	}
 
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
+static __be32
+nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
+			 struct nfsd4_exchange_id *exid)
+{
+	DECODE_HEAD;
+	int dummy;
+
+	status = nfsd4_decode_verifier4(argp, &exid->verifier);
+	if (status)
+		goto out;
+	status = nfsd4_decode_opaque(argp, &exid->clname);
+	if (status)
+		goto out;
+
+	READ_BUF(4);
+	exid->flags = be32_to_cpup(p++);
+
+	status = nfsd4_decode_state_protect4_a(argp, exid);
+	if (status)
+		goto out;
+
 	READ_BUF(4);    /* nfs_impl_id4 array length */
 	dummy = be32_to_cpup(p++);
 
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 6245004a9993..232529bc1b79 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -433,7 +433,7 @@ struct nfsd4_exchange_id {
 	u32		flags;
 	clientid_t	clientid;
 	u32		seqid;
-	int		spa_how;
+	u32		spa_how;
 	u32             spo_must_enforce[3];
 	u32             spo_must_allow[3];
 	struct xdr_netobj nii_domain;



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

* [PATCH v1 40/61] NFSD: Replace READ* macros in nfsd4_decode_exchange_id()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (38 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 39/61] NFSD: Add a helper to decode state_protect4_a Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:05 ` [PATCH v1 41/61] NFSD: Replace READ* macros in nfsd4_decode_create_session() Chuck Lever
                   ` (20 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index d3e238b538d0..6897078bde82 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1567,8 +1567,8 @@ static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 			 struct nfsd4_exchange_id *exid)
 {
-	DECODE_HEAD;
-	int dummy;
+	__be32 status;
+	u32 dummy;
 
 	status = nfsd4_decode_verifier4(argp, &exid->verifier);
 	if (status)
@@ -1577,16 +1577,16 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 	if (status)
 		goto out;
 
-	READ_BUF(4);
-	exid->flags = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &exid->flags) < 0)
+		goto xdr_error;
 
 	status = nfsd4_decode_state_protect4_a(argp, exid);
 	if (status)
 		goto out;
 
-	READ_BUF(4);    /* nfs_impl_id4 array length */
-	dummy = be32_to_cpup(p++);
-
+	/* nfs_impl_id4 array length */
+	if (xdr_stream_decode_u32(argp->xdr, &dummy) < 0)
+		goto xdr_error;
 	if (dummy > 1)
 		goto xdr_error;
 
@@ -1605,7 +1605,12 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 		if (status)
 			goto xdr_error;
 	}
-	DECODE_TAIL;
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 41/61] NFSD: Replace READ* macros in nfsd4_decode_create_session()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (39 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 40/61] NFSD: Replace READ* macros in nfsd4_decode_exchange_id() Chuck Lever
@ 2020-11-13 15:05 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 42/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_session() Chuck Lever
                   ` (19 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:05 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 6897078bde82..dfd2008db299 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1617,15 +1617,20 @@ static __be32
 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 			    struct nfsd4_create_session *sess)
 {
-	DECODE_HEAD;
+	__be32 *p, status;
 
-	READ_BUF(16);
-	COPYMEM(&sess->clientid, 8);
-	sess->seqid = be32_to_cpup(p++);
-	sess->flags = be32_to_cpup(p++);
+	status = nfsd4_decode_clientid4(argp, &sess->clientid);
+	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &sess->seqid) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &sess->flags) < 0)
+		goto xdr_error;
 
 	/* Fore channel attrs */
-	READ_BUF(28);
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 7);
+	if (!p)
+		goto xdr_error;
 	p++; /* headerpadsz is always 0 */
 	sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
 	sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
@@ -1634,15 +1639,17 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 	sess->fore_channel.maxreqs = be32_to_cpup(p++);
 	sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++);
 	if (sess->fore_channel.nr_rdma_attrs == 1) {
-		READ_BUF(4);
-		sess->fore_channel.rdma_attrs = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &sess->fore_channel.rdma_attrs) < 0)
+			goto xdr_error;
 	} else if (sess->fore_channel.nr_rdma_attrs > 1) {
 		dprintk("Too many fore channel attr bitmaps!\n");
 		goto xdr_error;
 	}
 
 	/* Back channel attrs */
-	READ_BUF(28);
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 7);
+	if (!p)
+		goto xdr_error;
 	p++; /* headerpadsz is always 0 */
 	sess->back_channel.maxreq_sz = be32_to_cpup(p++);
 	sess->back_channel.maxresp_sz = be32_to_cpup(p++);
@@ -1651,17 +1658,24 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 	sess->back_channel.maxreqs = be32_to_cpup(p++);
 	sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++);
 	if (sess->back_channel.nr_rdma_attrs == 1) {
-		READ_BUF(4);
-		sess->back_channel.rdma_attrs = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &sess->back_channel.rdma_attrs) < 0)
+			goto xdr_error;
 	} else if (sess->back_channel.nr_rdma_attrs > 1) {
 		dprintk("Too many back channel attr bitmaps!\n");
 		goto xdr_error;
 	}
 
-	READ_BUF(4);
-	sess->callback_prog = be32_to_cpup(p++);
-	nfsd4_decode_cb_sec(argp, &sess->cb_sec);
-	DECODE_TAIL;
+	if (xdr_stream_decode_u32(argp->xdr, &sess->callback_prog) < 0)
+		goto xdr_error;
+	status = nfsd4_decode_cb_sec(argp, &sess->cb_sec);
+	if (status)
+		goto out;
+
+	status = nfs_ok;
+out:
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 42/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_session()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (40 preceding siblings ...)
  2020-11-13 15:05 ` [PATCH v1 41/61] NFSD: Replace READ* macros in nfsd4_decode_create_session() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 43/61] NFSD: Replace READ* macros in nfsd4_decode_free_stateid() Chuck Lever
                   ` (18 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index dfd2008db299..a6b7533947dc 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1682,11 +1682,7 @@ static __be32
 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
 			     struct nfsd4_destroy_session *destroy_session)
 {
-	DECODE_HEAD;
-	READ_BUF(NFS4_MAX_SESSIONID_LEN);
-	COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
-
-	DECODE_TAIL;
+	return nfsd4_decode_sessionid(argp, &destroy_session->sessionid);
 }
 
 static __be32



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

* [PATCH v1 43/61] NFSD: Replace READ* macros in nfsd4_decode_free_stateid()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (41 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 42/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_session() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 44/61] NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo() Chuck Lever
                   ` (17 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index a6b7533947dc..c752924e2cdf 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1689,13 +1689,7 @@ static __be32
 nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 			  struct nfsd4_free_stateid *free_stateid)
 {
-	DECODE_HEAD;
-
-	READ_BUF(sizeof(stateid_t));
-	free_stateid->fr_stateid.si_generation = be32_to_cpup(p++);
-	COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
-
-	DECODE_TAIL;
+	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
 static __be32



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

* [PATCH v1 44/61] NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (42 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 43/61] NFSD: Replace READ* macros in nfsd4_decode_free_stateid() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 45/61] NFSD: Replace READ* macros in nfsd4_decode_layoutcommit() Chuck Lever
                   ` (16 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c752924e2cdf..44ffcaac3c8e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -570,6 +570,23 @@ nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 	return nfserr_bad_xdr;
 }
 
+#ifdef CONFIG_NFSD_PNFS
+static __be32
+nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
+		       struct nfsd4_deviceid *devid)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
+	if (!p)
+		goto xdr_error;
+	memcpy(devid, p, sizeof(*devid));
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+#endif /* CONFIG_NFSD_PNFS */
+
 static __be32 nfsd4_decode_sessionid(struct nfsd4_compoundargs *argp,
 				     struct nfs4_sessionid *sessionid)
 {
@@ -1769,27 +1786,24 @@ static __be32
 nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
 		struct nfsd4_getdeviceinfo *gdev)
 {
-	DECODE_HEAD;
-	u32 num, i;
-
-	READ_BUF(sizeof(struct nfsd4_deviceid) + 3 * 4);
-	COPYMEM(&gdev->gd_devid, sizeof(struct nfsd4_deviceid));
-	gdev->gd_layout_type = be32_to_cpup(p++);
-	gdev->gd_maxcount = be32_to_cpup(p++);
-	num = be32_to_cpup(p++);
-	if (num) {
-		if (num > 1000)
-			goto xdr_error;
-		READ_BUF(4 * num);
-		gdev->gd_notify_types = be32_to_cpup(p++);
-		for (i = 1; i < num; i++) {
-			if (be32_to_cpup(p++)) {
-				status = nfserr_inval;
-				goto out;
-			}
-		}
-	}
-	DECODE_TAIL;
+	__be32 status;
+
+	status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
+	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_maxcount) < 0)
+		goto xdr_error;
+	status = nfsd4_decode_bitmap4(argp, &gdev->gd_notify_types, 1);
+	if (status)
+		goto out;
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 45/61] NFSD: Replace READ* macros in nfsd4_decode_layoutcommit()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (43 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 44/61] NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 46/61] NFSD: Replace READ* macros in nfsd4_decode_layoutget() Chuck Lever
                   ` (15 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 44ffcaac3c8e..7ef6baf9c3b7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1806,6 +1806,57 @@ nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
 	return nfserr_bad_xdr;
 }
 
+static __be32
+nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
+		struct nfsd4_layoutcommit *lcp)
+{
+	__be32 *p, status;
+
+	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.length) < 0)
+		goto xdr_error;
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32));
+	if (!p)
+		goto xdr_error;
+	lcp->lc_reclaim = (*p == xdr_zero) ? 0 : 1;
+	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
+	if (status)
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_newoffset) < 0)
+		goto xdr_error;
+	if (lcp->lc_newoffset) {
+		if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_last_wr) < 0)
+			goto xdr_error;
+	} else
+		lcp->lc_last_wr = 0;
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32));
+	if (!p)
+		goto xdr_error;
+	if (xdr_item_is_present(p)) {
+		status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
+		if (status)
+			goto out;
+	} else {
+		lcp->lc_mtime.tv_nsec = UTIME_NOW;
+	}
+	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_layout_type) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_up_len) < 0)
+		goto xdr_error;
+	if (lcp->lc_up_len > 0) {
+		lcp->lc_up_layout = xdr_inline_decode(argp->xdr, lcp->lc_up_len);
+		if (!lcp->lc_up_layout)
+			goto xdr_error;
+	}
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutget *lgp)
@@ -1830,54 +1881,6 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 	DECODE_TAIL;
 }
 
-static __be32
-nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
-		struct nfsd4_layoutcommit *lcp)
-{
-	DECODE_HEAD;
-	u32 timechange;
-
-	READ_BUF(20);
-	p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
-	p = xdr_decode_hyper(p, &lcp->lc_seg.length);
-	lcp->lc_reclaim = be32_to_cpup(p++);
-
-	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
-	if (status)
-		return status;
-
-	READ_BUF(4);
-	lcp->lc_newoffset = be32_to_cpup(p++);
-	if (lcp->lc_newoffset) {
-		READ_BUF(8);
-		p = xdr_decode_hyper(p, &lcp->lc_last_wr);
-	} else
-		lcp->lc_last_wr = 0;
-	READ_BUF(4);
-	timechange = be32_to_cpup(p++);
-	if (timechange) {
-		status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
-		if (status)
-			return status;
-	} else {
-		lcp->lc_mtime.tv_nsec = UTIME_NOW;
-	}
-	READ_BUF(8);
-	lcp->lc_layout_type = be32_to_cpup(p++);
-
-	/*
-	 * Save the layout update in XDR format and let the layout driver deal
-	 * with it later.
-	 */
-	lcp->lc_up_len = be32_to_cpup(p++);
-	if (lcp->lc_up_len > 0) {
-		READ_BUF(lcp->lc_up_len);
-		READMEM(lcp->lc_up_layout, lcp->lc_up_len);
-	}
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutreturn *lrp)



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

* [PATCH v1 46/61] NFSD: Replace READ* macros in nfsd4_decode_layoutget()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (44 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 45/61] NFSD: Replace READ* macros in nfsd4_decode_layoutcommit() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 47/61] NFSD: Replace READ* macros in nfsd4_decode_layoutreturn() Chuck Lever
                   ` (14 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 7ef6baf9c3b7..c48fa1427421 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1861,24 +1861,31 @@ static __be32
 nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 		struct nfsd4_layoutget *lgp)
 {
-	DECODE_HEAD;
-
-	READ_BUF(36);
-	lgp->lg_signal = be32_to_cpup(p++);
-	lgp->lg_layout_type = be32_to_cpup(p++);
-	lgp->lg_seg.iomode = be32_to_cpup(p++);
-	p = xdr_decode_hyper(p, &lgp->lg_seg.offset);
-	p = xdr_decode_hyper(p, &lgp->lg_seg.length);
-	p = xdr_decode_hyper(p, &lgp->lg_minlength);
+	__be32 status;
 
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_signal) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_layout_type) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_seg.iomode) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.length) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_minlength) < 0)
+		goto xdr_error;
 	status = nfsd4_decode_stateid4(argp, &lgp->lg_sid);
 	if (status)
-		return status;
-
-	READ_BUF(4);
-	lgp->lg_maxcount = be32_to_cpup(p++);
+		goto out;
+	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_maxcount) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 47/61] NFSD: Replace READ* macros in nfsd4_decode_layoutreturn()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (45 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 46/61] NFSD: Replace READ* macros in nfsd4_decode_layoutget() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 48/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name() Chuck Lever
                   ` (13 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c48fa1427421..91f2612b3d2c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1889,37 +1889,63 @@ nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
 }
 
 static __be32
-nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
-		struct nfsd4_layoutreturn *lrp)
+nfsd4_decode_layoutreturn4(struct nfsd4_compoundargs *argp,
+			   struct nfsd4_layoutreturn *lrp)
 {
-	DECODE_HEAD;
-
-	READ_BUF(16);
-	lrp->lr_reclaim = be32_to_cpup(p++);
-	lrp->lr_layout_type = be32_to_cpup(p++);
-	lrp->lr_seg.iomode = be32_to_cpup(p++);
-	lrp->lr_return_type = be32_to_cpup(p++);
-	if (lrp->lr_return_type == RETURN_FILE) {
-		READ_BUF(16);
-		p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
-		p = xdr_decode_hyper(p, &lrp->lr_seg.length);
+	__be32 status;
 
+	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_return_type) < 0)
+		goto xdr_error;
+	switch (lrp->lr_return_type) {
+	case RETURN_FILE:
+		if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.offset) < 0)
+			goto xdr_error;
+		if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.length) < 0)
+			goto xdr_error;
 		status = nfsd4_decode_stateid4(argp, &lrp->lr_sid);
 		if (status)
-			return status;
-
-		READ_BUF(4);
-		lrp->lrf_body_len = be32_to_cpup(p++);
+			goto out;
+		if (xdr_stream_decode_u32(argp->xdr, &lrp->lrf_body_len) < 0)
+			goto xdr_error;
 		if (lrp->lrf_body_len > 0) {
-			READ_BUF(lrp->lrf_body_len);
-			READMEM(lrp->lrf_body, lrp->lrf_body_len);
+			lrp->lrf_body = xdr_inline_decode(argp->xdr, lrp->lrf_body_len);
+			if (!lrp->lrf_body)
+				goto xdr_error;
 		}
-	} else {
+		break;
+	case RETURN_FSID:
+	case RETURN_ALL:
 		lrp->lr_seg.offset = 0;
 		lrp->lr_seg.length = NFS4_MAX_UINT64;
+		break;
+	default:
+		goto xdr_error;
 	}
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
+static __be32
+nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
+		struct nfsd4_layoutreturn *lrp)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32));
+	if (!p)
+		goto xdr_error;
+	lrp->lr_reclaim = (*p == xdr_zero) ? 0 : 1;
+	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_layout_type) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_seg.iomode) < 0)
+		goto xdr_error;
+	return nfsd4_decode_layoutreturn4(argp, lrp);
+xdr_error:
+	return nfserr_bad_xdr;
 }
 #endif /* CONFIG_NFSD_PNFS */
 



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

* [PATCH v1 48/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (46 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 47/61] NFSD: Replace READ* macros in nfsd4_decode_layoutreturn() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 49/61] NFSD: Replace READ* macros in nfsd4_decode_sequence() Chuck Lever
                   ` (12 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 91f2612b3d2c..9585cb9febbc 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1283,17 +1283,6 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen);
 }
 
-static __be32
-nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
-		     struct nfsd4_secinfo_no_name *sin)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	sin->sin_style = be32_to_cpup(p++);
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
 {
@@ -1949,6 +1938,17 @@ nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
 }
 #endif /* CONFIG_NFSD_PNFS */
 
+static __be32
+nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
+		     struct nfsd4_secinfo_no_name *sin)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0)
+		goto xdr_error;
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)



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

* [PATCH v1 49/61] NFSD: Replace READ* macros in nfsd4_decode_sequence()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (47 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 48/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 50/61] NFSD: Replace READ* macros in nfsd4_decode_test_stateid() Chuck Lever
                   ` (11 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9585cb9febbc..7b4f7f8c44da 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1698,22 +1698,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32
-nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
-		      struct nfsd4_sequence *seq)
-{
-	DECODE_HEAD;
-
-	READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
-	COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
-	seq->seqid = be32_to_cpup(p++);
-	seq->slotid = be32_to_cpup(p++);
-	seq->maxslots = be32_to_cpup(p++);
-	seq->cachethis = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 static __be32
 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
 {
@@ -1949,6 +1933,30 @@ nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
 	return nfserr_bad_xdr;
 }
 
+static __be32
+nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
+		      struct nfsd4_sequence *seq)
+{
+	__be32 *p, status;
+
+	status = nfsd4_decode_sessionid(argp, &seq->sessionid);
+	if (status)
+		goto out;
+	p = xdr_inline_decode(argp->xdr, sizeof(__be32) * 4);
+	if (!p)
+		goto xdr_error;
+	seq->seqid = be32_to_cpup(p++);
+	seq->slotid = be32_to_cpup(p++);
+	seq->maxslots = be32_to_cpup(p++);
+	seq->cachethis = be32_to_cpup(p++);
+
+	status = nfs_ok;
+out:
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)



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

* [PATCH v1 50/61] NFSD: Replace READ* macros in nfsd4_decode_test_stateid()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (48 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 49/61] NFSD: Replace READ* macros in nfsd4_decode_sequence() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 51/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid() Chuck Lever
                   ` (10 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 7b4f7f8c44da..4e9f911366ef 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1698,42 +1698,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32
-nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
-{
-	int i;
-	__be32 *p, status;
-	struct nfsd4_test_stateid_id *stateid;
-
-	READ_BUF(4);
-	test_stateid->ts_num_ids = ntohl(*p++);
-
-	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
-
-	for (i = 0; i < test_stateid->ts_num_ids; i++) {
-		stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
-		if (!stateid) {
-			status = nfserrno(-ENOMEM);
-			goto out;
-		}
-
-		INIT_LIST_HEAD(&stateid->ts_id_list);
-		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
-
-		status = nfsd4_decode_stateid4(argp, &stateid->ts_id_stateid);
-		if (status)
-			goto out;
-	}
-
-	status = 0;
-out:
-	return status;
-xdr_error:
-	dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
-	status = nfserr_bad_xdr;
-	goto out;
-}
-
 static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
 {
 	DECODE_HEAD;
@@ -1957,6 +1921,37 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
 	return nfserr_bad_xdr;
 }
 
+static __be32
+nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
+{
+	struct nfsd4_test_stateid_id *stateid;
+	__be32 status;
+	u32 i;
+
+	if (xdr_stream_decode_u32(argp->xdr, &test_stateid->ts_num_ids) < 0)
+		goto xdr_error;
+
+	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
+	for (i = 0; i < test_stateid->ts_num_ids; i++) {
+		stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
+		if (!stateid)
+			goto nomem;
+		INIT_LIST_HEAD(&stateid->ts_id_list);
+		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
+		status = nfsd4_decode_stateid4(argp, &stateid->ts_id_stateid);
+		if (status)
+			goto out;
+	}
+
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserrno(-ENOMEM);
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)



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

* [PATCH v1 51/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (49 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 50/61] NFSD: Replace READ* macros in nfsd4_decode_test_stateid() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:06 ` [PATCH v1 52/61] NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete() Chuck Lever
                   ` (9 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4e9f911366ef..c69dbe8f5ff2 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1698,16 +1698,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
-{
-	DECODE_HEAD;
-
-	READ_BUF(8);
-	COPYMEM(&dc->clientid, 8);
-
-	DECODE_TAIL;
-}
-
 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
 {
 	DECODE_HEAD;
@@ -1952,6 +1942,11 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta
 	return nfserrno(-ENOMEM);
 }
 
+static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
+{
+	return nfsd4_decode_clientid4(argp, &dc->clientid);
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)



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

* [PATCH v1 52/61] NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (50 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 51/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid() Chuck Lever
@ 2020-11-13 15:06 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 53/61] NFSD: Replace READ* macros in nfsd4_decode_fallocate() Chuck Lever
                   ` (8 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:06 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c69dbe8f5ff2..94e96bf09cc1 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1698,16 +1698,6 @@ nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
 	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
 }
 
-static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
-{
-	DECODE_HEAD;
-
-	READ_BUF(4);
-	rc->rca_one_fs = be32_to_cpup(p++);
-
-	DECODE_TAIL;
-}
-
 #ifdef CONFIG_NFSD_PNFS
 static __be32
 nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
@@ -1947,6 +1937,13 @@ static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, str
 	return nfsd4_decode_clientid4(argp, &dc->clientid);
 }
 
+static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
+{
+	if (xdr_stream_decode_u32(argp->xdr, &rc->rca_one_fs) < 0)
+		return nfserr_bad_xdr;
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)



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

* [PATCH v1 53/61] NFSD: Replace READ* macros in nfsd4_decode_fallocate()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (51 preceding siblings ...)
  2020-11-13 15:06 ` [PATCH v1 52/61] NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 54/61] NFSD: Replace READ* macros in nfsd4_decode_clone() Chuck Lever
                   ` (7 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 94e96bf09cc1..9afdb83c5c23 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1948,17 +1948,21 @@ static __be32
 nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 		       struct nfsd4_fallocate *fallocate)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid);
 	if (status)
-		return status;
-
-	READ_BUF(16);
-	p = xdr_decode_hyper(p, &fallocate->falloc_offset);
-	xdr_decode_hyper(p, &fallocate->falloc_length);
+		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_length) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 54/61] NFSD: Replace READ* macros in nfsd4_decode_clone()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (52 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 53/61] NFSD: Replace READ* macros in nfsd4_decode_fallocate() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 55/61] NFSD: Replace READ* macros in nfsd4_decode_copy() Chuck Lever
                   ` (6 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9afdb83c5c23..7e969f04f62f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1968,20 +1968,26 @@ nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid);
 	if (status)
 		return status;
 	status = nfsd4_decode_stateid4(argp, &clone->cl_dst_stateid);
 	if (status)
-		return status;
+		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_src_pos) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_dst_pos) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_count) < 0)
+		goto xdr_error;
 
-	READ_BUF(8 + 8 + 8);
-	p = xdr_decode_hyper(p, &clone->cl_src_pos);
-	p = xdr_decode_hyper(p, &clone->cl_dst_pos);
-	p = xdr_decode_hyper(p, &clone->cl_count);
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,



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

* [PATCH v1 55/61] NFSD: Replace READ* macros in nfsd4_decode_copy()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (53 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 54/61] NFSD: Replace READ* macros in nfsd4_decode_clone() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 56/61] NFSD: Replace READ* macros in nfsd4_decode_seek() Chuck Lever
                   ` (5 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 7e969f04f62f..408da2625dba 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1993,43 +1993,51 @@ nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
 static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
 				      struct nl4_server *ns)
 {
-	DECODE_HEAD;
 	struct nfs42_netaddr *naddr;
+	__be32 *p;
 
-	READ_BUF(4);
-	ns->nl4_type = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &ns->nl4_type) < 0)
+		goto xdr_error;
 
 	/* currently support for 1 inter-server source server */
 	switch (ns->nl4_type) {
 	case NL4_NETADDR:
 		naddr = &ns->u.nl4_addr;
 
-		READ_BUF(4);
-		naddr->netid_len = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &naddr->netid_len) < 0)
+			goto xdr_error;
 		if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
 			goto xdr_error;
 
-		READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */
-		COPYMEM(naddr->netid, naddr->netid_len);
+		p = xdr_inline_decode(argp->xdr, naddr->netid_len);
+		if (!p)
+			goto xdr_error;
+		memcpy(naddr->netid, p, naddr->netid_len);
 
-		naddr->addr_len = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &naddr->addr_len) < 0)
+			goto xdr_error;
 		if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
 			goto xdr_error;
 
-		READ_BUF(naddr->addr_len);
-		COPYMEM(naddr->addr, naddr->addr_len);
+		p = xdr_inline_decode(argp->xdr, naddr->addr_len);
+		if (!p)
+			goto xdr_error;
+		memcpy(naddr->addr, p, naddr->addr_len);
 		break;
 	default:
 		goto xdr_error;
 	}
-	DECODE_TAIL;
+
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32
 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 {
-	DECODE_HEAD;
 	struct nl4_server *ns_dummy;
+	__be32 *p, status;
 	int i, count;
 
 	status = nfsd4_decode_stateid4(argp, &copy->cp_src_stateid);
@@ -2039,7 +2047,9 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 	if (status)
 		return status;
 
-	READ_BUF(8 + 8 + 8 + 4 + 4 + 4);
+	p = xdr_inline_decode(argp->xdr, sizeof(__be64) * 3 + sizeof(__be32) * 3);
+	if (!p)
+		goto xdr_error;
 	p = xdr_decode_hyper(p, &copy->cp_src_pos);
 	p = xdr_decode_hyper(p, &copy->cp_dst_pos);
 	p = xdr_decode_hyper(p, &copy->cp_count);
@@ -2057,7 +2067,7 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 	/* decode all the supplied server addresses but use first */
 	status = nfsd4_decode_nl4_server(argp, &copy->cp_src);
 	if (status)
-		return status;
+		goto out;
 
 	ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
 	if (ns_dummy == NULL)
@@ -2071,8 +2081,11 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 	}
 	kfree(ns_dummy);
 intra:
-
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 static __be32



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

* [PATCH v1 56/61] NFSD: Replace READ* macros in nfsd4_decode_seek()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (54 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 55/61] NFSD: Replace READ* macros in nfsd4_decode_copy() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 57/61] NFSD: Replace READ* macros in nfsd4_decode_xattr_name() Chuck Lever
                   ` (4 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 408da2625dba..1f7eb2f67390 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2110,17 +2110,21 @@ nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 {
-	DECODE_HEAD;
+	__be32 status;
 
 	status = nfsd4_decode_stateid4(argp, &seek->seek_stateid);
 	if (status)
-		return status;
-
-	READ_BUF(8 + 4);
-	p = xdr_decode_hyper(p, &seek->seek_offset);
-	seek->seek_whence = be32_to_cpup(p);
+		goto out;
+	if (xdr_stream_decode_u64(argp->xdr, &seek->seek_offset) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &seek->seek_whence) < 0)
+		goto xdr_error;
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
 }
 
 /*



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

* [PATCH v1 57/61] NFSD: Replace READ* macros in nfsd4_decode_xattr_name()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (55 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 56/61] NFSD: Replace READ* macros in nfsd4_decode_seek() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 58/61] NFSD: Replace READ* macros in nfsd4_decode_setxattr() Chuck Lever
                   ` (3 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1f7eb2f67390..12b90251fbf5 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2187,12 +2187,12 @@ nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
 static __be32
 nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
 {
-	DECODE_HEAD;
 	char *name, *sp, *dp;
 	u32 namelen, cnt;
+	__be32 *p;
 
-	READ_BUF(4);
-	namelen = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &namelen) < 0)
+		goto xdr_error;
 
 	if (namelen > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN))
 		return nfserr_nametoolong;
@@ -2200,12 +2200,12 @@ nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
 	if (namelen == 0)
 		goto xdr_error;
 
-	READ_BUF(namelen);
-
+	p = xdr_inline_decode(argp->xdr, namelen);
+	if (!p)
+		goto xdr_error;
 	name = svcxdr_tmpalloc(argp, namelen + XATTR_USER_PREFIX_LEN + 1);
 	if (!name)
-		return nfserr_jukebox;
-
+		goto nomem;
 	memcpy(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
 
 	/*
@@ -2225,7 +2225,11 @@ nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
 
 	*namep = name;
 
-	DECODE_TAIL;
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
 /*



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

* [PATCH v1 58/61] NFSD: Replace READ* macros in nfsd4_decode_setxattr()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (56 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 57/61] NFSD: Replace READ* macros in nfsd4_decode_xattr_name() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 59/61] NFSD: Replace READ* macros in nfsd4_decode_listxattrs() Chuck Lever
                   ` (2 subsequent siblings)
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 12b90251fbf5..760aac341fab 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2261,25 +2261,25 @@ static __be32
 nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 		      struct nfsd4_setxattr *setxattr)
 {
-	DECODE_HEAD;
 	u32 flags, maxcount, size;
+	__be32 status;
 
-	READ_BUF(4);
-	flags = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &flags) < 0)
+		goto xdr_error;
 
 	if (flags > SETXATTR4_REPLACE)
-		return nfserr_inval;
+		goto inval_arg;
 	setxattr->setxa_flags = flags;
 
 	status = nfsd4_decode_xattr_name(argp, &setxattr->setxa_name);
 	if (status)
-		return status;
+		goto out;
 
 	maxcount = svc_max_payload(argp->rqstp);
 	maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
 
-	READ_BUF(4);
-	size = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &size) < 0)
+		goto xdr_error;
 	if (size > maxcount)
 		return nfserr_xattr2big;
 
@@ -2293,7 +2293,13 @@ nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
 						&setxattr->setxa_buf, size);
 	}
 
-	DECODE_TAIL;
+	status = nfs_ok;
+out:
+	return status;
+xdr_error:
+	return nfserr_bad_xdr;
+inval_arg:
+	return nfserr_inval;
 }
 
 static __be32



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

* [PATCH v1 59/61] NFSD: Replace READ* macros in nfsd4_decode_listxattrs()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (57 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 58/61] NFSD: Replace READ* macros in nfsd4_decode_setxattr() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 60/61] NFSD: Replace READ* macros in nfsd4_decode_compound() Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 61/61] NFSD: Remove macros that are no longer used Chuck Lever
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 760aac341fab..4332b16cfdc8 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2306,11 +2306,10 @@ static __be32
 nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
 			struct nfsd4_listxattrs *listxattrs)
 {
-	DECODE_HEAD;
 	u32 maxcount;
 
-	READ_BUF(12);
-	p = xdr_decode_hyper(p, &listxattrs->lsxa_cookie);
+	if (xdr_stream_decode_u64(argp->xdr, &listxattrs->lsxa_cookie) < 0)
+		goto xdr_error;
 
 	/*
 	 * If the cookie  is too large to have even one user.x attribute
@@ -2320,15 +2319,20 @@ nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
 	    (XATTR_LIST_MAX / (XATTR_USER_PREFIX_LEN + 2)))
 		return nfserr_badcookie;
 
-	maxcount = be32_to_cpup(p++);
+	if (xdr_stream_decode_u32(argp->xdr, &maxcount) < 0)
+		goto xdr_error;
 	if (maxcount < 8)
 		/* Always need at least 2 words (length and one character) */
-		return nfserr_inval;
+		goto inval_arg;
 
 	maxcount = min(maxcount, svc_max_payload(argp->rqstp));
 	listxattrs->lsxa_maxcount = maxcount;
 
-	DECODE_TAIL;
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+inval_arg:
+	return nfserr_inval;
 }
 
 static __be32



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

* [PATCH v1 60/61] NFSD: Replace READ* macros in nfsd4_decode_compound()
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (58 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 59/61] NFSD: Replace READ* macros in nfsd4_decode_listxattrs() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  2020-11-13 15:07 ` [PATCH v1 61/61] NFSD: Remove macros that are no longer used Chuck Lever
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4proc.c |    2 +-
 fs/nfsd/nfs4xdr.c  |   67 +++++++++++++++++++++++-----------------------------
 fs/nfsd/xdr4.h     |    2 +-
 3 files changed, 32 insertions(+), 39 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index b810d048c5f8..205e1b3ce629 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -3281,7 +3281,7 @@ int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
 void warn_on_nonidempotent_op(struct nfsd4_op *op)
 {
 	if (OPDESC(op)->op_flags & OP_MODIFIES_SOMETHING) {
-		pr_err("unable to encode reply to nonidempotent op %d (%s)\n",
+		pr_err("unable to encode reply to nonidempotent op %u (%s)\n",
 			op->opnum, nfsd4_op_name(op->opnum));
 		WARN_ON_ONCE(1);
 	}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 4332b16cfdc8..3ab248433f44 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -184,28 +184,6 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
 	return p;
 }
 
-/**
- * savemem - duplicate a chunk of memory for later processing
- * @argp: NFSv4 compound argument structure to be freed with
- * @p: pointer to be duplicated
- * @nbytes: length to be duplicated
- *
- * Returns a pointer to a copy of @nbytes bytes of memory at @p
- * that are preserved until processing of the NFSv4 compound
- * operation described by @argp finishes.
- */
-static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
-{
-	void *ret;
-
-	ret = svcxdr_tmpalloc(argp, nbytes);
-	if (!ret)
-		return NULL;
-	memcpy(ret, p, nbytes);
-	return ret;
-}
-
-
 /*
  * NFSv4 basic data type decoders
  */
@@ -2462,33 +2440,43 @@ nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
 static __be32
 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 {
-	DECODE_HEAD;
 	struct nfsd4_op *op;
 	bool cachethis = false;
 	int auth_slack= argp->rqstp->rq_auth_slack;
 	int max_reply = auth_slack + 8; /* opcnt, status */
 	int readcount = 0;
 	int readbytes = 0;
+	__be32 *p;
 	int i;
 
-	READ_BUF(4);
-	argp->taglen = be32_to_cpup(p++);
-	READ_BUF(argp->taglen);
-	SAVEMEM(argp->tag, argp->taglen);
-	READ_BUF(8);
-	argp->minorversion = be32_to_cpup(p++);
-	argp->opcnt = be32_to_cpup(p++);
-	max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
+	if (xdr_stream_decode_u32(argp->xdr, &argp->taglen) < 0)
+		goto xdr_error;
+	argp->tag = NULL;
+	if (unlikely(argp->taglen)) {
+		if (argp->taglen > NFSD4_MAX_TAGLEN)
+			goto xdr_error;
+		p = xdr_inline_decode(argp->xdr, argp->taglen);
+		if (!p)
+			goto xdr_error;
+		argp->tag = svcxdr_tmpalloc(argp, argp->taglen);
+		if (!argp->tag)
+			goto nomem;
+		memcpy(argp->tag, p, argp->taglen);
+	}
 
-	if (argp->taglen > NFSD4_MAX_TAGLEN)
+	if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
+		goto xdr_error;
+	if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
 		goto xdr_error;
+	max_reply += 4 + xdr_align_size(argp->taglen);
+
 	/*
 	 * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
 	 * here, so we return success at the xdr level so that
 	 * nfsd4_proc can handle this is an NFS-level error.
 	 */
 	if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
-		return 0;
+		goto out;
 
 	if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
 		argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
@@ -2506,8 +2494,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 		op = &argp->ops[i];
 		op->replay = NULL;
 
-		READ_BUF(4);
-		op->opnum = be32_to_cpup(p++);
+		if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
+			goto xdr_error;
 
 		if (nfsd4_opnum_in_range(argp, op))
 			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
@@ -2550,7 +2538,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 	if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
 		clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
 
-	DECODE_TAIL;
+out:
+	return nfs_ok;
+xdr_error:
+	return nfserr_bad_xdr;
+nomem:
+	return nfserr_jukebox;
 }
 
 static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
@@ -5460,7 +5453,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 	if (op->status && opdesc &&
 			!(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
 		goto status;
-	BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
+	BUG_ON(op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
 	       !nfsd4_enc_ops[op->opnum]);
 	encoder = nfsd4_enc_ops[op->opnum];
 	op->status = encoder(resp, op->status, &op->u);
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 232529bc1b79..749c2d711d21 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -615,7 +615,7 @@ struct nfsd4_copy_notify {
 };
 
 struct nfsd4_op {
-	int					opnum;
+	u32					opnum;
 	const struct nfsd4_operation *		opdesc;
 	__be32					status;
 	union nfsd4_op_u {



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

* [PATCH v1 61/61] NFSD: Remove macros that are no longer used
  2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
                   ` (59 preceding siblings ...)
  2020-11-13 15:07 ` [PATCH v1 60/61] NFSD: Replace READ* macros in nfsd4_decode_compound() Chuck Lever
@ 2020-11-13 15:07 ` Chuck Lever
  60 siblings, 0 replies; 70+ messages in thread
From: Chuck Lever @ 2020-11-13 15:07 UTC (permalink / raw)
  To: linux-nfs

Now that all the NFSv4 decoder functions have been converted to
make direct calls to the xdr helpers, remove the unused C macros.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfsd/nfs4xdr.c |   40 ----------------------------------------
 fs/nfsd/xdr4.h    |    9 ---------
 2 files changed, 49 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3ab248433f44..68d9dec9bc32 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -100,45 +100,6 @@ check_filename(char *str, int len)
 	return 0;
 }
 
-#define DECODE_HEAD				\
-	__be32 *p;				\
-	__be32 status
-#define DECODE_TAIL				\
-	status = 0;				\
-out:						\
-	return status;				\
-xdr_error:					\
-	dprintk("NFSD: xdr error (%s:%d)\n",	\
-			__FILE__, __LINE__);	\
-	status = nfserr_bad_xdr;		\
-	goto out
-
-#define READMEM(x,nbytes) do {			\
-	x = (char *)p;				\
-	p += XDR_QUADLEN(nbytes);		\
-} while (0)
-#define SAVEMEM(x,nbytes) do {			\
-	if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
- 		savemem(argp, p, nbytes) :	\
- 		(char *)p)) {			\
-		dprintk("NFSD: xdr error (%s:%d)\n", \
-				__FILE__, __LINE__); \
-		goto xdr_error;			\
-		}				\
-	p += XDR_QUADLEN(nbytes);		\
-} while (0)
-#define COPYMEM(x,nbytes) do {			\
-	memcpy((x), p, nbytes);			\
-	p += XDR_QUADLEN(nbytes);		\
-} while (0)
-#define READ_BUF(nbytes)			\
-	do {					\
-		p = xdr_inline_decode(argp->xdr,\
-				      nbytes);	\
-		if (!p)				\
-			goto xdr_error;		\
-	} while (0)
-
 static int zero_clientid(clientid_t *clid)
 {
 	return (clid->cl_boot == 0) && (clid->cl_id == 0);
@@ -5546,7 +5507,6 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
 
 	/* svcxdr_tmp_alloc */
-	args->tmpp = NULL;
 	args->to_free = NULL;
 
 	args->xdr = &rqstp->rq_xdr_stream;
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 749c2d711d21..dc951768c695 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -386,13 +386,6 @@ struct nfsd4_setclientid_confirm {
 	nfs4_verifier	sc_confirm;
 };
 
-struct nfsd4_saved_compoundargs {
-	__be32 *p;
-	__be32 *end;
-	int pagelen;
-	struct page **pagelist;
-};
-
 struct nfsd4_test_stateid_id {
 	__be32			ts_id_status;
 	stateid_t		ts_id_stateid;
@@ -696,8 +689,6 @@ struct svcxdr_tmpbuf {
 
 struct nfsd4_compoundargs {
 	/* scratch variables for XDR decode */
-	__be32				tmp[8];
-	__be32 *			tmpp;
 	struct xdr_stream		*xdr;
 	struct svcxdr_tmpbuf		*to_free;
 	struct svc_rqst			*rqstp;



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

* Re: [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access()
  2020-11-13 15:02 ` [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access() Chuck Lever
@ 2020-11-14  9:28   ` Christoph Hellwig
  2020-11-14 18:26     ` Chuck Lever
  0 siblings, 1 reply; 70+ messages in thread
From: Christoph Hellwig @ 2020-11-14  9:28 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

> +static __be32
> +nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)

Please fix up a bunch of overly long lines here and in the other
patches.

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

* Re: [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close()
  2020-11-13 15:03 ` [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close() Chuck Lever
@ 2020-11-14  9:29   ` Christoph Hellwig
  2020-11-14 18:30     ` Chuck Lever
  0 siblings, 1 reply; 70+ messages in thread
From: Christoph Hellwig @ 2020-11-14  9:29 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs

>  {
> +	__be32 *p;
>  
> +	p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
> +	if (!p)
> +		goto xdr_error;
>  	sid->si_generation = be32_to_cpup(p++);
> +	memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
> +	return nfs_ok;
> +xdr_error:
> +	return nfserr_bad_xdr;

Using a goto for a trivial direct error return looks pretty strange
and makes the code harder to follow.  This seems to happen quite a bit
in this and the following patches.

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

* Re: [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access()
  2020-11-14  9:28   ` Christoph Hellwig
@ 2020-11-14 18:26     ` Chuck Lever
  2020-11-14 18:45       ` Christoph Hellwig
  0 siblings, 1 reply; 70+ messages in thread
From: Chuck Lever @ 2020-11-14 18:26 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Linux NFS Mailing List



> On Nov 14, 2020, at 4:28 AM, Christoph Hellwig <hch@infradead.org> wrote:
> 
>> +static __be32
>> +nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
> 
> Please fix up a bunch of overly long lines here and in the other
> patches.

Not saying no, but...

Kernel coding style and scripts/checkpatch.pl were recently
updated to permit 100 character long lines. What reason is
there to shorten these?

--
Chuck Lever




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

* Re: [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close()
  2020-11-14  9:29   ` Christoph Hellwig
@ 2020-11-14 18:30     ` Chuck Lever
  2020-11-14 18:47       ` Christoph Hellwig
  0 siblings, 1 reply; 70+ messages in thread
From: Chuck Lever @ 2020-11-14 18:30 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Linux NFS Mailing List

Thanks for having a look!


> On Nov 14, 2020, at 4:29 AM, Christoph Hellwig <hch@infradead.org> wrote:
> 
>> {
>> +	__be32 *p;
>> 
>> +	p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
>> +	if (!p)
>> +		goto xdr_error;
>> 	sid->si_generation = be32_to_cpup(p++);
>> +	memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
>> +	return nfs_ok;
>> +xdr_error:
>> +	return nfserr_bad_xdr;
> 
> Using a goto for a trivial direct error return looks pretty strange
> and makes the code harder to follow.  This seems to happen quite a bit
> in this and the following patches.

Question of coding style. Some people prefer having a single
point of exit at the tail of a function.

I suppose I could simplify these smaller decoders, but it's
subjective. Anyone else have an opinion? Christoph, as an
example, how would you express this particular function?

--
Chuck Lever




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

* Re: [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access()
  2020-11-14 18:26     ` Chuck Lever
@ 2020-11-14 18:45       ` Christoph Hellwig
  2020-11-14 18:48         ` Chuck Lever
  0 siblings, 1 reply; 70+ messages in thread
From: Christoph Hellwig @ 2020-11-14 18:45 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Christoph Hellwig, Linux NFS Mailing List

On Sat, Nov 14, 2020 at 01:26:43PM -0500, Chuck Lever wrote:
> 
> 
> > On Nov 14, 2020, at 4:28 AM, Christoph Hellwig <hch@infradead.org> wrote:
> > 
> >> +static __be32
> >> +nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
> > 
> > Please fix up a bunch of overly long lines here and in the other
> > patches.
> 
> Not saying no, but...
> 
> Kernel coding style and scripts/checkpatch.pl were recently
> updated to permit 100 character long lines. What reason is
> there to shorten these?

The coding style only allows it as an exception if it significantly
improves readabily.  and modern checkpatch.pl unfortunately is wrong
more often than not.

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

* Re: [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close()
  2020-11-14 18:30     ` Chuck Lever
@ 2020-11-14 18:47       ` Christoph Hellwig
  0 siblings, 0 replies; 70+ messages in thread
From: Christoph Hellwig @ 2020-11-14 18:47 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Christoph Hellwig, Linux NFS Mailing List

On Sat, Nov 14, 2020 at 01:30:33PM -0500, Chuck Lever wrote:
> Question of coding style. Some people prefer having a single
> point of exit at the tail of a function.

While I've heard the argument of a single exit a few times, it was
usually from people that also frown upon goto labels and produces
strange deeply nested code..

> I suppose I could simplify these smaller decoders, but it's
> subjective. Anyone else have an opinion? Christoph, as an
> example, how would you express this particular function?

static __be32
nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
{
	__be32 *p;

	p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
	if (!p)
		return nfserr_bad_xdr;
	sid->si_generation = be32_to_cpup(p++);
	memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
	return nfs_ok;
}

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

* Re: [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access()
  2020-11-14 18:45       ` Christoph Hellwig
@ 2020-11-14 18:48         ` Chuck Lever
  2020-11-14 18:49           ` Christoph Hellwig
  0 siblings, 1 reply; 70+ messages in thread
From: Chuck Lever @ 2020-11-14 18:48 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Linux NFS Mailing List



> On Nov 14, 2020, at 1:45 PM, Christoph Hellwig <hch@infradead.org> wrote:
> 
> On Sat, Nov 14, 2020 at 01:26:43PM -0500, Chuck Lever wrote:
>> 
>> 
>>> On Nov 14, 2020, at 4:28 AM, Christoph Hellwig <hch@infradead.org> wrote:
>>> 
>>>> +static __be32
>>>> +nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
>>> 
>>> Please fix up a bunch of overly long lines here and in the other
>>> patches.
>> 
>> Not saying no, but...
>> 
>> Kernel coding style and scripts/checkpatch.pl were recently
>> updated to permit 100 character long lines. What reason is
>> there to shorten these?
> 
> The coding style only allows it as an exception if it significantly
> improves readabily.  and modern checkpatch.pl unfortunately is wrong
> more often than not.

So you would prefer:

static __be32 nfsd4_decode_access(struct nfsd4_compoundargs *argp,
                                  struct nfsd4_access *access)

?

--
Chuck Lever




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

* Re: [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access()
  2020-11-14 18:48         ` Chuck Lever
@ 2020-11-14 18:49           ` Christoph Hellwig
  0 siblings, 0 replies; 70+ messages in thread
From: Christoph Hellwig @ 2020-11-14 18:49 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Christoph Hellwig, Linux NFS Mailing List

On Sat, Nov 14, 2020 at 01:48:13PM -0500, Chuck Lever wrote:
> So you would prefer:
> 
> static __be32 nfsd4_decode_access(struct nfsd4_compoundargs *argp,
>                                   struct nfsd4_access *access)
> 
> ?

My personal preference is two tab alignments for the continuation
line, but that vs aligning to the opening brace has always been one
of two options with people picking one (another thing recent
checkpatch.pl gets wrong).

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

end of thread, back to index

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-13 15:02 [PATCH v1 00/61] Update NFSD XDR functions Chuck Lever
2020-11-13 15:02 ` [PATCH v1 01/61] NFSD: Fix returned READDIR offset cookie Chuck Lever
2020-11-13 15:02 ` [PATCH v1 02/61] SUNRPC: Add xdr_set_scratch_page() and xdr_reset_scratch_buffer() Chuck Lever
2020-11-13 15:02 ` [PATCH v1 03/61] SUNRPC: Prepare for xdr_stream-style decoding on the server-side Chuck Lever
2020-11-13 15:02 ` [PATCH v1 04/61] NFSD: Add common helpers to decode void args and encode void results Chuck Lever
2020-11-13 15:02 ` [PATCH v1 05/61] NFSD: Replace the internals of the READ_BUF() macro Chuck Lever
2020-11-13 15:02 ` [PATCH v1 06/61] NFSD: Replace READ* macros in nfsd4_decode_access() Chuck Lever
2020-11-14  9:28   ` Christoph Hellwig
2020-11-14 18:26     ` Chuck Lever
2020-11-14 18:45       ` Christoph Hellwig
2020-11-14 18:48         ` Chuck Lever
2020-11-14 18:49           ` Christoph Hellwig
2020-11-13 15:03 ` [PATCH v1 07/61] NFSD: Replace READ* macros in nfsd4_decode_close() Chuck Lever
2020-11-14  9:29   ` Christoph Hellwig
2020-11-14 18:30     ` Chuck Lever
2020-11-14 18:47       ` Christoph Hellwig
2020-11-13 15:03 ` [PATCH v1 08/61] NFSD: Replace READ* macros in nfsd4_decode_commit() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 09/61] NFSD: Replace READ* macros in nfsd4_decode_create() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 10/61] NFSD: Replace READ* macros in nfsd4_decode_bitmap() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 11/61] NFSD: Replace READ* macros in nfsd4_decode_link() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 12/61] NFSD: Relocate nfsd4_decode_opaque() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 13/61] NFSD: Replace READ* macros in nfsd4_decode_lock() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 14/61] NFSD: Replace READ* macros in nfsd4_decode_lockt() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 15/61] NFSD: Replace READ* macros in nfsd4_decode_locku() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 16/61] NFSD: Replace READ* macros in nfsd4_decode_lookup() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 17/61] NFSD: Replace READ* macros in nfsd4_decode_time() Chuck Lever
2020-11-13 15:03 ` [PATCH v1 18/61] NFSD: Replace READ* macros in nfsd4_decode_fattr() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 19/61] NFSD: Replace READ* macros in nfsd4_decode_open() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 20/61] NFSD: Replace READ* macros in nfsd4_decode_open_confirm() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 21/61] NFSD: Replace READ* macros in nfsd4_decode_open_downgrade() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 22/61] NFSD: Replace READ* macros in nfsd4_decode_putfh() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 23/61] NFSD: Replace READ* macros in nfsd4_decode_read() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 24/61] NFSD: Replace READ* macros in nfsd4_decode_readdir() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 25/61] NFSD: Replace READ* macros in nfsd4_decode_remove() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 26/61] NFSD: Replace READ* macros in nfsd4_decode_rename() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 27/61] NFSD: Replace READ* macros in nfsd4_decode_renew() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 28/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo() Chuck Lever
2020-11-13 15:04 ` [PATCH v1 29/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 30/61] NFSD: Replace READ* macros in nfsd4_decode_setclientid_confirm() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 31/61] NFSD: Replace READ* macros in nfsd4_decode_verify() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 32/61] NFSD: Replace READ* macros in nfsd4_decode_write() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 33/61] NFSD: Replace READ* macros in nfsd4_decode_release_lockowner() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 34/61] NFSD: Replace READ* macros in nfsd4_decode_cb_sec() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 35/61] NFSD: Replace READ* macros in nfsd4_decode_backchannel_ctl() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 36/61] NFSD: Replace READ* macros in nfsd4_decode_bind_conn_to_session() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 37/61] NFSD: Add a separate decoder to handle state_protect_ops Chuck Lever
2020-11-13 15:05 ` [PATCH v1 38/61] NFSD: Add a separate decoder for ssv_sp_parms Chuck Lever
2020-11-13 15:05 ` [PATCH v1 39/61] NFSD: Add a helper to decode state_protect4_a Chuck Lever
2020-11-13 15:05 ` [PATCH v1 40/61] NFSD: Replace READ* macros in nfsd4_decode_exchange_id() Chuck Lever
2020-11-13 15:05 ` [PATCH v1 41/61] NFSD: Replace READ* macros in nfsd4_decode_create_session() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 42/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_session() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 43/61] NFSD: Replace READ* macros in nfsd4_decode_free_stateid() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 44/61] NFSD: Replace READ* macros in nfsd4_decode_getdeviceinfo() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 45/61] NFSD: Replace READ* macros in nfsd4_decode_layoutcommit() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 46/61] NFSD: Replace READ* macros in nfsd4_decode_layoutget() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 47/61] NFSD: Replace READ* macros in nfsd4_decode_layoutreturn() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 48/61] NFSD: Replace READ* macros in nfsd4_decode_secinfo_no_name() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 49/61] NFSD: Replace READ* macros in nfsd4_decode_sequence() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 50/61] NFSD: Replace READ* macros in nfsd4_decode_test_stateid() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 51/61] NFSD: Replace READ* macros in nfsd4_decode_destroy_clientid() Chuck Lever
2020-11-13 15:06 ` [PATCH v1 52/61] NFSD: Replace READ* macros in nfsd4_decode_reclaim_complete() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 53/61] NFSD: Replace READ* macros in nfsd4_decode_fallocate() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 54/61] NFSD: Replace READ* macros in nfsd4_decode_clone() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 55/61] NFSD: Replace READ* macros in nfsd4_decode_copy() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 56/61] NFSD: Replace READ* macros in nfsd4_decode_seek() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 57/61] NFSD: Replace READ* macros in nfsd4_decode_xattr_name() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 58/61] NFSD: Replace READ* macros in nfsd4_decode_setxattr() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 59/61] NFSD: Replace READ* macros in nfsd4_decode_listxattrs() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 60/61] NFSD: Replace READ* macros in nfsd4_decode_compound() Chuck Lever
2020-11-13 15:07 ` [PATCH v1 61/61] NFSD: Remove macros that are no longer used Chuck Lever

Linux-NFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \
		linux-nfs@vger.kernel.org
	public-inbox-index linux-nfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-nfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git