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