linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: NeilBrown <neil@brown.name>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>
Cc: David Howells <dhowells@redhat.com>,
	Marc Dionne <marc.dionne@auristor.com>,
	Xiubo Li <xiubli@redhat.com>, Ilya Dryomov <idryomov@gmail.com>,
	Tyler Hicks <code@tyhicks.com>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Richard Weinberger <richard@nod.at>,
	Anton Ivanov <anton.ivanov@cambridgegreys.com>,
	Johannes Berg <johannes@sipsolutions.net>,
	Trond Myklebust <trondmy@kernel.org>,
	Anna Schumaker <anna@kernel.org>,
	Chuck Lever <chuck.lever@oracle.com>,
	Jeff Layton <jlayton@kernel.org>,
	Amir Goldstein <amir73il@gmail.com>,
	Steve French <sfrench@samba.org>,
	Namjae Jeon <linkinjeon@kernel.org>,
	Carlos Maiolino <cem@kernel.org>,
	linux-fsdevel@vger.kernel.org, linux-afs@lists.infradead.org,
	netfs@lists.linux.dev, ceph-devel@vger.kernel.org,
	ecryptfs@vger.kernel.org, linux-um@lists.infradead.org,
	linux-nfs@vger.kernel.org, linux-unionfs@vger.kernel.org,
	linux-cifs@vger.kernel.org, linux-xfs@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 04/11] VFS: introduce dentry_lookup_continue()
Date: Tue, 12 Aug 2025 12:25:07 +1000	[thread overview]
Message-ID: <20250812235228.3072318-5-neil@brown.name> (raw)
In-Reply-To: <20250812235228.3072318-1-neil@brown.name>

A few callers operate on a dentry which they already have - unlike the
normal case where a lookup proceeds an operation.

For these callers dentry_lookup_continue() is provided where other
callers would use dentry_lookup().  The call will fail if, after the
lock was gained, the child is no longer a child of the given parent.

There are a couple of callers that want to lock a dentry in whatever
its current parent is.  For these a NULL parent can be passed, in which
case ->d_parent is used.  In this case the call cannot fail.

The idea behind the name is that the actual lookup occurred some time
ago, and now we are continuing with an operation on the dentry.

When the operation completes done_dentry_lookup() must be called.  An
extra reference is taken when the dentry_lookup_continue() call succeeds
and will be dropped by done_dentry_lookup().

This will be used in smb/server, ecryptfs, and overlayfs, each of which
have their own lock_parent() or parent_lock() or similar; and a few
other places which lock the parent but don't check if the parent is
still correct (often because rename isn't supported so parent cannot be
incorrect).

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/namei.c            | 39 +++++++++++++++++++++++++++++++++++++++
 include/linux/namei.h |  2 ++
 2 files changed, 41 insertions(+)

diff --git a/fs/namei.c b/fs/namei.c
index 7af9b464886a..df21b6fa5a0e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1874,6 +1874,45 @@ struct dentry *dentry_lookup_killable(struct mnt_idmap *idmap,
 }
 EXPORT_SYMBOL(dentry_lookup_killable);
 
+/**
+ * dentry_lookup_continue: lock a dentry if it is still in the given parent, prior to dir ops
+ * @child: the dentry to lock
+ * @parent: the dentry of the assumed parent
+ *
+ * The child is locked - currently by taking i_rwsem on the parent - to
+ * prepare for create/remove operations.  If the given parent is not
+ * %NULL and is no longer the parent of the dentry after the lock is
+ * gained, the lock is released and the call fails (returns
+ * ERR_PTR(-EINVAL).
+ *
+ * On success a reference to the child is taken and returned.  The lock
+ * and reference must both be dropped by done_dentry_lookup() after the
+ * operation completes.
+ */
+struct dentry *dentry_lookup_continue(struct dentry *child,
+				      struct dentry *parent)
+{
+	struct dentry *p = parent;
+
+again:
+	if (!parent)
+		p = dget_parent(child);
+	inode_lock_nested(d_inode(p), I_MUTEX_PARENT);
+	if (child->d_parent != p) {
+		inode_unlock(d_inode(p));
+		if (!parent) {
+			dput(p);
+			goto again;
+		}
+		return ERR_PTR(-EINVAL);
+	}
+	if (!parent)
+		dput(p);
+	/* get the child to balance with done_dentry_lookup() which puts it. */
+	return dget(child);
+}
+EXPORT_SYMBOL(dentry_lookup_continue);
+
 /**
  * done_dentry_lookup - finish a lookup used for create/delete
  * @dentry:  the target dentry
diff --git a/include/linux/namei.h b/include/linux/namei.h
index facb5852afa9..67eef91603cc 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -88,6 +88,8 @@ struct dentry *dentry_lookup_killable(struct mnt_idmap *idmap,
 				      unsigned int lookup_flags);
 struct dentry *dentry_lookup_noperm(struct qstr *name, struct dentry *base,
 				      unsigned int lookup_flags);
+struct dentry *dentry_lookup_continue(struct dentry *child,
+				      struct dentry *parent);
 void done_dentry_lookup(struct dentry *dentry);
 /* no_free_ptr() must not be used here - use dget() */
 DEFINE_FREE(dentry_lookup, struct dentry *, if (_T) done_dentry_lookup(_T))
-- 
2.50.0.107.gf914562f5916.dirty


  parent reply	other threads:[~2025-08-12 23:53 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-12  2:25 [PATCH 00/11] VFS: prepare for changes to directory locking NeilBrown
2025-08-12  2:25 ` [PATCH 01/11] VFS: discard err2 in filename_create() NeilBrown
2025-08-13  3:22   ` Al Viro
2025-08-12  2:25 ` [PATCH 02/11] VFS: introduce dentry_lookup() and friends NeilBrown
2025-08-13  4:12   ` Al Viro
2025-08-13  7:48     ` NeilBrown
2025-08-12  2:25 ` [PATCH 03/11] VFS: add dentry_lookup_killable() NeilBrown
2025-08-13  4:15   ` Al Viro
2025-08-13  7:50     ` NeilBrown
2025-08-12  2:25 ` NeilBrown [this message]
2025-08-13  4:22   ` [PATCH 04/11] VFS: introduce dentry_lookup_continue() Al Viro
2025-08-13  7:53     ` NeilBrown
2025-08-18 12:39   ` Amir Goldstein
2025-08-18 21:52     ` NeilBrown
2025-08-19  8:37       ` Amir Goldstein
2025-08-12  2:25 ` [PATCH 05/11] VFS: add rename_lookup() NeilBrown
2025-08-13  4:35   ` Al Viro
2025-08-13  8:04     ` NeilBrown
2025-08-14  1:40       ` Al Viro
2025-08-12  2:25 ` [PATCH 06/11] VFS: unify old_mnt_idmap and new_mnt_idmap in renamedata NeilBrown
2025-08-13  4:36   ` Al Viro
2025-08-12  2:25 ` [PATCH 07/11] VFS: Change vfs_mkdir() to unlock on failure NeilBrown
2025-08-13  7:22   ` Amir Goldstein
2025-08-14  1:13     ` NeilBrown
2025-08-14 13:29       ` Amir Goldstein
2025-08-12  2:25 ` [PATCH 08/11] VFS: allow d_splice_alias() and d_add() to work on hashed dentries NeilBrown
2025-08-13  5:07   ` Al Viro
2025-08-12  2:25 ` [PATCH 09/11] VFS: use global wait-queue table for d_alloc_parallel() NeilBrown
2025-08-13  6:44   ` Al Viro
2025-08-14  1:31     ` NeilBrown
2025-08-12  2:25 ` [PATCH 10/11] VFS: use d_alloc_parallel() in lookup_one_qstr_excl() NeilBrown
2025-08-13  5:19   ` Al Viro
2025-08-14  0:56     ` NeilBrown
2025-08-12  2:25 ` [PATCH 11/11] VFS: introduce d_alloc_noblock() and d_alloc_locked() NeilBrown
2025-08-13  6:53   ` Al Viro
2025-08-14  2:07     ` NeilBrown
2025-08-14 13:47       ` Amir Goldstein
2025-08-13  0:01 ` [PATCH 00/11] VFS: prepare for changes to directory locking Al Viro

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=20250812235228.3072318-5-neil@brown.name \
    --to=neil@brown.name \
    --cc=amir73il@gmail.com \
    --cc=anna@kernel.org \
    --cc=anton.ivanov@cambridgegreys.com \
    --cc=brauner@kernel.org \
    --cc=cem@kernel.org \
    --cc=ceph-devel@vger.kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=code@tyhicks.com \
    --cc=dhowells@redhat.com \
    --cc=ecryptfs@vger.kernel.org \
    --cc=idryomov@gmail.com \
    --cc=jack@suse.cz \
    --cc=jlayton@kernel.org \
    --cc=johannes@sipsolutions.net \
    --cc=linkinjeon@kernel.org \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-um@lists.infradead.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=marc.dionne@auristor.com \
    --cc=miklos@szeredi.hu \
    --cc=netfs@lists.linux.dev \
    --cc=richard@nod.at \
    --cc=sfrench@samba.org \
    --cc=trondmy@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=xiubli@redhat.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;
as well as URLs for NNTP newsgroup(s).