From: NeilBrown <neilb@ownmail.net>
To: Chuck Lever <chuck.lever@oracle.com>, Jeff Layton <jlayton@kernel.org>
Cc: Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
linux-nfs@vger.kernel.org
Subject: [PATCH v6 08/14] nfsd: pass parent_fh explicitly to nfsd4_process_open2()
Date: Sat, 22 Nov 2025 11:47:06 +1100 [thread overview]
Message-ID: <20251122005236.3440177-9-neilb@ownmail.net> (raw)
In-Reply-To: <20251122005236.3440177-1-neilb@ownmail.net>
From: NeilBrown <neil@brown.name>
nfsd4_process_open2() sometimes needs the filehandle of the parent of
the created file. This is passed to nfs4_set_delegation() to verify
that the parent is unchanged after the delegation is obtained.
Currently nfsd4_process_open2() knows that the parent is
cstate->current_fh but that will change in the next patch.
So with this patch we take a copy of current_fh earlier in the one case
(NFS4_OPEN_CLAIM_NULL) where it is needed and before any lookup happens.
nfs4_open_delegation() currently uses "currentfh" (which is the parent)
to pass to nfs4_delegation_stat(). As nfs4_delegation_stat() only wants
the vfsmount, it can equally well use "fh" which is the filehandle for the
newly created file - it must be on the same filesystem.
Signed-off-by: NeilBrown <neil@brown.name>
---
fs/nfsd/nfs4proc.c | 8 ++++++--
fs/nfsd/nfs4state.c | 25 ++++++++++++-------------
fs/nfsd/xdr4.h | 4 +++-
3 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index bd7ba5df07a7..0c13c75e4092 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -538,6 +538,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct nfsd4_open *open = &u->open;
__be32 status;
struct svc_fh *resfh = NULL;
+ struct svc_fh parent_fh = {};
struct net *net = SVC_NET(rqstp);
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
bool reclaim = false;
@@ -601,8 +602,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
switch (open->op_claim_type) {
- case NFS4_OPEN_CLAIM_DELEGATE_CUR:
case NFS4_OPEN_CLAIM_NULL:
+ fh_dup2(&parent_fh, &cstate->current_fh);
+ fallthrough;
+ case NFS4_OPEN_CLAIM_DELEGATE_CUR:
status = do_open_lookup(rqstp, cstate, open, &resfh);
if (status)
goto out;
@@ -630,7 +633,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
}
- status = nfsd4_process_open2(rqstp, resfh, open);
+ status = nfsd4_process_open2(rqstp, resfh, &parent_fh, open);
+ fh_put(&parent_fh);
if (status && open->op_created)
pr_warn("nfsd4_process_open2 failed to open newly-created file: status=%u\n",
be32_to_cpu(status));
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index f10c22d02735..3aebe90a12ec 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6046,7 +6046,7 @@ static bool nfsd4_want_deleg_timestamps(const struct nfsd4_open *open)
static struct nfs4_delegation *
nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,
- struct svc_fh *parent)
+ struct svc_fh *parent_fh)
{
bool deleg_ts = nfsd4_want_deleg_timestamps(open);
struct nfs4_client *clp = stp->st_stid.sc_client;
@@ -6146,8 +6146,8 @@ nfs4_set_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,
if (status)
goto out_clnt_odstate;
- if (parent) {
- status = nfsd4_verify_deleg_dentry(open, fp, parent);
+ if (parent_fh && parent_fh->fh_dentry) {
+ status = nfsd4_verify_deleg_dentry(open, fp, parent_fh);
if (status)
goto out_unlock;
}
@@ -6288,13 +6288,12 @@ nfsd4_add_rdaccess_to_wrdeleg(struct svc_rqst *rqstp, struct nfsd4_open *open,
*/
static void
nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
- struct nfs4_ol_stateid *stp, struct svc_fh *currentfh,
+ struct nfs4_ol_stateid *stp, struct svc_fh *parent_fh,
struct svc_fh *fh)
{
struct nfs4_openowner *oo = openowner(stp->st_stateowner);
bool deleg_ts = nfsd4_want_deleg_timestamps(open);
struct nfs4_client *clp = stp->st_stid.sc_client;
- struct svc_fh *parent = NULL;
struct nfs4_delegation *dp;
struct kstat stat;
int status = 0;
@@ -6308,8 +6307,6 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
open->op_recall = true;
break;
case NFS4_OPEN_CLAIM_NULL:
- parent = currentfh;
- fallthrough;
case NFS4_OPEN_CLAIM_FH:
/*
* Let's not give out any delegations till everyone's
@@ -6327,7 +6324,7 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
default:
goto out_no_deleg;
}
- dp = nfs4_set_delegation(open, stp, parent);
+ dp = nfs4_set_delegation(open, stp, parent_fh);
if (IS_ERR(dp))
goto out_no_deleg;
@@ -6337,7 +6334,7 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
struct file *f = dp->dl_stid.sc_file->fi_deleg_file->nf_file;
if (!nfsd4_add_rdaccess_to_wrdeleg(rqstp, open, fh, stp) ||
- !nfs4_delegation_stat(dp, currentfh, &stat)) {
+ !nfs4_delegation_stat(dp, fh, &stat)) {
nfs4_put_stid(&dp->dl_stid);
destroy_delegation(dp);
goto out_no_deleg;
@@ -6354,7 +6351,7 @@ nfs4_open_delegation(struct svc_rqst *rqstp, struct nfsd4_open *open,
spin_unlock(&f->f_lock);
trace_nfsd_deleg_write(&dp->dl_stid.sc_stateid);
} else {
- open->op_delegate_type = deleg_ts && nfs4_delegation_stat(dp, currentfh, &stat) ?
+ open->op_delegate_type = deleg_ts && nfs4_delegation_stat(dp, fh, &stat) ?
OPEN_DELEGATE_READ_ATTRS_DELEG : OPEN_DELEGATE_READ;
dp->dl_atime = stat.atime;
trace_nfsd_deleg_read(&dp->dl_stid.sc_stateid);
@@ -6403,6 +6400,7 @@ static bool open_xor_delegation(struct nfsd4_open *open)
* nfsd4_process_open2 - finish open processing
* @rqstp: the RPC transaction being executed
* @current_fh: NFSv4 COMPOUND's current filehandle
+ * @parent_fh: filehandle of parent when CLAIM_NULL
* @open: OPEN arguments
*
* If successful, (1) truncate the file if open->op_truncate was
@@ -6412,7 +6410,9 @@ static bool open_xor_delegation(struct nfsd4_open *open)
* network byte order is returned.
*/
__be32
-nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
+nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+ struct svc_fh *parent_fh,
+ struct nfsd4_open *open)
{
struct nfsd4_compoundres *resp = rqstp->rq_resp;
struct nfs4_client *cl = open->op_openowner->oo_owner.so_client;
@@ -6509,8 +6509,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
* Attempt to hand out a delegation. No error return, because the
* OPEN succeeds even if we fail.
*/
- nfs4_open_delegation(rqstp, open, stp,
- &resp->cstate.current_fh, current_fh);
+ nfs4_open_delegation(rqstp, open, stp, parent_fh, current_fh);
/*
* If there is an existing open stateid, it must be updated and
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index b5ec2cdd61a0..ea61e1a4c263 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -974,7 +974,9 @@ __be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *,
extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
struct nfsd4_open *open, struct nfsd_net *nn);
extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
- struct svc_fh *current_fh, struct nfsd4_open *open);
+ struct svc_fh *current_fh,
+ struct svc_fh *parent_fh,
+ struct nfsd4_open *open);
extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate);
extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
struct nfsd4_open *open);
--
2.50.0.107.gf914562f5916.dirty
next prev parent reply other threads:[~2025-11-22 0:53 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-22 0:46 [PATCH v7 00/14] nfsd: assorted cleanups involving v4 special stateids NeilBrown
2025-11-22 0:46 ` [PATCH v6 01/14] nfsd: rename ALLOWED_WITHOUT_FH to ALLOWED_WITHOUT_LOCAL_FH and revise use NeilBrown
2025-11-22 20:40 ` Chuck Lever
2025-11-22 0:47 ` [PATCH v6 02/14] nfsd: discard NFSD4_FH_FOREIGN NeilBrown
2025-11-22 0:47 ` [PATCH v6 03/14] nfsd: simplify foreign-filehandle handling to better match RFC-7862 NeilBrown
2025-11-22 0:47 ` [PATCH v6 04/14] nfsd: allow unrecognisable filehandle for foreign servers in COPY NeilBrown
2025-11-22 21:16 ` Chuck Lever
2025-11-23 16:43 ` Chuck Lever
2025-11-27 0:55 ` NeilBrown
2026-01-23 17:03 ` Chuck Lever
2025-11-22 0:47 ` [PATCH v6 05/14] nfsd: report correct error for attempt to use foreign filehandle NeilBrown
2025-11-22 0:47 ` [PATCH v6 06/14] nfsd: drop explicit tests for special stateids which would be invalid NeilBrown
2025-11-22 0:47 ` [PATCH v6 07/14] nfsd: revise names of special stateid, and predicate functions NeilBrown
2025-11-22 0:47 ` NeilBrown [this message]
2025-11-22 0:47 ` [PATCH v6 09/14] nfsd: revert nfsd4: delay setting current_fh in open NeilBrown
2025-11-22 0:47 ` [PATCH v6 10/14] nfsd: simplify clearing of current-state-id NeilBrown
2025-11-22 0:47 ` [PATCH v6 11/14] nfsd: simplify use of the current stateid NeilBrown
2025-11-22 0:47 ` [PATCH v6 12/14] nfsd: simplify saving " NeilBrown
2025-11-22 0:47 ` [PATCH v6 13/14] nfsd: discard current_stateid.h NeilBrown
2025-11-22 0:47 ` [PATCH v6 14/14] nfsd: conditionally clear seqid when current_stateid is used NeilBrown
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=20251122005236.3440177-9-neilb@ownmail.net \
--to=neilb@ownmail.net \
--cc=Dai.Ngo@oracle.com \
--cc=chuck.lever@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox