Linux NFS development
 help / color / mirror / Atom feed
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 09/14] nfsd: revert nfsd4: delay setting current_fh in open
Date: Sat, 22 Nov 2025 11:47:07 +1100	[thread overview]
Message-ID: <20251122005236.3440177-10-neilb@ownmail.net> (raw)
In-Reply-To: <20251122005236.3440177-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

This reverts
 Commit: c0e6bee48059 ("nfsd4: delay setting current_fh in open")

That patch was a precusor to

Commit: 4335723e8e9f ("nfsd4: fix delegation-unlink/rename race")

which attempted to fix a race by holding the parent directory locked for
longer.  That race was subsequently fixed a better way
Commit: 876c553cb410 ("NFSD: verify the opened dentry after setting a delegation")

which repeated the lookup after the delegation was obtained.

So delaying the setting of current_fh is no longer needed.

A cost of setting current_fh later is that when
nfs4_inc_and_copy_stateid() is called, current_fh has already been set
to the correct filehandle everywhere *except* in nfsd4_process_open2().
With this change, the current_fh will be stable from when
nfs4_inc_and_copy_stateid() which will allow a future patch which
simplifies the handling of current_stateid.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/nfsd/nfs4proc.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 0c13c75e4092..0f490f2524fa 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -424,16 +424,17 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 }
 
 static __be32
-do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh)
+do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
 {
 	struct svc_fh *current_fh = &cstate->current_fh;
+	struct svc_fh *resfh;
 	int accmode;
 	__be32 status;
 
-	*resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
-	if (!*resfh)
+	resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
+	if (!resfh)
 		return nfserr_jukebox;
-	fh_init(*resfh, NFS4_FHSIZE);
+	fh_init(resfh, NFS4_FHSIZE);
 	open->op_truncate = false;
 
 	if (open->op_create) {
@@ -453,7 +454,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 		 */
 
 		current->fs->umask = open->op_umask;
-		status = nfsd4_create_file(rqstp, current_fh, *resfh, open);
+		status = nfsd4_create_file(rqstp, current_fh, resfh, open);
 		current->fs->umask = 0;
 
 		/*
@@ -466,7 +467,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 						FATTR4_WORD1_TIME_MODIFY);
 	} else {
 		status = nfsd_lookup(rqstp, current_fh,
-				     open->op_fname, open->op_fnamelen, *resfh);
+				     open->op_fname, open->op_fnamelen, resfh);
 		if (status == nfs_ok)
 			/* NFSv4 protocol requires change attributes even though
 			 * no change happened.
@@ -475,18 +476,21 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
 	}
 	if (status)
 		goto out;
-	status = nfsd_check_obj_isreg(*resfh, cstate->minorversion);
+	status = nfsd_check_obj_isreg(resfh, cstate->minorversion);
 	if (status)
 		goto out;
 
-	nfsd4_set_open_owner_reply_cache(cstate, open, *resfh);
+	nfsd4_set_open_owner_reply_cache(cstate, open, resfh);
 	accmode = NFSD_MAY_NOP;
 	if (open->op_created ||
 			open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
 		accmode |= NFSD_MAY_OWNER_OVERRIDE;
-	status = do_open_permission(rqstp, *resfh, open, accmode);
+	status = do_open_permission(rqstp, resfh, open, accmode);
 	set_change_info(&open->op_cinfo, current_fh);
+	fh_dup2(current_fh, resfh);
 out:
+	fh_put(resfh);
+	kfree(resfh);
 	return status;
 }
 
@@ -537,7 +541,6 @@ 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);
@@ -606,7 +609,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		fh_dup2(&parent_fh, &cstate->current_fh);
 		fallthrough;
 	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
-		status = do_open_lookup(rqstp, cstate, open, &resfh);
+		status = do_open_lookup(rqstp, cstate, open);
 		if (status)
 			goto out;
 		break;
@@ -622,7 +625,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		status = do_open_fhandle(rqstp, cstate, open);
 		if (status)
 			goto out;
-		resfh = &cstate->current_fh;
 		break;
 	case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
 	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
@@ -633,7 +635,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		goto out;
 	}
 
-	status = nfsd4_process_open2(rqstp, resfh, &parent_fh, open);
+	status = nfsd4_process_open2(rqstp, &cstate->current_fh, &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",
@@ -645,11 +647,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		fput(open->op_filp);
 		open->op_filp = NULL;
 	}
-	if (resfh && resfh != &cstate->current_fh) {
-		fh_dup2(&cstate->current_fh, resfh);
-		fh_put(resfh);
-		kfree(resfh);
-	}
 	nfsd4_cleanup_open_state(cstate, open);
 	nfsd4_bump_seqid(cstate, status);
 	return status;
-- 
2.50.0.107.gf914562f5916.dirty


  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 ` [PATCH v6 08/14] nfsd: pass parent_fh explicitly to nfsd4_process_open2() NeilBrown
2025-11-22  0:47 ` NeilBrown [this message]
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-10-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