From: Mike Snitzer <snitzer@kernel.org>
To: Chuck Lever <chuck.lever@oracle.com>,
Jeff Layton <jlayton@kernel.org>,
Trond Myklebust <trond.myklebust@hammerspace.com>,
Anna Schumaker <anna.schumaker@oracle.com>
Cc: linux-nfs@vger.kernel.org
Subject: [RFC PATCH 09/11] NFSv4: add reexport support for SETACL nfs4_acl passthru
Date: Thu, 19 Feb 2026 17:13:50 -0500 [thread overview]
Message-ID: <20260219221352.40554-10-snitzer@kernel.org> (raw)
In-Reply-To: <20260219221352.40554-1-snitzer@kernel.org>
From: Mike Snitzer <snitzer@hammerspace.com>
Wire up the export_operations .setacl hook and use the upper layer
provided nfs4_acl's pages in the call to NFSPROC4_CLNT_SETACL.
Signed-off-by: Mike Snitzer <snitzer@hammerspace.com>
---
fs/nfs/export.c | 10 ++++++++++
fs/nfs/nfs4proc.c | 33 +++++++++++++++++++++++++++------
fs/nfs/nfs4xdr.c | 2 +-
include/linux/nfs_xdr.h | 3 +++
4 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/export.c b/fs/nfs/export.c
index a10dd5f9d078..9a90eee3e433 100644
--- a/fs/nfs/export.c
+++ b/fs/nfs/export.c
@@ -152,10 +152,20 @@ nfs_get_parent(struct dentry *dentry)
return parent;
}
+static int nfs_set_nfs4_acl(struct inode *inode, struct nfs4_acl *acl)
+{
+ const struct nfs_rpc_ops *rpc_ops = NFS_SERVER(inode)->nfs_client->rpc_ops;
+
+ if (rpc_ops->set_nfs4_acl == NULL)
+ return -EOPNOTSUPP;
+ return rpc_ops->set_nfs4_acl(inode, acl);
+}
+
const struct export_operations nfs_export_ops = {
.encode_fh = nfs_encode_fh,
.fh_to_dentry = nfs_fh_to_dentry,
.get_parent = nfs_get_parent,
+ .setacl = nfs_set_nfs4_acl,
.flags = EXPORT_OP_NOWCC |
EXPORT_OP_NOSUBTREECHK |
EXPORT_OP_CLOSE_BEFORE_UNLINK |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f3116145b354..f97ef2d41e35 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6219,7 +6219,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen,
}
static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
- size_t buflen, enum nfs4_acl_type type)
+ size_t buflen, enum nfs4_acl_type type,
+ struct nfs4_acl *acl)
{
struct nfs_server *server = NFS_SERVER(inode);
struct page *pages[NFS4ACL_MAXPAGES];
@@ -6227,6 +6228,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
.fh = NFS_FH(inode),
.acl_type = type,
.acl_len = buflen,
+ .acl_pgbase = 0,
.acl_pages = pages,
};
struct nfs_setaclres res;
@@ -6238,6 +6240,15 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
int ret, i;
+ if (acl != NULL) {
+ arg.acl_len = acl->len;
+ arg.acl_pgbase = acl->pgbase;
+ arg.acl_pages = acl->pages;
+ nfs4_inode_make_writeable(inode);
+ ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
+ goto out;
+ }
+
/* You can't remove system.nfs4_acl: */
if (buflen == 0)
return -EINVAL;
@@ -6262,6 +6273,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
* Acl update can result in inode attribute update.
* so mark the attribute cache invalid.
*/
+out:
spin_lock(&inode->i_lock);
nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE |
NFS_INO_INVALID_CTIME |
@@ -6273,7 +6285,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf,
}
static int nfs4_proc_set_acl(struct inode *inode, const void *buf,
- size_t buflen, enum nfs4_acl_type type)
+ size_t buflen, enum nfs4_acl_type type,
+ struct nfs4_acl *acl)
{
struct nfs4_exception exception = { };
int err;
@@ -6281,7 +6294,7 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf,
if (unlikely(NFS_FH(inode)->size == 0))
return -ENODATA;
do {
- err = __nfs4_proc_set_acl(inode, buf, buflen, type);
+ err = __nfs4_proc_set_acl(inode, buf, buflen, type, acl);
trace_nfs4_set_acl(inode, err);
if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) {
/*
@@ -6297,6 +6310,13 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf,
return err;
}
+static int nfs4_set_nfs4_acl(struct inode *inode, struct nfs4_acl *acl)
+{
+ if (!nfs4_server_supports_acls(NFS_SERVER(inode), acl->type))
+ return -EOPNOTSUPP;
+ return nfs4_proc_set_acl(inode, NULL, 0, acl->type, acl);
+}
+
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
static int _nfs4_get_security_label(struct inode *inode, void *buf,
size_t buflen)
@@ -7950,7 +7970,7 @@ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
const char *key, const void *buf,
size_t buflen, int flags)
{
- return nfs4_proc_set_acl(inode, buf, buflen, NFS4ACL_ACL);
+ return nfs4_proc_set_acl(inode, buf, buflen, NFS4ACL_ACL, NULL);
}
static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
@@ -7974,7 +7994,7 @@ static int nfs4_xattr_set_nfs4_dacl(const struct xattr_handler *handler,
const char *key, const void *buf,
size_t buflen, int flags)
{
- return nfs4_proc_set_acl(inode, buf, buflen, NFS4ACL_DACL);
+ return nfs4_proc_set_acl(inode, buf, buflen, NFS4ACL_DACL, NULL);
}
static int nfs4_xattr_get_nfs4_dacl(const struct xattr_handler *handler,
@@ -7997,7 +8017,7 @@ static int nfs4_xattr_set_nfs4_sacl(const struct xattr_handler *handler,
const char *key, const void *buf,
size_t buflen, int flags)
{
- return nfs4_proc_set_acl(inode, buf, buflen, NFS4ACL_SACL);
+ return nfs4_proc_set_acl(inode, buf, buflen, NFS4ACL_SACL, NULL);
}
static int nfs4_xattr_get_nfs4_sacl(const struct xattr_handler *handler,
@@ -11020,6 +11040,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
.discover_trunking = nfs4_discover_trunking,
.enable_swap = nfs4_enable_swap,
.disable_swap = nfs4_disable_swap,
+ .set_nfs4_acl = nfs4_set_nfs4_acl,
};
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1d0e6c10f921..228dbb2a8af5 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1717,7 +1717,7 @@ static void encode_setacl(struct xdr_stream *xdr,
encode_nfs4_stateid(xdr, &zero_stateid);
xdr_encode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
encode_uint32(xdr, arg->acl_len);
- xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len);
+ xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
}
static void
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 65dbe7c05346..47cb3b140640 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -832,6 +832,7 @@ struct nfs_setaclargs {
struct nfs_fh * fh;
enum nfs4_acl_type acl_type;
size_t acl_len;
+ unsigned int acl_pgbase;
struct page ** acl_pages;
};
@@ -1759,6 +1760,7 @@ struct nfs_mount_info;
struct nfs_client_initdata;
struct nfs_pageio_descriptor;
struct fs_context;
+struct nfs4_acl;
/*
* RPC procedure vector for NFSv2/NFSv3 demuxing
@@ -1845,6 +1847,7 @@ struct nfs_rpc_ops {
int (*discover_trunking)(struct nfs_server *, struct nfs_fh *);
void (*enable_swap)(struct inode *inode);
void (*disable_swap)(struct inode *inode);
+ int (*set_nfs4_acl)(struct inode *, struct nfs4_acl *);
};
/*
--
2.44.0
next prev parent reply other threads:[~2026-02-19 22:14 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-19 22:13 [RFC PATCH 00/11] NFS/NFSD: nfs4_acl passthru for NFSv4 reexport Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 01/11] exportfs: add ability to advertise NFSv4 ACL passthru support Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 02/11] NFSD: factor out nfsd_supports_nfs4_acl() to nfsd/acl.h Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 03/11] NFS/NFSD: data structure enablement for nfs4_acl passthru support Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 04/11] NFSD: prepare to support SETACL nfs4_acl passthru Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 05/11] NFSD: add NFS4 reexport support for " Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 06/11] NFSD: add NFS4 reexport support for GETACL " Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 07/11] NFSD: add NFS4ACL_DACL and NFS4ACL_SACL passthru support Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 08/11] NFSD: avoid extra nfs4_acl passthru work unless needed Mike Snitzer
2026-02-19 22:13 ` Mike Snitzer [this message]
2026-02-19 22:13 ` [RFC PATCH 10/11] NFSv4: add reexport support for GETACL nfs4_acl passthru Mike Snitzer
2026-02-19 22:13 ` [RFC PATCH 11/11] NFSv4: set EXPORT_OP_NFSV4_ACL_PASSTHRU flag Mike Snitzer
2026-02-19 22:21 ` [RFC PATCH 00/11] NFS/NFSD: nfs4_acl passthru for NFSv4 reexport Chuck Lever
2026-02-19 23:07 ` Mike Snitzer
2026-02-20 15:46 ` Chuck Lever
2026-02-19 23:57 ` Trond Myklebust
2026-02-20 15:33 ` Chuck Lever
2026-02-22 17:53 ` Chuck Lever
2026-02-22 19:39 ` Mike Snitzer
2026-02-22 20:31 ` 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=20260219221352.40554-10-snitzer@kernel.org \
--to=snitzer@kernel.org \
--cc=anna.schumaker@oracle.com \
--cc=chuck.lever@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@hammerspace.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox