public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Christian Brauner <brauner@kernel.org>, linux-fsdevel@vger.kernel.org
Subject: [PATCH v2 05/10] fsnotify: do not report mount events with fsnotify()
Date: Fri, 24 Apr 2026 19:04:58 +0200	[thread overview]
Message-ID: <20260424170503.2096847-6-amir73il@gmail.com> (raw)
In-Reply-To: <20260424170503.2096847-1-amir73il@gmail.com>

fsnotify() is now used to report events to both filesystem watchers and
(mnt) namepsace watchers, but those two distinct event categories can
never be sent to the same group.

Split out send_to_ns_groups() which only looks for interested mntns object
marks from fsnotify() which only looks for interested filesystem object
marks and let fsnotify_mnt() call send_to_ns_groups().

The intention is that send_to_ns_groups() will also be used to report
namespace events to watchers of userns object.

Gate the common code that is checking fs events with filesystem
group type check.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fsnotify.c | 87 +++++++++++++++++++++++++++++++-------------
 1 file changed, 62 insertions(+), 25 deletions(-)

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 429ce614233ce..db79f51d8109c 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -330,7 +330,8 @@ static int fsnotify_handle_event(struct fsnotify_group *group, __u32 mask,
 
 static int send_to_group(__u32 mask, const void *data, int data_type,
 			 struct inode *dir, const struct qstr *file_name,
-			 u32 cookie, struct fsnotify_iter_info *iter_info)
+			 u32 cookie, struct fsnotify_iter_info *iter_info,
+			 enum fsnotify_group_type group_type)
 {
 	struct fsnotify_group *group = NULL;
 	__u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);
@@ -344,7 +345,7 @@ static int send_to_group(__u32 mask, const void *data, int data_type,
 		return 0;
 
 	/* clear ignored on inode modification */
-	if (mask & FS_MODIFY) {
+	if (group_type ==  FSNOTIFY_GROUP_TYPE_FS && mask & FS_MODIFY) {
 		fsnotify_foreach_iter_mark_type(iter_info, mark, type) {
 			if (!(mark->flags &
 			      FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
@@ -360,10 +361,13 @@ static int send_to_group(__u32 mask, const void *data, int data_type,
 			fsnotify_effective_ignore_mask(mark, is_dir, type);
 	}
 
-	pr_debug("%s: group=%p mask=%x marks_mask=%x marks_ignore_mask=%x data=%p data_type=%d dir=%p cookie=%d\n",
-		 __func__, group, mask, marks_mask, marks_ignore_mask,
+	pr_debug("%s: group=%p type=%d mask=%x marks_mask=%x marks_ignore_mask=%x data=%p data_type=%d dir=%p cookie=%d\n",
+		 __func__, group, group_type, mask, marks_mask, marks_ignore_mask,
 		 data, data_type, dir, cookie);
 
+	if (WARN_ON_ONCE(group->type != group_type))
+		return 0;
+
 	if (!(test_mask & marks_mask & ~marks_ignore_mask))
 		return 0;
 
@@ -469,6 +473,26 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
 	}
 }
 
+static int send_to_groups(__u32 mask, const void *data, int data_type,
+			  struct inode *dir, const struct qstr *file_name,
+			  u32 cookie, struct fsnotify_iter_info *iter_info,
+			  enum fsnotify_group_type group_type)
+{
+	int ret;
+
+	while (fsnotify_iter_select_report_types(iter_info)) {
+		ret = send_to_group(mask, data, data_type, dir, file_name,
+				    cookie, iter_info, group_type);
+
+		if (ret && group_type == FSNOTIFY_GROUP_TYPE_FS &&
+		    (mask & ALL_FSNOTIFY_PERM_EVENTS))
+			return ret;
+
+		fsnotify_iter_next(iter_info);
+	}
+	return 0;
+}
+
 /*
  * fsnotify - This is the main call to fsnotify.
  *
@@ -494,7 +518,6 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 {
 	const struct path *path = fsnotify_data_path(data, data_type);
 	struct super_block *sb = fsnotify_data_sb(data, data_type);
-	const struct fsnotify_mnt *mnt_data = fsnotify_data_mnt(data, data_type);
 	struct fsnotify_sb_info *sbinfo = sb ? fsnotify_sb_info(sb) : NULL;
 	struct fsnotify_iter_info iter_info = {};
 	struct mount *mnt = NULL;
@@ -535,8 +558,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 	if ((!sbinfo || !sbinfo->sb_marks) &&
 	    (!mnt || !mnt->mnt_fsnotify_marks) &&
 	    (!inode || !inode->i_fsnotify_marks) &&
-	    (!inode2 || !inode2->i_fsnotify_marks) &&
-	    (!mnt_data || !mnt_data->ns->n_fsnotify_marks))
+	    (!inode2 || !inode2->i_fsnotify_marks))
 		return 0;
 
 	if (sb)
@@ -547,8 +569,6 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 		marks_mask |= READ_ONCE(inode->i_fsnotify_mask);
 	if (inode2)
 		marks_mask |= READ_ONCE(inode2->i_fsnotify_mask);
-	if (mnt_data)
-		marks_mask |= READ_ONCE(mnt_data->ns->n_fsnotify_mask);
 
 	/*
 	 * If this is a modify event we may need to clear some ignore masks.
@@ -556,7 +576,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 	 * event in its mask.
 	 * Otherwise, return if none of the marks care about this type of event.
 	 */
-	test_mask = (mask & ALL_FSNOTIFY_EVENTS);
+	test_mask = (mask & FSNOTIFY_EVENTS_ON_FS);
 	if (!(test_mask & marks_mask))
 		return 0;
 
@@ -578,27 +598,15 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 		iter_info.marks[inode2_type] =
 			fsnotify_first_mark(&inode2->i_fsnotify_marks);
 	}
-	if (mnt_data) {
-		iter_info.marks[FSNOTIFY_ITER_TYPE_MNTNS] =
-			fsnotify_first_mark(&mnt_data->ns->n_fsnotify_marks);
-	}
 
 	/*
 	 * We need to merge inode/vfsmount/sb mark lists so that e.g. inode mark
 	 * ignore masks are properly reflected for mount/sb mark notifications.
 	 * That's why this traversal is so complicated...
 	 */
-	while (fsnotify_iter_select_report_types(&iter_info)) {
-		ret = send_to_group(mask, data, data_type, dir, file_name,
-				    cookie, &iter_info);
+	ret = send_to_groups(mask, data, data_type, dir, file_name,
+			     cookie, &iter_info, FSNOTIFY_GROUP_TYPE_FS);
 
-		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
-			goto out;
-
-		fsnotify_iter_next(&iter_info);
-	}
-	ret = 0;
-out:
 	srcu_read_unlock(&fsnotify_mark_srcu, iter_info.srcu_idx);
 
 	return ret;
@@ -691,6 +699,35 @@ int fsnotify_open_perm_and_set_mode(struct file *file)
 }
 #endif
 
+static int send_to_ns_groups(__u32 mask, const void *data, int data_type)
+{
+	const struct fsnotify_mnt *mnt_data = fsnotify_data_mnt(data, data_type);
+	struct fsnotify_iter_info iter_info = {};
+	__u32 test_mask, marks_mask = 0;
+	int ret;
+
+	if (mnt_data)
+		marks_mask |= READ_ONCE(mnt_data->ns->n_fsnotify_mask);
+
+	test_mask = mask & FSNOTIFY_EVENTS_ON_NS;
+	if (!(test_mask & marks_mask))
+		return 0;
+
+	iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
+
+	if (mnt_data) {
+		iter_info.marks[FSNOTIFY_ITER_TYPE_MNTNS] =
+			fsnotify_first_mark(&mnt_data->ns->n_fsnotify_marks);
+	}
+
+	ret = send_to_groups(mask, data, data_type, NULL, NULL, 0, &iter_info,
+			     FSNOTIFY_GROUP_TYPE_NS);
+
+	srcu_read_unlock(&fsnotify_mark_srcu, iter_info.srcu_idx);
+
+	return ret;
+}
+
 void fsnotify_mnt(__u32 mask, struct mnt_namespace *ns, struct vfsmount *mnt)
 {
 	struct fsnotify_mnt data = {
@@ -708,7 +745,7 @@ void fsnotify_mnt(__u32 mask, struct mnt_namespace *ns, struct vfsmount *mnt)
 	if (!ns->n_fsnotify_marks)
 		return;
 
-	fsnotify(mask, &data, FSNOTIFY_EVENT_MNT, NULL, NULL, NULL, 0);
+	send_to_ns_groups(mask, &data, FSNOTIFY_EVENT_MNT);
 }
 
 static __init int fsnotify_init(void)
-- 
2.54.0


  parent reply	other threads:[~2026-04-24 17:05 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-24 17:04 [PATCH v2 00/10] fanotify namespace monitoring Amir Goldstein
2026-04-24 17:04 ` [PATCH v2 01/10] fsnotify: rename fsnotify group flag macros Amir Goldstein
2026-04-24 17:04 ` [PATCH v2 02/10] fsnotify: introduce fsnotify group types Amir Goldstein
2026-04-24 17:04 ` [PATCH v2 03/10] fsnotify: separate the events bitmask macros by group type Amir Goldstein
2026-04-24 17:04 ` [PATCH v2 04/10] fanotify: test event->type instead of event mask when possible Amir Goldstein
2026-04-24 17:04 ` Amir Goldstein [this message]
2026-04-24 17:04 ` [PATCH v2 06/10] fanotify: gate fs event classification by group type Amir Goldstein
2026-04-24 17:05 ` [PATCH v2 07/10] fanotify: gate fs events checks in fanotify_mark() " Amir Goldstein
2026-04-24 17:05 ` [PATCH v2 08/10] fanotify: add support for watching the namespaces tree Amir Goldstein
2026-04-24 17:05 ` [PATCH v2 09/10] selftests/filesystems: create fanotify test dir Amir Goldstein
2026-04-24 17:05 ` [PATCH v2 10/10] selftests/filesystems: add fanotify namespace notifications test Amir Goldstein

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=20260424170503.2096847-6-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=brauner@kernel.org \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    /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