Linux NFS development
 help / color / mirror / Atom feed
* [PATCH] nfsd: switch nfsd4_open() to use vfs_lookup_open()
@ 2026-09-02  2:30 NeilBrown
  2026-09-02 12:40 ` Jeff Layton
  2026-09-03  3:04 ` Chuck Lever
  0 siblings, 2 replies; 4+ messages in thread
From: NeilBrown @ 2026-09-02  2:30 UTC (permalink / raw)
  To: Chuck Lever, Jeff Layton; +Cc: Christian Brauner, linux-nfs


From: NeilBrown <neil@brown.name>

The functionality that was recently gathered into do_lookup_open() is
now available from the vfs as vfs_lookup_open().

This implementation shares more code with syscall open paths and so uses
some filesystem interfaces slightly more correctly.  It also takes the
responsibility for locking out of nfsd so that planned changes can
happen entirely in VFS code.

One difference is that do_lookup_open() would use nfsd_check_obj_isreg()
to get an error when the name exists but is not a regular file.
vfs_lookup_open() uses slightly different error code, particularly
returning -ENODEV when a device-special file is found.  So we need
to map that error to -EFTYPE.

Unfortunately vfs_lookup_open() doesn't allow O_LARGEFILE so we need
to patch it to avoid a warning.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/namei.c         |  2 +-
 fs/nfsd/nfs4proc.c | 66 ++++++++++------------------------------------
 2 files changed, 15 insertions(+), 53 deletions(-)

This patch is against nfsd-test.  I would like it to land there so it
best good nfsd testing over the coming weeks.
Thanks,
NeilBrown


diff --git a/fs/namei.c b/fs/namei.c
index d95249dd527c..85fd5e8221e2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4632,7 +4632,7 @@ struct file *vfs_lookup_open(struct path *parent, struct qstr *last,
 	int error = 0;
 
 	WARN_ONCE(mode & ~S_IALLUGO, "mode must only have permission bits");
-	WARN_ONCE(open_flag & ~(O_ACCMODE|O_CREAT|O_EXCL|O_TRUNC|__O_REGULAR),
+	WARN_ONCE(open_flag & ~(O_ACCMODE|O_CREAT|O_EXCL|O_TRUNC|__O_REGULAR|O_LARGEFILE),
 		  "open_flag has unsupported flags");
 
 	mode |= S_IFREG;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 33dc92d48ce0..ae70f7489d95 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -213,52 +213,6 @@ static inline bool nfsd4_create_is_exclusive(int createmode)
 		createmode == NFS4_CREATE_EXCLUSIVE4_1;
 }
 
-static struct file *do_lookup_open(struct path *parent,
-				   struct qstr *name,
-				   unsigned int oflags,
-				   umode_t mode)
-{
-	struct file *filp = NULL;
-	struct path path;
-	struct dentry *child;
-	int want_write_err = 0;
-
-	want_write_err = mnt_want_write(parent->mnt);
-
-	child = start_creating(&nop_mnt_idmap, parent->dentry, name);
-	if (IS_ERR(child)) {
-		filp = ERR_CAST(child);
-		goto out;
-	}
-	path.mnt = parent->mnt;
-	path.dentry = child;
-
-	if (d_really_is_positive(child)) {
-		/*
-		 * open the file so that we consistently have a valid
-		 * op_filp and consequently a valid ->f_path.dentry.
-		 */
-		int err = nfsd_check_obj_isreg(child);
-
-		if (err)
-			filp = ERR_PTR(err);
-		else
-			filp = dentry_open(&path, oflags, current_cred());
-	} else if (!(oflags & O_CREAT)) {
-		filp = ERR_PTR(-ENOENT);
-	} else if (want_write_err) {
-		filp = ERR_PTR(want_write_err);
-	} else {
-		filp = dentry_create(&path, oflags, mode, current_cred());
-		child = path.dentry;
-	}
-	end_creating(child);
-out:
-	if (!want_write_err)
-		mnt_drop_write(parent->mnt);
-	return filp;
-}
-
 /*
  * Implement NFSv4's unchecked, guarded, and exclusive create
  * semantics for regular files. Open state for this new file is
@@ -390,13 +344,21 @@ nfsd4_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp,
 		/* Might still succeed if no create is needed */
 		oflags &= ~O_CREAT;
 
-	open->op_filp = do_lookup_open(&parent,
-				       &QSTR_LEN(open->op_fname,
-						 open->op_fnamelen),
-				       oflags,
-				       open->op_iattr.ia_mode);
+	open->op_filp = vfs_lookup_open(&parent,
+					&QSTR_LEN(open->op_fname,
+						  open->op_fnamelen),
+					oflags,
+					open->op_iattr.ia_mode);
 	if (IS_ERR(open->op_filp)) {
-		status = nfserrno(PTR_ERR(open->op_filp));
+		int hosterr = PTR_ERR(open->op_filp);
+
+		/*
+		 * NFS doesn't differentiate between device files and
+		 * sock/fifo when reporting an error.
+		 */
+		if (hosterr == -ENODEV)
+			hosterr = -EFTYPE;
+		status = nfserrno(hosterr);
 		open->op_filp = NULL;
 		if (status == nfserr_noent && create_status)
 			status = create_status;

base-commit: f5dc2038906bb0c9627c99bea06dd7786b5ac2d1
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-03  3:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02  2:30 [PATCH] nfsd: switch nfsd4_open() to use vfs_lookup_open() NeilBrown
2026-09-02 12:40 ` Jeff Layton
2026-09-02 22:38   ` NeilBrown
2026-09-03  3:04 ` Chuck Lever

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox