All of lore.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@ownmail.net>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>,
	Chuck Lever <cel@kernel.org>, Jeff Layton <jlayton@kernel.org>
Cc: linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org
Subject: [PATCH 4/7] vfs: change vfs_lookup_open() to return found dentry in path.dentry.
Date: Thu, 10 Sep 2026 10:20:50 +1000	[thread overview]
Message-ID: <20260910002934.192979-5-neilb@ownmail.net> (raw)
In-Reply-To: <20260910002934.192979-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

The caller - nfsd - needs to know the type of object found when a
non-regular file was found to exist.  This is most easily done
by passing back the dentry.

So change calling pattern so that the path (now called "path") contains
the parent dentry on entry and the child dentry on exit.
vfs_lookup_open() will dput() the parent and caller must dput() the
child.

If lookup_open() returns -EFTYPE (from ->atomic_open()) we need to
use d_lookup() to find the dentry.  If ->atomic_open() didn't add a
dentry to the dcache we return %NULL in %path->dentry.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/namei.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 0c787363b101..30ccc0c2f02f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4606,7 +4606,7 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
 
 /**
  * vfs_lookup_open - open and possibly create a regular file
- * @parent: directory to contain file
+ * @path: directory to contain file
  * @last: final component of file name
  * @open_flag: O_flags
  * @mode: initial permissions for file
@@ -4619,9 +4619,15 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
  * If the fs object found is not a regular file then -EFTYPE is
  * returned.
  *
+ * @path is updated to contain the dentry that was found if possible.
+ * In particular, if -EFTYPE is returned, then @path.dentry will be the
+ * object that is not a regular file, or %NULL.
+ * Consequently the caller must be prepared for @path.dentry to be
+ * dput(), an it must dput() whatever is in @path.dentry after the call.
+ *
  * Returns: the opened struct file, or an error.
  */
-struct file *vfs_lookup_open(struct path *parent, struct qstr *last,
+struct file *vfs_lookup_open(struct path *path, struct qstr *last,
 			     int open_flag, umode_t mode)
 {
 	struct file *file __free(fput) = NULL;
@@ -4638,7 +4644,7 @@ struct file *vfs_lookup_open(struct path *parent, struct qstr *last,
 	mode |= S_IFREG;
 	open_flag |= __O_REGULAR;
 
-	error = lookup_noperm_common(last, parent->dentry);
+	error = lookup_noperm_common(last, path->dentry);
 	if (error)
 		return ERR_PTR(error);
 
@@ -4646,7 +4652,7 @@ struct file *vfs_lookup_open(struct path *parent, struct qstr *last,
 	if (IS_ERR(file))
 		return file;
 
-	nd.path = *parent;
+	nd.path = *path;
 	nd.last = *last;
 	nd.flags = LOOKUP_OPEN;
 	if (open_flag & O_CREAT) {
@@ -4658,9 +4664,18 @@ struct file *vfs_lookup_open(struct path *parent, struct qstr *last,
 	op.mode = mode;
 	dentry = lookup_open(&nd, file, &op);
 
-	if (IS_ERR(dentry))
+	if (IS_ERR(dentry)) {
+		if (dentry == -EFTYPE) {
+			/* Try to determine what was found */
+			struct dentry *child = d_lookup(path->dentry, &nd.last);
+			dput(path->dentry);
+			path->dentry = child;
+			WARN_ON_ONCE(child && d_is_reg(child));
+		}
 		return ERR_CAST(dentry);
-
+	}
+	dput(path->dentry);
+	path->dentry = dentry;
 	if (d_really_is_negative(dentry)) {
 		error = -ENOENT;
 	} else if (!(file->f_mode & FMODE_CREATED) && (open_flag & O_EXCL)) {
@@ -4668,10 +4683,8 @@ struct file *vfs_lookup_open(struct path *parent, struct qstr *last,
 	} else if (!d_is_reg(dentry)) {
 		error = -EFTYPE;
 	} else if (!(file->f_mode & FMODE_OPENED)) {
-		nd.path.dentry = dentry;
-		error = vfs_open(&nd.path, file);
+		error = vfs_open(path, file);
 	}
-	dput(dentry);
 
 	if (error)
 		return ERR_PTR(error);
-- 
2.50.0.107.gf914562f5916.dirty


  parent reply	other threads:[~2026-09-10  0:30 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-10  0:20 [PATCH 0/7 RFC] fixes for vfs_lookup_open, and integration with nfsd NeilBrown
2026-09-10  0:20 ` [PATCH 1/7] vfs: add some allowed open flags to vfs_lookup_open() NeilBrown
2026-09-10  0:20 ` [PATCH 2/7] vfs: O_NONBLOCK|O_CREAT open shouldn't wait for directory delegation NeilBrown
2026-09-10  0:20 ` [PATCH 3/7] vfs: vfs_lookup_open() should only return -EFTYPE for non-regular files NeilBrown
2026-09-10  0:20 ` NeilBrown [this message]
2026-09-10  0:39   ` [PATCH 4/7] vfs: change vfs_lookup_open() to return found dentry in path.dentry NeilBrown
2026-09-10 15:13   ` Chuck Lever
2026-09-10  0:20 ` [PATCH 5/7] nfsd: switch NFS4 OPEN to use vfs_lookup_open() NeilBrown
2026-09-10 15:41   ` Chuck Lever
2026-09-10  0:20 ` [PATCH 6/7] nfsd: nfsd_check_obj_isreg() to use nfs error codes NeilBrown
2026-09-10  0:20 ` [PATCH 7/7] nfsd: use vfs_lookup_open() for non-creating open requests too NeilBrown
2026-09-10 15:47   ` 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=20260910002934.192979-5-neilb@ownmail.net \
    --to=neilb@ownmail.net \
    --cc=brauner@kernel.org \
    --cc=cel@kernel.org \
    --cc=jlayton@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.