All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neil@brown.name>, Jeff Layton <jlayton@kernel.org>,
	Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>
Subject: [PATCH v1 16/17] NFSD: Use xdrgen XDR functions for the NFS-ACL v2 ACCESS procedure
Date: Thu, 22 Oct 2026 09:53:40 -0400	[thread overview]
Message-ID: <20261022135341.14265-17-cel@kernel.org> (raw)
In-Reply-To: <20261022135341.14265-1-cel@kernel.org>

Convert the NFS-ACL version 2 ACCESS procedure to xdrgen. As with
the GETATTR conversion, neither direction needs a hand-written XDR
tail: ACCESS2args carries a file handle and an access bitmask, so
the generated nfs_acl_svc_decode_ACCESS2args decodes the argument
in full, and ACCESS2res carries a status word and, on success, the
file attributes and the granted access bits, so the generated
nfs_acl_svc_encode_ACCESS2res emits the entire reply. On an error
status the encoder emits only the status word, matching what the
hand-written encoder produced. Wrapper structures bridge the
generated ACCESS2args and ACCESS2res types and the legacy svc_fh
and scratch kstat that the NFSD VFS layer still uses.

The procedure's pc_argzero is zero because the generated decoder
writes the whole ACCESS2args, making the earlier defensive memset
of the argument buffer unnecessary.

Because nfsacld_proc_access() now fills in the reply attributes and
releases the file handle itself, the fh_getattr() call moves into
the proc function and the separate ->pc_release callback is dropped.
This makes it straightforward to confirm the handle is released on
every flow.

ACCESS was the only remaining user of the file-local struct
nfsd3_accessargs and struct nfsd3_accessres, so this removes those
definitions, the hand-written accessargs decoder and accessres
encoder, and the ST and AT size macros that only the ACCESS entry
still referenced. The svcxdr_decode_fhandle, svcxdr_encode_stat,
and svcxdr_encode_fattr declarations lose their last callers here
and are removed as well.

While rewriting the procedure entry, correct its pc_name from the
stale "SETATTR" to "ACCESS".

Signed-off-by: Chuck Lever <cel@kernel.org>
---
 fs/nfsd/nfs2acl.c | 132 ++++++++++++++++------------------------------
 1 file changed, 45 insertions(+), 87 deletions(-)

diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index d4261ef076bd..a805d2ac76db 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -95,22 +95,19 @@ struct GETATTR2res_wrapper {
 
 static_assert(offsetof(struct GETATTR2res_wrapper, xdrgen) == 0);
 
-struct nfsd3_accessargs {
+struct ACCESS2args_wrapper {
+	struct ACCESS2args	xdrgen;
 	struct svc_fh		fh;
-	__u32			access;
 };
 
-struct nfsd3_accessres {
-	__be32			status;
-	struct svc_fh		fh;
-	__u32			access;
+static_assert(offsetof(struct ACCESS2args_wrapper, xdrgen) == 0);
+
+struct ACCESS2res_wrapper {
+	struct ACCESS2res	xdrgen;
 	struct kstat		stat;
 };
 
-bool svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp);
-bool svcxdr_encode_stat(struct xdr_stream *xdr, __be32 status);
-bool svcxdr_encode_fattr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
-			 const struct svc_fh *fhp, const struct kstat *stat);
+static_assert(offsetof(struct ACCESS2res_wrapper, xdrgen) == 0);
 
 /*
  * These maps are identical to the NFSv3 maps (nfs3proc.c). This enables
@@ -514,28 +511,41 @@ static __be32 nfsacld_proc_getattr(struct svc_rqst *rqstp)
 	return rpc_success;
 }
 
-/*
- * Check file access
+/**
+ * nfsacld_proc_access - ACCESS: Check access permission
+ * @rqstp: RPC transaction context
+ *
+ * Return:
+ *   %rpc_success:		RPC executed successfully
+ *
+ * RPC synopsis:
+ *   ACCESS2res ACLPROC2_ACCESS(ACCESS2args) = 4;
  */
 static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
 {
-	struct nfsd3_accessargs *argp = rqstp->rq_argp;
-	struct nfsd3_accessres *resp = rqstp->rq_resp;
+	struct ACCESS2args_wrapper *argp = rqstp->rq_argp;
+	struct ACCESS2res_wrapper *resp = rqstp->rq_resp;
+	struct svc_fh *fhp = &argp->fh;
 
+	nfsacld_fhandle_to_svc_fh(fhp, &argp->xdrgen.fh);
 	dprintk("nfsd: ACCESS(2acl)   %s 0x%x\n",
-			SVCFH_fmt(&argp->fh),
-			argp->access);
+			SVCFH_fmt(fhp), argp->xdrgen.access);
 
-	fh_copy(&resp->fh, &argp->fh);
-	resp->access = argp->access;
-
-	resp->status = nfsd_access(rqstp, &resp->fh, &nfsd2_access_maps,
-				   &resp->access, NULL);
-	if (resp->status != acl2_ok)
+	resp->xdrgen.status = nfsd_access(rqstp, fhp, &nfsd2_access_maps,
+					  &argp->xdrgen.access, NULL);
+	if (resp->xdrgen.status != acl2_ok)
 		goto out;
-	resp->status = fh_getattr(&resp->fh, &resp->stat);
+	resp->xdrgen.status = fh_getattr(fhp, &resp->stat);
+
 out:
-	resp->status = nfsacld_map_status(resp->status);
+	if (resp->xdrgen.status == acl2_ok) {
+		struct ACCESS2resok *resok = &resp->xdrgen.u.resok;
+
+		resok->access = argp->xdrgen.access;
+		nfsacld_stat_to_fattr(rqstp, &resok->attr, &resp->stat, fhp);
+	}
+	fh_put(fhp);
+	resp->xdrgen.status = nfsacld_map_status(resp->xdrgen.status);
 	return rpc_success;
 }
 
@@ -733,47 +743,6 @@ bool nfs_acl2_secattr_decode_end(struct xdrgen_aggregate_cursor *c, bool ok)
 	return posix_acl_from_nfsacl(acl) == 0;
 }
 
-/*
- * XDR decode functions
- */
-
-static bool
-nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
-{
-	struct nfsd3_accessargs *args = rqstp->rq_argp;
-
-	if (!svcxdr_decode_fhandle(xdr, &args->fh))
-		return false;
-	if (xdr_stream_decode_u32(xdr, &args->access) < 0)
-		return false;
-
-	return true;
-}
-
-/*
- * XDR encode functions
- */
-
-/* ACCESS */
-static bool
-nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
-{
-	struct nfsd3_accessres *resp = rqstp->rq_resp;
-
-	if (!svcxdr_encode_stat(xdr, resp->status))
-		return false;
-	switch (resp->status) {
-	case acl2_ok:
-		if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
-			return false;
-		if (xdr_stream_encode_u32(xdr, resp->access) < 0)
-			return false;
-		break;
-	}
-
-	return true;
-}
-
 /*
  * XDR release functions
  */
@@ -785,13 +754,6 @@ static void nfsaclsvc_release_getacl(struct svc_rqst *rqstp)
 	posix_acl_release(resp->acl_default);
 }
 
-static void nfsaclsvc_release_access(struct svc_rqst *rqstp)
-{
-	struct nfsd3_accessres *resp = rqstp->rq_resp;
-
-	fh_put(&resp->fh);
-}
-
 static void nfsaclsvc_release_setacl(struct svc_rqst *rqstp)
 {
 	struct SETACL2args_wrapper *argp = rqstp->rq_argp;
@@ -800,9 +762,6 @@ static void nfsaclsvc_release_setacl(struct svc_rqst *rqstp)
 	posix_acl_release(argp->acl_default);
 }
 
-#define ST 1		/* status*/
-#define AT 21		/* attributes */
-
 static const struct svc_procedure nfsd_acl_procedures2[5] = {
 	[ACLPROC2_NULL] = {
 		.pc_func	= nfsacld_proc_null,
@@ -851,16 +810,15 @@ static const struct svc_procedure nfsd_acl_procedures2[5] = {
 		.pc_name	= "GETATTR",
 	},
 	[ACLPROC2_ACCESS] = {
-		.pc_func = nfsacld_proc_access,
-		.pc_decode = nfsaclsvc_decode_accessargs,
-		.pc_encode = nfsaclsvc_encode_accessres,
-		.pc_release = nfsaclsvc_release_access,
-		.pc_argsize = sizeof(struct nfsd3_accessargs),
-		.pc_argzero = sizeof(struct nfsd3_accessargs),
-		.pc_ressize = sizeof(struct nfsd3_accessres),
-		.pc_cachetype = RC_NOCACHE,
-		.pc_xdrressize = ST+AT+1,
-		.pc_name = "SETATTR",
+		.pc_func	= nfsacld_proc_access,
+		.pc_decode	= nfs_acl_svc_decode_ACCESS2args,
+		.pc_encode	= nfs_acl_svc_encode_ACCESS2res,
+		.pc_argsize	= sizeof(struct ACCESS2args_wrapper),
+		.pc_argzero	= 0,
+		.pc_ressize	= sizeof(struct ACCESS2res_wrapper),
+		.pc_cachetype	= RC_NOCACHE,
+		.pc_xdrressize	= NFS_ACL2_ACCESS2res_sz,
+		.pc_name	= "ACCESS",
 	},
 };
 
@@ -871,11 +829,11 @@ union nfsd_acl2_xdrstore {
 	struct GETACL2args_wrapper	getaclargs;
 	struct SETACL2args_wrapper	setaclargs;
 	struct GETATTR2args_wrapper	getattrargs;
-	struct nfsd3_accessargs		accessargs;
+	struct ACCESS2args_wrapper	accessargs;
 	struct GETACL2res_wrapper	getaclres;
 	struct SETACL2res_wrapper	setaclres;
 	struct GETATTR2res_wrapper	getattrres;
-	struct nfsd3_accessres		accessres;
+	struct ACCESS2res_wrapper	accessres;
 };
 
 const struct svc_version nfsd_acl_version2 = {
-- 
2.56.0


  parent reply	other threads:[~2026-10-22 13:53 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-22 13:53 [PATCH v1 00/17] Convert server-side NFS_ACLv2 XDR to use xdrgen Chuck Lever
2026-10-22 13:53 ` [PATCH v1 01/17] xdrgen: Reject out-of-range unsigned short values on decode Chuck Lever
2026-10-22 13:53 ` [PATCH v1 02/17] xdrgen: Reject out-of-range " Chuck Lever
2026-10-22 13:53 ` [PATCH v1 03/17] nfs_common: Export posix_acl_from_nfsacl for server ACL codecs Chuck Lever
2026-10-22 13:53 ` [PATCH v1 04/17] NFSD: Remove the unused NFSACL_MAXWORDS macro Chuck Lever
2026-10-22 13:53 ` [PATCH v1 05/17] NFSD: Move the definition of NFS_ACL_MAX_ENTRIES Chuck Lever
2026-10-22 13:53 ` [PATCH v1 06/17] Documentation: Add the RPC language description of NFS_ACLv2 Chuck Lever
2026-10-22 13:53 ` [PATCH v1 07/17] NFSD: Add infrastructure for generating NFS_ACLv2 XDR encoders and decoders Chuck Lever
2026-10-22 13:53 ` [PATCH v1 08/17] NFSD: Remove '#include "xdr3.h"' from nfs2acl.c Chuck Lever
2026-10-22 13:53 ` [PATCH v1 09/17] NFSD: Remove '#include "xdr.h"' " Chuck Lever
2026-10-22 13:53 ` [PATCH v1 10/17] NFSD: Switch to using the NFS_ACLv2 status codes Chuck Lever
2026-10-22 13:53 ` [PATCH v1 11/17] NFSD: Use xdrgen XDR functions for the NFS-ACL v2 NULL procedure Chuck Lever
2026-10-22 13:53 ` [PATCH v1 12/17] NFSD: Implement NFS-ACL v2 ACL encoding and decoding with xdrgen Chuck Lever
2026-10-22 13:53 ` [PATCH v1 13/17] NFSD: Use xdrgen XDR functions for the NFS-ACL v2 GETACL procedure Chuck Lever
2026-10-22 13:53 ` [PATCH v1 14/17] NFSD: Use xdrgen XDR functions for the NFS-ACL v2 SETACL procedure Chuck Lever
2026-10-22 13:53 ` [PATCH v1 15/17] NFSD: Use xdrgen XDR functions for the NFS-ACL v2 GETATTR procedure Chuck Lever
2026-10-22 13:53 ` Chuck Lever [this message]
2026-10-22 13:53 ` [PATCH v1 17/17] NFSD: Map every NFS_ACLv2 reply status into aclstat2 Chuck Lever

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261022135341.14265-17-cel@kernel.org \
    --to=cel@kernel.org \
    --cc=dai.ngo@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.