From: Jeff Layton <jlayton@kernel.org>
To: Chuck Lever <cel@kernel.org>, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
Jeff Layton <jlayton@kernel.org>
Subject: [PATCH 1/2] nfsd: pass caller-provided attrmask storage into nfsd4_setup_notify_entry4()
Date: Wed, 12 Aug 2026 14:08:14 -0400 [thread overview]
Message-ID: <20260812-dir-deleg-v1-1-411faa713068@kernel.org> (raw)
In-Reply-To: <20260812-dir-deleg-v1-0-411faa713068@kernel.org>
nfsd4_setup_notify_entry4() stole 3 words from the xdr stream via
xdr_reserve_space() to hold the host-order bmval[3] attrmask that
nfsd4_encode_attr_vals() consumes and ne_attrs.attrmask.element points
at. Stashing host-endian scratch in an XDR stream buffer is fragile:
the buffer layout is not guaranteed by sunrpc, and it blocks moving the
encoder to pages or xdrgen.
The attrmask only needs to live until the enclosing encode call
serializes the notify_entry4, so hand it caller-provided stack storage
instead. The two callers keep the words on the stack: up to three
concurrent entries for a rename in nfsd4_encode_notify_event(), one in
nfsd4_encode_dir_attr_change().
No wire change: the reserved words were never emitted; attr_vals.data/len
are still captured relative to xdr->p.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/nfsd/nfs4xdr.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index a47eb544b99f..7d1b2d6f57f2 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4378,21 +4378,16 @@ setup_notify_fhandle(struct dentry *dentry, struct nfs4_delegation *dp,
static bool
nfsd4_setup_notify_entry4(struct notify_entry4 *ne, struct xdr_stream *xdr,
struct dentry *dentry, struct nfs4_delegation *dp,
- struct nfsd_file *nf, char *name, u32 namelen)
+ struct nfsd_file *nf, char *name, u32 namelen,
+ u32 *attrmask)
{
struct path path = nf->nf_file->f_path;
struct nfsd4_fattr_args args = { };
const u32 *reqmask;
- uint32_t *attrmask;
__be32 status;
bool parent;
int ret;
- /* Reserve space for attrmask */
- attrmask = xdr_reserve_space(xdr, 3 * sizeof(uint32_t));
- if (!attrmask)
- return false;
-
ne->ne_file.data = name;
ne->ne_file.len = namelen;
ne->ne_attrs.attrmask.element = attrmask;
@@ -4476,6 +4471,7 @@ u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_event *
struct nfs4_delegation *dp, struct nfsd_file *nf,
u32 *notify_mask)
{
+ u32 attrmask[3][3] = { };
u8 *p = NULL;
*notify_mask = 0;
@@ -4484,7 +4480,8 @@ u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_event *
struct notify_remove4 nr = { };
if (!nfsd4_setup_notify_entry4(&nr.nrm_old_entry, xdr, nne->ne_dentry, dp,
- nf, nne->ne_name, nne->ne_namelen))
+ nf, nne->ne_name, nne->ne_namelen,
+ attrmask[0]))
goto out_err;
p = (u8 *)xdr->p;
if (!xdrgen_encode_notify_remove4(xdr, &nr))
@@ -4495,14 +4492,16 @@ u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_event *
struct notify_remove4 old = { };
if (!nfsd4_setup_notify_entry4(&na.nad_new_entry, xdr, nne->ne_dentry, dp,
- nf, nne->ne_name, nne->ne_namelen))
+ nf, nne->ne_name, nne->ne_namelen,
+ attrmask[0]))
goto out_err;
/* If a file was overwritten, report it in nad_old_entry */
if (nne->ne_target) {
if (!nfsd4_setup_notify_entry4(&old.nrm_old_entry, xdr,
NULL, dp, nf,
- nne->ne_name, nne->ne_namelen))
+ nne->ne_name, nne->ne_namelen,
+ attrmask[1]))
goto out_err;
na.nad_old_entry.count = 1;
na.nad_old_entry.element = &old;
@@ -4521,19 +4520,19 @@ u8 *nfsd4_encode_notify_event(struct xdr_stream *xdr, struct nfsd_notify_event *
/* Don't send any attributes in the old_entry since they're the same in new */
if (!nfsd4_setup_notify_entry4(&nr.nrn_old_entry.nrm_old_entry, xdr,
NULL, dp, nf, nne->ne_name,
- nne->ne_namelen))
+ nne->ne_namelen, attrmask[0]))
goto out_err;
if (!nfsd4_setup_notify_entry4(&nr.nrn_new_entry.nad_new_entry, xdr,
nne->ne_dentry, dp, nf, newname,
- nne->ne_newnamelen))
+ nne->ne_newnamelen, attrmask[1]))
goto out_err;
/* If a file was overwritten, report it in nad_old_entry */
if (nne->ne_target) {
if (!nfsd4_setup_notify_entry4(&old.nrm_old_entry, xdr,
NULL, dp, nf, newname,
- nne->ne_newnamelen))
+ nne->ne_newnamelen, attrmask[2]))
goto out_err;
nr.nrn_new_entry.nad_old_entry.count = 1;
nr.nrn_new_entry.nad_old_entry.element = &old;
@@ -4569,11 +4568,12 @@ u8 *nfsd4_encode_dir_attr_change(struct xdr_stream *xdr, struct nfs4_delegation
{
struct dentry *dentry = nf->nf_file->f_path.dentry;
struct notify_attr4 na = { };
+ u32 attrmask[3] = { };
u8 *p;
/* RFC 8881 s10.4.3: ne_file must be a zero-length string for dir attrs */
if (!nfsd4_setup_notify_entry4(&na.na_changed_entry, xdr,
- dentry, dp, nf, "", 0))
+ dentry, dp, nf, "", 0, attrmask))
return ERR_PTR(-ENOBUFS);
/* No requested attributes to report; omit the event */
--
2.55.0
next prev parent reply other threads:[~2026-08-12 18:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 18:08 [PATCH 0/2] nfsd: don't use the xdr buf for temporary storage in CB_NOTIFY Jeff Layton
2026-08-12 18:08 ` Jeff Layton [this message]
2026-08-12 18:08 ` [PATCH 2/2] nfsd: back CB_NOTIFY notify_mask words with per-delegation storage Jeff Layton
2026-08-12 18:58 ` [PATCH 0/2] nfsd: don't use the xdr buf for temporary storage in CB_NOTIFY 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=20260812-dir-deleg-v1-1-411faa713068@kernel.org \
--to=jlayton@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=cel@kernel.org \
--cc=linux-kernel@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®