Linux NFS development
 help / color / mirror / Atom feed
* [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders
@ 2023-10-09 18:29 Chuck Lever
  2023-10-09 18:29 ` [PATCH v1 1/8] NFSD: Clean up nfsd4_encode_access() Chuck Lever
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:29 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

Tidy up the server-side XDR result encoders for remaining
miscellanous NFSv4 operations. Series applies to nfsd-next. See
topic branch "nfsd4-encoder-overhaul" in this repo:

https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git

---

Chuck Lever (8):
      NFSD: Clean up nfsd4_encode_access()
      NFSD: Clean up nfsd4_do_encode_secinfo()
      NFSD: Clean up nfsd4_encode_exchange_id()
      NFSD: Clean up nfsd4_encode_test_stateid()
      NFSD: Clean up nfsd4_encode_copy()
      NFSD: Clean up nfsd4_encode_copy_notify()
      NFSD: Clean up nfsd4_encode_offset_status()
      NFSD: Clean up nfsd4_encode_seek()


 fs/nfsd/nfs4proc.c |   4 +-
 fs/nfsd/nfs4xdr.c  | 419 ++++++++++++++++++++++++---------------------
 fs/nfsd/xdr4.h     |   4 +-
 3 files changed, 225 insertions(+), 202 deletions(-)

--
Chuck Lever


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

* [PATCH v1 1/8] NFSD: Clean up nfsd4_encode_access()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
@ 2023-10-09 18:29 ` Chuck Lever
  2023-10-09 18:29 ` [PATCH v1 2/8] NFSD: Clean up nfsd4_do_encode_secinfo() Chuck Lever
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:29 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Convert nfsd4_encode_access() to use modern XDR utility functions.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5efcd9691e5d..12a1254c5f54 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3904,14 +3904,14 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr,
 {
 	struct nfsd4_access *access = &u->access;
 	struct xdr_stream *xdr = resp->xdr;
-	__be32 *p;
+	__be32 status;
 
-	p = xdr_reserve_space(xdr, 8);
-	if (!p)
-		return nfserr_resource;
-	*p++ = cpu_to_be32(access->ac_supported);
-	*p++ = cpu_to_be32(access->ac_resp_access);
-	return 0;
+	/* supported */
+	status = nfsd4_encode_uint32_t(xdr, access->ac_supported);
+	if (status != nfs_ok)
+		return status;
+	/* access */
+	return nfsd4_encode_uint32_t(xdr, access->ac_resp_access);
 }
 
 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr,



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

* [PATCH v1 2/8] NFSD: Clean up nfsd4_do_encode_secinfo()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
  2023-10-09 18:29 ` [PATCH v1 1/8] NFSD: Clean up nfsd4_encode_access() Chuck Lever
@ 2023-10-09 18:29 ` Chuck Lever
  2023-10-09 18:29 ` [PATCH v1 3/8] NFSD: Clean up nfsd4_encode_exchange_id() Chuck Lever
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:29 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Refactor nfsd4_encode_secinfo() so it is more clear what XDR data
item is being encoded by which piece of code.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 12a1254c5f54..085f4bda5c58 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4551,14 +4551,35 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr,
 	return nfsd4_encode_change_info4(xdr, &rename->rn_tinfo);
 }
 
+static __be32
+nfsd4_encode_rpcsec_gss_info(struct xdr_stream *xdr,
+			     struct rpcsec_gss_info *info)
+{
+	__be32 status;
+
+	/* oid */
+	if (xdr_stream_encode_opaque(xdr, info->oid.data, info->oid.len) < 0)
+		return nfserr_resource;
+	/* qop */
+	status = nfsd4_encode_qop4(xdr, info->qop);
+	if (status != nfs_ok)
+		return status;
+	/* service */
+	if (xdr_stream_encode_u32(xdr, info->service) != XDR_UNIT)
+		return nfserr_resource;
+
+	return nfs_ok;
+}
+
 static __be32
 nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
 {
 	u32 i, nflavs, supported;
 	struct exp_flavor_info *flavs;
 	struct exp_flavor_info def_flavs[2];
-	__be32 *p, *flavorsp;
 	static bool report = true;
+	__be32 *flavorsp;
+	__be32 status;
 
 	if (exp->ex_nflavors) {
 		flavs = exp->ex_flavors;
@@ -4581,10 +4602,9 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
 	}
 
 	supported = 0;
-	p = xdr_reserve_space(xdr, 4);
-	if (!p)
+	flavorsp = xdr_reserve_space(xdr, XDR_UNIT);
+	if (!flavorsp)
 		return nfserr_resource;
-	flavorsp = p++;		/* to be backfilled later */
 
 	for (i = 0; i < nflavs; i++) {
 		rpc_authflavor_t pf = flavs[i].pseudoflavor;
@@ -4592,20 +4612,22 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
 
 		if (rpcauth_get_gssinfo(pf, &info) == 0) {
 			supported++;
-			p = xdr_reserve_space(xdr, 4 + 4 +
-					      XDR_LEN(info.oid.len) + 4 + 4);
-			if (!p)
-				return nfserr_resource;
-			*p++ = cpu_to_be32(RPC_AUTH_GSS);
-			p = xdr_encode_opaque(p,  info.oid.data, info.oid.len);
-			*p++ = cpu_to_be32(info.qop);
-			*p++ = cpu_to_be32(info.service);
+
+			/* flavor */
+			status = nfsd4_encode_uint32_t(xdr, RPC_AUTH_GSS);
+			if (status != nfs_ok)
+				return status;
+			/* flavor_info */
+			status = nfsd4_encode_rpcsec_gss_info(xdr, &info);
+			if (status != nfs_ok)
+				return status;
 		} else if (pf < RPC_AUTH_MAXFLAVOR) {
 			supported++;
-			p = xdr_reserve_space(xdr, 4);
-			if (!p)
-				return nfserr_resource;
-			*p++ = cpu_to_be32(pf);
+
+			/* flavor */
+			status = nfsd4_encode_uint32_t(xdr, pf);
+			if (status != nfs_ok)
+				return status;
 		} else {
 			if (report)
 				pr_warn("NFS: SECINFO: security flavor %u "
@@ -4615,7 +4637,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
 
 	if (nflavs != supported)
 		report = false;
-	*flavorsp = htonl(supported);
+	*flavorsp = cpu_to_be32(supported);
 	return 0;
 }
 
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 6f5c3f4b4ca3..947345d8490d 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -96,6 +96,7 @@ nfsd4_encode_uint32_t(struct xdr_stream *xdr, u32 val)
 #define nfsd4_encode_count4(x, v)	nfsd4_encode_uint32_t(x, v)
 #define nfsd4_encode_mode4(x, v)	nfsd4_encode_uint32_t(x, v)
 #define nfsd4_encode_nfs_lease4(x, v)	nfsd4_encode_uint32_t(x, v)
+#define nfsd4_encode_qop4(x, v)		nfsd4_encode_uint32_t(x, v)
 #define nfsd4_encode_sequenceid4(x, v)	nfsd4_encode_uint32_t(x, v)
 #define nfsd4_encode_slotid4(x, v)	nfsd4_encode_uint32_t(x, v)
 



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

* [PATCH v1 3/8] NFSD: Clean up nfsd4_encode_exchange_id()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
  2023-10-09 18:29 ` [PATCH v1 1/8] NFSD: Clean up nfsd4_encode_access() Chuck Lever
  2023-10-09 18:29 ` [PATCH v1 2/8] NFSD: Clean up nfsd4_do_encode_secinfo() Chuck Lever
@ 2023-10-09 18:29 ` Chuck Lever
  2023-10-09 18:30 ` [PATCH v1 4/8] NFSD: Clean up nfsd4_encode_test_stateid() Chuck Lever
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:29 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Restructure nfsd4_encode_exchange_id() so that it will be more
straightforward to add support for SSV one day. Also, adopt the use
of the conventional XDR utility functions.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 085f4bda5c58..85044cdcf2a7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4729,77 +4729,96 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr,
 }
 
 static __be32
-nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
-			 union nfsd4_op_u *u)
+nfsd4_encode_state_protect_ops4(struct xdr_stream *xdr,
+				struct nfsd4_exchange_id *exid)
 {
-	struct nfsd4_exchange_id *exid = &u->exchange_id;
-	struct xdr_stream *xdr = resp->xdr;
-	__be32 *p;
-	char *major_id;
-	char *server_scope;
-	int major_id_sz;
-	int server_scope_sz;
-	uint64_t minor_id = 0;
-	struct nfsd_net *nn = net_generic(SVC_NET(resp->rqstp), nfsd_net_id);
+	__be32 status;
 
-	major_id = nn->nfsd_name;
-	major_id_sz = strlen(nn->nfsd_name);
-	server_scope = nn->nfsd_name;
-	server_scope_sz = strlen(nn->nfsd_name);
+	/* spo_must_enforce */
+	status = nfsd4_encode_bitmap4(xdr, exid->spo_must_enforce[0],
+				      exid->spo_must_enforce[1],
+				      exid->spo_must_enforce[2]);
+	if (status != nfs_ok)
+		return status;
+	/* spo_must_allow */
+	return nfsd4_encode_bitmap4(xdr, exid->spo_must_allow[0],
+				    exid->spo_must_allow[1],
+				    exid->spo_must_allow[2]);
+}
 
-	if (nfsd4_encode_clientid4(xdr, &exid->clientid) != nfs_ok)
-		return nfserr_resource;
-	if (xdr_stream_encode_u32(xdr, exid->seqid) < 0)
-		return nfserr_resource;
-	if (xdr_stream_encode_u32(xdr, exid->flags) < 0)
-		return nfserr_resource;
+static __be32
+nfsd4_encode_state_protect4_r(struct xdr_stream *xdr, struct nfsd4_exchange_id *exid)
+{
+	__be32 status;
 
-	if (xdr_stream_encode_u32(xdr, exid->spa_how) < 0)
+	if (xdr_stream_encode_u32(xdr, exid->spa_how) != XDR_UNIT)
 		return nfserr_resource;
 	switch (exid->spa_how) {
 	case SP4_NONE:
+		status = nfs_ok;
 		break;
 	case SP4_MACH_CRED:
-		/* spo_must_enforce bitmap: */
-		nfserr = nfsd4_encode_bitmap4(xdr,
-					exid->spo_must_enforce[0],
-					exid->spo_must_enforce[1],
-					exid->spo_must_enforce[2]);
-		if (nfserr)
-			return nfserr;
-		/* spo_must_allow bitmap: */
-		nfserr = nfsd4_encode_bitmap4(xdr,
-					exid->spo_must_allow[0],
-					exid->spo_must_allow[1],
-					exid->spo_must_allow[2]);
-		if (nfserr)
-			return nfserr;
+		/* spr_mach_ops */
+		status = nfsd4_encode_state_protect_ops4(xdr, exid);
 		break;
 	default:
-		WARN_ON_ONCE(1);
+		status = nfserr_serverfault;
 	}
+	return status;
+}
 
-	p = xdr_reserve_space(xdr,
-		8 /* so_minor_id */ +
-		4 /* so_major_id.len */ +
-		(XDR_QUADLEN(major_id_sz) * 4) +
-		4 /* eir_server_scope.len */ +
-		(XDR_QUADLEN(server_scope_sz) * 4) +
-		4 /* eir_server_impl_id.count (0) */);
-	if (!p)
-		return nfserr_resource;
+static __be32
+nfsd4_encode_server_owner4(struct xdr_stream *xdr, struct svc_rqst *rqstp)
+{
+	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+	__be32 status;
 
-	/* The server_owner struct */
-	p = xdr_encode_hyper(p, minor_id);      /* Minor id */
-	/* major id */
-	p = xdr_encode_opaque(p, major_id, major_id_sz);
+	/* so_minor_id */
+	status = nfsd4_encode_uint64_t(xdr, 0);
+	if (status != nfs_ok)
+		return status;
+	/* so_major_id */
+	return nfsd4_encode_opaque(xdr, nn->nfsd_name, strlen(nn->nfsd_name));
+}
 
-	/* Server scope */
-	p = xdr_encode_opaque(p, server_scope, server_scope_sz);
+static __be32
+nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
+			 union nfsd4_op_u *u)
+{
+	struct nfsd_net *nn = net_generic(SVC_NET(resp->rqstp), nfsd_net_id);
+	struct nfsd4_exchange_id *exid = &u->exchange_id;
+	struct xdr_stream *xdr = resp->xdr;
 
-	/* Implementation id */
-	*p++ = cpu_to_be32(0);	/* zero length nfs_impl_id4 array */
-	return 0;
+	/* eir_clientid */
+	nfserr = nfsd4_encode_clientid4(xdr, &exid->clientid);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* eir_sequenceid */
+	nfserr = nfsd4_encode_sequenceid4(xdr, exid->seqid);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* eir_flags */
+	nfserr = nfsd4_encode_uint32_t(xdr, exid->flags);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* eir_state_protect */
+	nfserr = nfsd4_encode_state_protect4_r(xdr, exid);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* eir_server_owner */
+	nfserr = nfsd4_encode_server_owner4(xdr, resp->rqstp);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* eir_server_scope */
+	nfserr = nfsd4_encode_opaque(xdr, nn->nfsd_name,
+				     strlen(nn->nfsd_name));
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* eir_server_impl_id<1> */
+	if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
+		return nfserr_resource;
+
+	return nfs_ok;
 }
 
 static __be32



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

* [PATCH v1 4/8] NFSD: Clean up nfsd4_encode_test_stateid()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
                   ` (2 preceding siblings ...)
  2023-10-09 18:29 ` [PATCH v1 3/8] NFSD: Clean up nfsd4_encode_exchange_id() Chuck Lever
@ 2023-10-09 18:30 ` Chuck Lever
  2023-10-09 18:30 ` [PATCH v1 5/8] NFSD: Clean up nfsd4_encode_copy() Chuck Lever
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:30 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Use conventional XDR utilities.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 85044cdcf2a7..859ee70e076f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4928,20 +4928,18 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
 			  union nfsd4_op_u *u)
 {
 	struct nfsd4_test_stateid *test_stateid = &u->test_stateid;
-	struct xdr_stream *xdr = resp->xdr;
 	struct nfsd4_test_stateid_id *stateid, *next;
-	__be32 *p;
+	struct xdr_stream *xdr = resp->xdr;
 
-	p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
-	if (!p)
+	/* tsr_status_codes<> */
+	if (xdr_stream_encode_u32(xdr, test_stateid->ts_num_ids) != XDR_UNIT)
 		return nfserr_resource;
-	*p++ = htonl(test_stateid->ts_num_ids);
-
-	list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
-		*p++ = stateid->ts_id_status;
+	list_for_each_entry_safe(stateid, next,
+				 &test_stateid->ts_stateid_list, ts_id_list) {
+		if (xdr_stream_encode_be32(xdr, stateid->ts_id_status) != XDR_UNIT)
+			return nfserr_resource;
 	}
-
-	return 0;
+	return nfs_ok;
 }
 
 #ifdef CONFIG_NFSD_PNFS



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

* [PATCH v1 5/8] NFSD: Clean up nfsd4_encode_copy()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
                   ` (3 preceding siblings ...)
  2023-10-09 18:30 ` [PATCH v1 4/8] NFSD: Clean up nfsd4_encode_test_stateid() Chuck Lever
@ 2023-10-09 18:30 ` Chuck Lever
  2023-10-09 18:30 ` [PATCH v1 6/8] NFSD: Clean up nfsd4_encode_copy_notify() Chuck Lever
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:30 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Restructure this function using conventional XDR utility functions
and so it aligns better with the XDR in the specification.

I've also moved nfsd4_encode_copy() closer to the data type encoders
that only it uses.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 859ee70e076f..b9339a1452c8 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5075,32 +5075,56 @@ nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
 #endif /* CONFIG_NFSD_PNFS */
 
 static __be32
-nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
-		struct nfsd42_write_res *write, bool sync)
+nfsd4_encode_write_response4(struct xdr_stream *xdr,
+			     const struct nfsd4_copy *copy)
 {
-	__be32 *p;
-	p = xdr_reserve_space(resp->xdr, 4);
-	if (!p)
-		return nfserr_resource;
+	const struct nfsd42_write_res *write = &copy->cp_res;
+	u32 count = nfsd4_copy_is_sync(copy) ? 0 : 1;
+	__be32 status;
 
-	if (sync)
-		*p++ = cpu_to_be32(0);
-	else {
-		__be32 nfserr;
-		*p++ = cpu_to_be32(1);
-		nfserr = nfsd4_encode_stateid4(resp->xdr, &write->cb_stateid);
-		if (nfserr)
-			return nfserr;
+	/* wr_callback_id<1> */
+	if (xdr_stream_encode_u32(xdr, count) != XDR_UNIT)
+		return nfserr_resource;
+	if (count) {
+		status = nfsd4_encode_stateid4(xdr, &write->cb_stateid);
+		if (status != nfs_ok)
+			return status;
 	}
-	p = xdr_reserve_space(resp->xdr, 8 + 4 + NFS4_VERIFIER_SIZE);
-	if (!p)
+
+	/* wr_count */
+	status = nfsd4_encode_length4(xdr, write->wr_bytes_written);
+	if (status != nfs_ok)
+		return status;
+	/* wr_committed */
+	if (xdr_stream_encode_u32(xdr, write->wr_stable_how) != XDR_UNIT)
 		return nfserr_resource;
+	/* wr_writeverf */
+	return nfsd4_encode_verifier4(xdr, &write->wr_verifier);
+}
 
-	p = xdr_encode_hyper(p, write->wr_bytes_written);
-	*p++ = cpu_to_be32(write->wr_stable_how);
-	p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
-				    NFS4_VERIFIER_SIZE);
-	return nfs_ok;
+static __be32 nfsd4_encode_copy_requirements4(struct xdr_stream *xdr,
+					      const struct nfsd4_copy *copy)
+{
+	__be32 status;
+
+	/* cr_consecutive */
+	status = nfsd4_encode_bool(xdr, true);
+	if (status != nfs_ok)
+		return status;
+	/* cr_synchronous */
+	return nfsd4_encode_bool(xdr, nfsd4_copy_is_sync(copy));
+}
+
+static __be32
+nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
+		  union nfsd4_op_u *u)
+{
+	struct nfsd4_copy *copy = &u->copy;
+
+	nfserr = nfsd4_encode_write_response4(resp->xdr, copy);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	return nfsd4_encode_copy_requirements4(resp->xdr, copy);
 }
 
 static __be32
@@ -5143,24 +5167,6 @@ nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
 	return 0;
 }
 
-static __be32
-nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
-		  union nfsd4_op_u *u)
-{
-	struct nfsd4_copy *copy = &u->copy;
-	__be32 *p;
-
-	nfserr = nfsd42_encode_write_res(resp, &copy->cp_res,
-					 nfsd4_copy_is_sync(copy));
-	if (nfserr)
-		return nfserr;
-
-	p = xdr_reserve_space(resp->xdr, 4 + 4);
-	*p++ = xdr_one; /* cr_consecutive */
-	*p = nfsd4_copy_is_sync(copy) ? xdr_one : xdr_zero;
-	return 0;
-}
-
 static __be32
 nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
 			    union nfsd4_op_u *u)



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

* [PATCH v1 6/8] NFSD: Clean up nfsd4_encode_copy_notify()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
                   ` (4 preceding siblings ...)
  2023-10-09 18:30 ` [PATCH v1 5/8] NFSD: Clean up nfsd4_encode_copy() Chuck Lever
@ 2023-10-09 18:30 ` Chuck Lever
  2023-10-09 18:30 ` [PATCH v1 7/8] NFSD: Clean up nfsd4_encode_offset_status() Chuck Lever
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:30 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Replace open-coded encoding logic with the use of conventional XDR
utility functions.

Note that if we replace the cpn_sec and cpn_nsec fields with a
single struct timespec64 field, the encoder can use
nfsd4_encode_nfstime4(), as that is the data type specified by the
XDR spec.

NFS4ERR_INVAL seems inappropriate if the encoder doesn't support
encoding the response. Instead use NFS4ERR_SERVERFAULT, since this
condition is a software bug on the server.

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

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 60262fd27b15..0bb046ebc6c5 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1939,8 +1939,8 @@ nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	if (status)
 		return status;
 
-	cn->cpn_sec = nn->nfsd4_lease;
-	cn->cpn_nsec = 0;
+	cn->cpn_lease_time.tv_sec = nn->nfsd4_lease;
+	cn->cpn_lease_time.tv_nsec = 0;
 
 	status = nfserrno(-ENOMEM);
 	cps = nfs4_alloc_init_cpntf_state(nn, stid);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b9339a1452c8..fdb7dafa7f27 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2575,6 +2575,19 @@ nfsd4_encode_change_info4(struct xdr_stream *xdr, const struct nfsd4_change_info
 	return nfsd4_encode_changeid4(xdr, c->after_change);
 }
 
+static __be32 nfsd4_encode_netaddr4(struct xdr_stream *xdr,
+				    const struct nfs42_netaddr *addr)
+{
+	__be32 status;
+
+	/* na_r_netid */
+	status = nfsd4_encode_opaque(xdr, addr->netid, addr->netid_len);
+	if (status != nfs_ok)
+		return status;
+	/* na_r_addr */
+	return nfsd4_encode_opaque(xdr, addr->addr, addr->addr_len);
+}
+
 /* Encode as an array of strings the string given with components
  * separated @sep, escaped with esc_enter and esc_exit.
  */
@@ -5128,43 +5141,42 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
 }
 
 static __be32
-nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
+nfsd4_encode_netloc4(struct xdr_stream *xdr, const struct nl4_server *ns)
 {
-	struct xdr_stream *xdr = resp->xdr;
-	struct nfs42_netaddr *addr;
-	__be32 *p;
-
-	p = xdr_reserve_space(xdr, 4);
-	*p++ = cpu_to_be32(ns->nl4_type);
+	__be32 status;
 
+	if (xdr_stream_encode_u32(xdr, ns->nl4_type) != XDR_UNIT)
+		return nfserr_resource;
 	switch (ns->nl4_type) {
 	case NL4_NETADDR:
-		addr = &ns->u.nl4_addr;
-
-		/* netid_len, netid, uaddr_len, uaddr (port included
-		 * in RPCBIND_MAXUADDRLEN)
-		 */
-		p = xdr_reserve_space(xdr,
-			4 /* netid len */ +
-			(XDR_QUADLEN(addr->netid_len) * 4) +
-			4 /* uaddr len */ +
-			(XDR_QUADLEN(addr->addr_len) * 4));
-		if (!p)
-			return nfserr_resource;
-
-		*p++ = cpu_to_be32(addr->netid_len);
-		p = xdr_encode_opaque_fixed(p, addr->netid,
-					    addr->netid_len);
-		*p++ = cpu_to_be32(addr->addr_len);
-		p = xdr_encode_opaque_fixed(p, addr->addr,
-					addr->addr_len);
+		/* nl_addr */
+		status = nfsd4_encode_netaddr4(xdr, &ns->u.nl4_addr);
 		break;
 	default:
-		WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
-		return nfserr_inval;
+		status = nfserr_serverfault;
 	}
+	return status;
+}
 
-	return 0;
+static __be32
+nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
+			 union nfsd4_op_u *u)
+{
+	struct nfsd4_copy_notify *cn = &u->copy_notify;
+	struct xdr_stream *xdr = resp->xdr;
+
+	/* cnr_lease_time */
+	nfserr = nfsd4_encode_nfstime4(xdr, &cn->cpn_lease_time);
+	if (nfserr)
+		return nfserr;
+	/* cnr_stateid */
+	nfserr = nfsd4_encode_stateid4(xdr, &cn->cpn_cnr_stateid);
+	if (nfserr)
+		return nfserr;
+	/* cnr_source_server<> */
+	if (xdr_stream_encode_u32(xdr, 1) != XDR_UNIT)
+		return nfserr_resource;
+	return nfsd4_encode_netloc4(xdr, cn->cpn_src);
 }
 
 static __be32
@@ -5257,42 +5269,6 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
 	return nfserr;
 }
 
-static __be32
-nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
-			 union nfsd4_op_u *u)
-{
-	struct nfsd4_copy_notify *cn = &u->copy_notify;
-	struct xdr_stream *xdr = resp->xdr;
-	__be32 *p;
-
-	if (nfserr)
-		return nfserr;
-
-	/* 8 sec, 4 nsec */
-	p = xdr_reserve_space(xdr, 12);
-	if (!p)
-		return nfserr_resource;
-
-	/* cnr_lease_time */
-	p = xdr_encode_hyper(p, cn->cpn_sec);
-	*p++ = cpu_to_be32(cn->cpn_nsec);
-
-	/* cnr_stateid */
-	nfserr = nfsd4_encode_stateid4(xdr, &cn->cpn_cnr_stateid);
-	if (nfserr)
-		return nfserr;
-
-	/* cnr_src.nl_nsvr */
-	p = xdr_reserve_space(xdr, 4);
-	if (!p)
-		return nfserr_resource;
-
-	*p++ = cpu_to_be32(1);
-
-	nfserr = nfsd42_encode_nl4_server(resp, cn->cpn_src);
-	return nfserr;
-}
-
 static __be32
 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
 		  union nfsd4_op_u *u)
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 947345d8490d..3147b92c7216 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -754,8 +754,7 @@ struct nfsd4_copy_notify {
 
 	/* response */
 	stateid_t		cpn_cnr_stateid;
-	u64			cpn_sec;
-	u32			cpn_nsec;
+	struct timespec64	cpn_lease_time;
 	struct nl4_server	*cpn_src;
 };
 



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

* [PATCH v1 7/8] NFSD: Clean up nfsd4_encode_offset_status()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
                   ` (5 preceding siblings ...)
  2023-10-09 18:30 ` [PATCH v1 6/8] NFSD: Clean up nfsd4_encode_copy_notify() Chuck Lever
@ 2023-10-09 18:30 ` Chuck Lever
  2023-10-09 18:30 ` [PATCH v1 8/8] NFSD: Clean up nfsd4_encode_seek() Chuck Lever
  2023-10-10 15:22 ` [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Jeff Layton
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:30 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Use modern XDR encoder utilities.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index fdb7dafa7f27..c87e7c5de592 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5185,14 +5185,15 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
 {
 	struct nfsd4_offload_status *os = &u->offload_status;
 	struct xdr_stream *xdr = resp->xdr;
-	__be32 *p;
 
-	p = xdr_reserve_space(xdr, 8 + 4);
-	if (!p)
+	/* osr_count */
+	nfserr = nfsd4_encode_length4(xdr, os->count);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* osr_complete<1> */
+	if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
 		return nfserr_resource;
-	p = xdr_encode_hyper(p, os->count);
-	*p++ = cpu_to_be32(0);
-	return nfserr;
+	return nfs_ok;
 }
 
 static __be32



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

* [PATCH v1 8/8] NFSD: Clean up nfsd4_encode_seek()
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
                   ` (6 preceding siblings ...)
  2023-10-09 18:30 ` [PATCH v1 7/8] NFSD: Clean up nfsd4_encode_offset_status() Chuck Lever
@ 2023-10-09 18:30 ` Chuck Lever
  2023-10-10 15:22 ` [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Jeff Layton
  8 siblings, 0 replies; 10+ messages in thread
From: Chuck Lever @ 2023-10-09 18:30 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Use modern XDR encoder utilities.

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

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c87e7c5de592..1961223d2642 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5275,13 +5275,14 @@ nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
 		  union nfsd4_op_u *u)
 {
 	struct nfsd4_seek *seek = &u->seek;
-	__be32 *p;
-
-	p = xdr_reserve_space(resp->xdr, 4 + 8);
-	*p++ = cpu_to_be32(seek->seek_eof);
-	p = xdr_encode_hyper(p, seek->seek_pos);
+	struct xdr_stream *xdr = resp->xdr;
 
-	return 0;
+	/* sr_eof */
+	nfserr = nfsd4_encode_bool(xdr, seek->seek_eof);
+	if (nfserr != nfs_ok)
+		return nfserr;
+	/* sr_offset */
+	return nfsd4_encode_offset4(xdr, seek->seek_pos);
 }
 
 static __be32



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

* Re: [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders
  2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
                   ` (7 preceding siblings ...)
  2023-10-09 18:30 ` [PATCH v1 8/8] NFSD: Clean up nfsd4_encode_seek() Chuck Lever
@ 2023-10-10 15:22 ` Jeff Layton
  8 siblings, 0 replies; 10+ messages in thread
From: Jeff Layton @ 2023-10-10 15:22 UTC (permalink / raw)
  To: Chuck Lever, linux-nfs; +Cc: Chuck Lever

On Mon, 2023-10-09 at 14:29 -0400, Chuck Lever wrote:
> Tidy up the server-side XDR result encoders for remaining
> miscellanous NFSv4 operations. Series applies to nfsd-next. See
> topic branch "nfsd4-encoder-overhaul" in this repo:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
> 
> ---
> 
> Chuck Lever (8):
>       NFSD: Clean up nfsd4_encode_access()
>       NFSD: Clean up nfsd4_do_encode_secinfo()
>       NFSD: Clean up nfsd4_encode_exchange_id()
>       NFSD: Clean up nfsd4_encode_test_stateid()
>       NFSD: Clean up nfsd4_encode_copy()
>       NFSD: Clean up nfsd4_encode_copy_notify()
>       NFSD: Clean up nfsd4_encode_offset_status()
>       NFSD: Clean up nfsd4_encode_seek()
> 
> 
>  fs/nfsd/nfs4proc.c |   4 +-
>  fs/nfsd/nfs4xdr.c  | 419 ++++++++++++++++++++++++---------------------
>  fs/nfsd/xdr4.h     |   4 +-
>  3 files changed, 225 insertions(+), 202 deletions(-)
> 
> --
> Chuck Lever
> 

Reviewed-by: Jeff Layton <jlayton@kernel.org>

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

end of thread, other threads:[~2023-10-10 15:22 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-09 18:29 [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Chuck Lever
2023-10-09 18:29 ` [PATCH v1 1/8] NFSD: Clean up nfsd4_encode_access() Chuck Lever
2023-10-09 18:29 ` [PATCH v1 2/8] NFSD: Clean up nfsd4_do_encode_secinfo() Chuck Lever
2023-10-09 18:29 ` [PATCH v1 3/8] NFSD: Clean up nfsd4_encode_exchange_id() Chuck Lever
2023-10-09 18:30 ` [PATCH v1 4/8] NFSD: Clean up nfsd4_encode_test_stateid() Chuck Lever
2023-10-09 18:30 ` [PATCH v1 5/8] NFSD: Clean up nfsd4_encode_copy() Chuck Lever
2023-10-09 18:30 ` [PATCH v1 6/8] NFSD: Clean up nfsd4_encode_copy_notify() Chuck Lever
2023-10-09 18:30 ` [PATCH v1 7/8] NFSD: Clean up nfsd4_encode_offset_status() Chuck Lever
2023-10-09 18:30 ` [PATCH v1 8/8] NFSD: Clean up nfsd4_encode_seek() Chuck Lever
2023-10-10 15:22 ` [PATCH v1 0/8] Clean up miscellaneous NFSv4 XDR encoders Jeff Layton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox