From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neilb@ownmail.net>, Jeff Layton <jlayton@kernel.org>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>,
Chuck Lever <chuck.lever@oracle.com>
Subject: [PATCH v2 4/6] fs: invoke group_pin_kill() during mount teardown
Date: Wed, 7 Jan 2026 19:40:14 -0500 [thread overview]
Message-ID: <20260108004016.3907158-5-cel@kernel.org> (raw)
In-Reply-To: <20260108004016.3907158-1-cel@kernel.org>
From: Chuck Lever <chuck.lever@oracle.com>
The group_pin_kill() function iterates the superblock's s_pins list
and invokes each pin's kill callback. Previously, this function was
called only during remount read-only (in reconfigure_super).
Add a group_pin_kill() call in cleanup_mnt() so that pins registered
via pin_insert_sb() receive callbacks during mount teardown as
well. This call runs after mnt_pin_kill() processes the per-mount
m_list, ensuring:
- Pins registered via pin_insert() receive their callback from
mnt_pin_kill() (which also removes them from s_list via
pin_remove()), so group_pin_kill() skips them.
- Pins registered via pin_insert_sb() are only on s_list, so
mnt_pin_kill() skips them and group_pin_kill() invokes their
callback.
This enables subsystems to use pin_insert_sb() for receiving
unmount notifications while avoiding any problematic locking context
that mnt_pin_kill() callbacks must handle.
Because group_pin_kill() operates on the superblock's s_pins list,
unmounting any mount of a filesystem--including bind mounts--triggers
callbacks for all pins registered on that superblock. For NFSD, this
means unmounting an exported bind mount revokes NFSv4 state for the
entire filesystem, even if other mounts remain.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/fs_pin.c | 14 +++++++-------
fs/namespace.c | 2 ++
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/fs/fs_pin.c b/fs/fs_pin.c
index 7204b4a5891f..54c1163a9cde 100644
--- a/fs/fs_pin.c
+++ b/fs/fs_pin.c
@@ -54,17 +54,17 @@ EXPORT_SYMBOL_GPL(pin_insert);
* @m: the vfsmount whose superblock to monitor
*
* Registers @pin on the superblock's s_pins list only. Callbacks arrive
- * only from group_pin_kill() (invoked during remount read-only), not
- * from mnt_pin_kill() (invoked during mount namespace teardown).
+ * from group_pin_kill(), invoked during both remount read-only and mount
+ * teardown. Unlike pin_insert(), the pin is not added to the per-mount
+ * mnt_pins list, so mnt_pin_kill() does not invoke the callback.
*
* Use this instead of pin_insert() when mnt_pin_kill() callbacks would
- * execute in problematic locking contexts. Because mnt_pin_kill() runs
- * during cleanup_mnt(), callbacks cannot acquire locks also taken during
- * mount table operations without risking AB-BA deadlock.
+ * execute in problematic locking contexts. Callbacks registered via this
+ * function run from group_pin_kill() instead, which may execute under
+ * different locking conditions.
*
* After insertion, check SB_ACTIVE to detect racing unmounts. If clear,
- * call pin_remove() and abort. Normal unmount cleanup then occurs through
- * subsystem-specific shutdown paths without pin callback involvement.
+ * call pin_remove() and abort.
*
* The callback must call pin_remove() before returning. Callbacks execute
* with the RCU read lock held.
diff --git a/fs/namespace.c b/fs/namespace.c
index c58674a20cad..a887d45636f5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1309,6 +1309,8 @@ static void cleanup_mnt(struct mount *mnt)
WARN_ON(mnt_get_writers(mnt));
if (unlikely(mnt->mnt_pins.first))
mnt_pin_kill(mnt);
+ if (unlikely(!hlist_empty(&mnt->mnt.mnt_sb->s_pins)))
+ group_pin_kill(&mnt->mnt.mnt_sb->s_pins);
hlist_for_each_entry_safe(m, p, &mnt->mnt_stuck_children, mnt_umount) {
hlist_del(&m->mnt_umount);
mntput(&m->mnt);
--
2.52.0
next prev parent reply other threads:[~2026-01-08 0:40 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-08 0:40 [PATCH v2 0/6] Automatic NFSv4 state revocation on filesystem unmount Chuck Lever
2026-01-08 0:40 ` [PATCH v2 1/6] nfsd: cancel async COPY operations when admin revokes filesystem state Chuck Lever
2026-01-08 0:40 ` [PATCH v2 2/6] fs: export pin_insert and pin_remove for modular filesystems Chuck Lever
2026-01-08 0:40 ` [PATCH v2 3/6] fs: add pin_insert_sb() for superblock-only pins Chuck Lever
2026-01-08 0:40 ` Chuck Lever [this message]
2026-01-09 8:38 ` [PATCH v2 4/6] fs: invoke group_pin_kill() during mount teardown NeilBrown
2026-01-09 16:04 ` Chuck Lever
2026-01-10 16:49 ` Al Viro
2026-01-10 20:07 ` Chuck Lever
2026-01-10 21:52 ` NeilBrown
2026-01-10 22:08 ` Al Viro
2026-01-10 22:31 ` Chuck Lever
2026-01-08 0:40 ` [PATCH v2 5/6] nfsd: revoke NFSv4 state when filesystem is unmounted Chuck Lever
2026-01-09 9:06 ` NeilBrown
2026-01-08 0:40 ` [PATCH v2 6/6] nfsd: close cached files on filesystem unmount Chuck Lever
2026-01-09 16:25 ` [PATCH v2 0/6] Automatic NFSv4 state revocation " Jeff Layton
2026-01-12 9:16 ` Christian Brauner
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=20260108004016.3907158-5-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=dai.ngo@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@ownmail.net \
--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