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>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>
Cc: Tom Haynes <loghyr@gmail.com>,
linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org, Jeff Layton <jlayton@kernel.org>
Subject: [PATCH v3 4/8] nfsd: don't vet delegated times against an exclusive-create verifier
Date: Mon, 09 Nov 2026 15:36:45 -0500 [thread overview]
Message-ID: <20261109-deleg-cb-getattr-times-v3-4-710c7244a6ea@kernel.org> (raw)
In-Reply-To: <20261109-deleg-cb-getattr-times-v3-0-710c7244a6ea@kernel.org>
An exclusive create stores the client's verifier in atime and mtime
until the client sets real times. A delegation granted on that OPEN
records those as dl_atime and dl_mtime (e.g. 4777.0 and 681509.0), so
vetting the holder's times against them always passes, including times
older than the file itself.
When the OPEN did an exclusive create, use the ctime at grant, less 1ns,
as the floor for atime and mtime too. Vetting rejects a time equal to
its floor, and a holder time equal to the ctime must still replace the
verifier. Do this for both write and read timestamp delegations, and
set a read delegation's floors only when the stat behind them was
done. Move nfsd4_create_is_exclusive() to xdr4.h so nfs4state.c can use
it.
Fixes: 7663e963a511 ("nfsd: track original timestamps in nfs4_delegation")
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/nfsd/nfs4proc.c | 6 ------
fs/nfsd/nfs4state.c | 27 +++++++++++++++++++++++----
fs/nfsd/xdr4.h | 6 ++++++
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 4e5d5852bf57..25613c1ffaaf 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -245,12 +245,6 @@ static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate
&resfh->fh_handle);
}
-static inline bool nfsd4_create_is_exclusive(int createmode)
-{
- return createmode == NFS4_CREATE_EXCLUSIVE ||
- createmode == NFS4_CREATE_EXCLUSIVE4_1;
-}
-
static struct file *do_lookup_open(struct path *parent,
struct qstr *name,
unsigned int oflags,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 35712e129b7a..4566fa86f82f 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -7466,6 +7466,26 @@ nfsd4_add_rdaccess_to_wrdeleg(struct svc_rqst *rqstp, struct nfsd4_open *open,
return true;
}
+/*
+ * An exclusive create stores the verifier in atime and mtime, so the only
+ * real floor for the holder's times is the ctime. Vetting rejects a time
+ * equal to its floor, but one equal to the ctime must still replace the
+ * verifier.
+ */
+static void nfsd4_deleg_set_time_floors(struct nfs4_delegation *dp,
+ const struct nfsd4_open *open,
+ const struct kstat *stat)
+{
+ dp->dl_atime = stat->atime;
+ dp->dl_ctime = stat->ctime;
+ dp->dl_mtime = stat->mtime;
+ if (open->op_created &&
+ nfsd4_create_is_exclusive(open->op_createmode)) {
+ dp->dl_atime = timespec64_sub(stat->ctime, ns_to_timespec64(1));
+ dp->dl_mtime = dp->dl_atime;
+ }
+}
+
/*
* The Linux NFS server does not offer write delegations to NFSv4.0
* clients in order to avoid conflicts between write delegations and
@@ -7556,9 +7576,7 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
OPEN_DELEGATE_WRITE;
dp->dl_cb_fattr.ncf_initial_cinfo = nfsd4_change_attribute(&stat);
dp->dl_cb_fattr.ncf_srv_cinfo = dp->dl_cb_fattr.ncf_initial_cinfo;
- dp->dl_atime = stat.atime;
- dp->dl_ctime = stat.ctime;
- dp->dl_mtime = stat.mtime;
+ nfsd4_deleg_set_time_floors(dp, open, &stat);
spin_lock(&f->f_lock);
if (deleg_ts)
f->f_mode |= FMODE_NOCMTIME;
@@ -7567,7 +7585,8 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
} else {
open->op_delegate_type = deleg_ts && nfs4_delegation_stat(dp, currentfh, &stat) ?
OPEN_DELEGATE_READ_ATTRS_DELEG : OPEN_DELEGATE_READ;
- dp->dl_atime = stat.atime;
+ if (open->op_delegate_type == OPEN_DELEGATE_READ_ATTRS_DELEG)
+ nfsd4_deleg_set_time_floors(dp, open, &stat);
trace_nfsd_deleg_read(&dp->dl_stid.sc_stateid);
}
nfs4_put_stid(&dp->dl_stid);
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index ecab2249e9bd..feda5464f260 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -280,6 +280,12 @@ struct nfsd4_open {
struct svc_rqst *op_rqstp;
};
+static inline bool nfsd4_create_is_exclusive(int createmode)
+{
+ return createmode == NFS4_CREATE_EXCLUSIVE ||
+ createmode == NFS4_CREATE_EXCLUSIVE4_1;
+}
+
struct nfsd4_open_confirm {
stateid_t oc_req_stateid /* request */;
u32 oc_seqid /* request */;
--
2.56.0
next prev parent reply other threads:[~2026-11-09 20:37 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 20:36 [PATCH v3 0/8] nfsd: more delegated timestamp fixes Jeff Layton
2026-11-09 20:36 ` [PATCH v3 1/8] nfsd: Report vetted delegated timestamps in GETATTR replies Jeff Layton
2026-11-09 20:36 ` [PATCH v3 2/8] nfsd: Honor delegated timestamps when change and size match Jeff Layton
2026-11-09 20:36 ` [PATCH v3 3/8] nfsd: don't stamp over an applied delegated mtime at DELEGRETURN Jeff Layton
2026-11-09 20:36 ` Jeff Layton [this message]
2026-11-09 20:36 ` [PATCH v3 5/8] nfsd: mark the delegation written on COPY/CLONE instead of stamping c/mtime Jeff Layton
2026-11-09 20:36 ` [PATCH v3 6/8] fs: check a fine-grained time before clamping a delegated ctime Jeff Layton
2026-11-09 20:36 ` [PATCH v3 7/8] nfsd: check a fine-grained time before clamping a delegated mtime Jeff Layton
2026-11-09 20:36 ` [PATCH v3 8/8] nfsd: raise delegated time floors after a size-changing SETATTR Jeff Layton
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=20261109-deleg-cb-getattr-times-v3-4-710c7244a6ea@kernel.org \
--to=jlayton@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=brauner@kernel.org \
--cc=cel@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=loghyr@gmail.com \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
--cc=viro@zeniv.linux.org.uk \
/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®