public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
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 v3 1/3] fs: add umount notifier chain for filesystem unmount notification
Date: Tue, 24 Feb 2026 11:39:06 -0500	[thread overview]
Message-ID: <20260224163908.44060-2-cel@kernel.org> (raw)
In-Reply-To: <20260224163908.44060-1-cel@kernel.org>

From: Chuck Lever <chuck.lever@oracle.com>

Kernel subsystems occasionally need notification when a filesystem
is unmounted. Until now, the only mechanism available is the fs_pin
infrastructure, which has limited adoption (only BSD process
accounting uses it) and VFS maintainers consider it deprecated.

Add an SRCU notifier chain that fires during mount teardown,
following the pattern established by lease_notifier_chain in
fs/locks.c. The notifier fires after processing stuck children but
before fsnotify_vfsmount_delete(), at which point SB_ACTIVE is
still set and the superblock remains fully accessible.

The SRCU notifier type is chosen because:
 - Unmount is relatively infrequent, so the overhead of SRCU
   registration and unregistration is acceptable
 - Callbacks run in process context and may sleep
 - No cache bounces occur during chain traversal

NFSD requires this mechanism to revoke NFSv4 state (opens, locks,
delegations) and release cached file handles when a filesystem is
unmounted, avoiding EBUSY errors that occur when client state pins
the mount.

Suggested-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/namespace.c        | 69 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/mount.h |  4 +++
 2 files changed, 73 insertions(+)

diff --git a/fs/namespace.c b/fs/namespace.c
index ebe19ded293a..269e007e9312 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -34,6 +34,7 @@
 #include <linux/mnt_idmapping.h>
 #include <linux/pidfs.h>
 #include <linux/nstree.h>
+#include <linux/notifier.h>
 
 #include "pnode.h"
 #include "internal.h"
@@ -73,6 +74,70 @@ static u64 event;
 static DEFINE_XARRAY_FLAGS(mnt_id_xa, XA_FLAGS_ALLOC);
 static DEFINE_IDA(mnt_group_ida);
 
+/*
+ * Kernel subsystems can register to be notified when a filesystem is
+ * unmounted. This is used by (e.g.) nfsd to revoke state associated
+ * with files on the filesystem being unmounted.
+ */
+static struct srcu_notifier_head umount_notifier_chain;
+
+/**
+ * umount_register_notifier - register for unmount notifications
+ * @nb: notifier_block to register
+ *
+ * Registers a notifier to be called when any filesystem is
+ * unmounted. The callback is invoked after stuck children are
+ * processed but before fsnotify_vfsmount_delete(), while SB_ACTIVE
+ * is still set and the superblock remains fully accessible.
+ *
+ * Callback signature:
+ *   int (*callback)(struct notifier_block *nb,
+ *                   unsigned long val, void *data)
+ *
+ *   @val:  always 0 (reserved for future extension)
+ *   @data: struct super_block * for the unmounting filesystem
+ *
+ * Callbacks run in process context and may sleep. Return
+ * NOTIFY_DONE from the callback; return values are ignored and
+ * cannot prevent unmount. Callbacks must handle their own error
+ * recovery internally.
+ *
+ * The notification fires once per mount instance. Bind mounts of
+ * the same filesystem trigger multiple callbacks with the same
+ * super_block pointer; callbacks must handle duplicate
+ * notifications idempotently.
+ *
+ * The super_block pointer is valid only for the duration of the
+ * callback. Callbacks must not retain this pointer for
+ * asynchronous use; to access the filesystem after the callback
+ * returns, acquire a separate reference (e.g., via an open file)
+ * during callback execution.
+ *
+ * Returns: 0 on success, negative error code on failure.
+ */
+int umount_register_notifier(struct notifier_block *nb)
+{
+	return srcu_notifier_chain_register(&umount_notifier_chain, nb);
+}
+EXPORT_SYMBOL_GPL(umount_register_notifier);
+
+/**
+ * umount_unregister_notifier - unregister an unmount notifier
+ * @nb: notifier_block to unregister
+ *
+ * Unregisters a previously registered notifier. This function may
+ * block due to SRCU synchronization.
+ *
+ * Must not be called from within a notifier callback; doing so
+ * causes deadlock. Must be called before module unload if the
+ * notifier_block resides in module memory.
+ */
+void umount_unregister_notifier(struct notifier_block *nb)
+{
+	srcu_notifier_chain_unregister(&umount_notifier_chain, nb);
+}
+EXPORT_SYMBOL_GPL(umount_unregister_notifier);
+
 /* Don't allow confusion with old 32bit mount ID */
 #define MNT_UNIQUE_ID_OFFSET (1ULL << 31)
 static u64 mnt_id_ctr = MNT_UNIQUE_ID_OFFSET;
@@ -1307,6 +1372,8 @@ static void cleanup_mnt(struct mount *mnt)
 		hlist_del(&m->mnt_umount);
 		mntput(&m->mnt);
 	}
+	/* Notify registrants before superblock deactivation */
+	srcu_notifier_call_chain(&umount_notifier_chain, 0, mnt->mnt.mnt_sb);
 	fsnotify_vfsmount_delete(&mnt->mnt);
 	dput(mnt->mnt.mnt_root);
 	deactivate_super(mnt->mnt.mnt_sb);
@@ -6189,6 +6256,8 @@ void __init mnt_init(void)
 {
 	int err;
 
+	srcu_init_notifier_head(&umount_notifier_chain);
+
 	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
 			0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL);
 
diff --git a/include/linux/mount.h b/include/linux/mount.h
index acfe7ef86a1b..9a46ab40dffd 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -21,6 +21,7 @@ struct file_system_type;
 struct fs_context;
 struct file;
 struct path;
+struct notifier_block;
 
 enum mount_flags {
 	MNT_NOSUID	= 0x01,
@@ -109,4 +110,7 @@ extern void kern_unmount_array(struct vfsmount *mnt[], unsigned int num);
 
 extern int cifs_root_data(char **dev, char **opts);
 
+int umount_register_notifier(struct notifier_block *nb);
+void umount_unregister_notifier(struct notifier_block *nb);
+
 #endif /* _LINUX_MOUNT_H */
-- 
2.53.0


  reply	other threads:[~2026-02-24 16:39 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-24 16:39 [PATCH v3 0/3] Automatic NFSv4 state revocation on filesystem unmount Chuck Lever
2026-02-24 16:39 ` Chuck Lever [this message]
2026-02-26  8:48   ` [PATCH v3 1/3] fs: add umount notifier chain for filesystem unmount notification Christian Brauner
2026-02-26 10:52     ` Amir Goldstein
2026-02-26 13:27       ` Chuck Lever
2026-02-26 13:32         ` Jan Kara
2026-02-27 15:10           ` Chuck Lever
2026-03-01 14:37             ` Amir Goldstein
2026-03-01 17:20               ` Chuck Lever
2026-03-01 18:09                 ` Amir Goldstein
2026-03-01 18:19                   ` Chuck Lever
2026-03-02  4:09                     ` NeilBrown
2026-03-02 13:57                       ` Chuck Lever
2026-03-02 15:26                         ` Jan Kara
2026-03-02 17:10                           ` Jeff Layton
2026-03-02 17:37                             ` Jan Kara
2026-03-02 17:53                               ` Jeff Layton
2026-03-04 13:17                                 ` Christian Brauner
2026-03-04 15:15                                   ` Chuck Lever
2026-03-02 20:46                               ` NeilBrown
2026-03-02 17:01                         ` Chuck Lever
2026-03-02 20:36                           ` NeilBrown
2026-03-03 20:02                             ` Chuck Lever
2026-03-03 21:23                               ` NeilBrown
2026-03-03 22:50                                 ` Chuck Lever
2026-03-04  1:01                                   ` NeilBrown
2026-03-04 13:05                             ` Christian Brauner
2026-02-24 16:39 ` [PATCH v3 2/3] nfsd: revoke NFSv4 state when filesystem is unmounted Chuck Lever
2026-02-24 16:39 ` [PATCH v3 3/3] nfsd: close cached files on filesystem unmount Chuck Lever
2026-02-24 17:14 ` [PATCH v3 0/3] Automatic NFSv4 state revocation " 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=20260224163908.44060-2-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