linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH 7/7] fsnotify: optimize merging of marks with no ignored masks
Date: Wed,  2 Dec 2020 14:07:13 +0200	[thread overview]
Message-ID: <20201202120713.702387-8-amir73il@gmail.com> (raw)
In-Reply-To: <20201202120713.702387-1-amir73il@gmail.com>

fsnotify() tries to merge marks on all object types (sb, mount, inode)
even if the object's mask shows no interest in the specific event type.

This is done for the case that the object has marks with the event type
in their ignored mask, but the common case is that an object does not
have any marks with ignored mask.

Set a bit in object's fsnotify mask during fsnotify_recalc_mask() to
indicate the existence of any marks with ignored masks.

Instead of merging marks of all object types, only merge marks from
objects that either showed interest in the specific event type or have
any marks with ignored mask.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c    |  5 +++++
 fs/notify/fsnotify.c             | 18 ++++++++++++------
 include/linux/fsnotify_backend.h | 12 ++++++++++--
 3 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 8655a1e7c6a6..4441de2fba11 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -677,6 +677,11 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
 	BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM);
 
 	BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 19);
+	/*
+	 * FS_HAS_IGNORED_MASK bit is reserved for internal use so should
+	 * not be exposed to fanotify uapi.
+	 */
+	BUILD_BUG_ON(ALL_FANOTIFY_EVENT_BITS & FS_HAS_IGNORED_MASK);
 
 	mask = fanotify_group_event_mask(group, iter_info, mask, data,
 					 data_type, dir);
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 9a26207d1b5d..6b3a828db6aa 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -500,7 +500,6 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 	if (parent)
 		marks_mask |= parent->i_fsnotify_mask;
 
-
 	/*
 	 * If this is a modify event we may need to clear some ignored masks.
 	 * In that case, the object with ignored masks will have the FS_MODIFY
@@ -521,17 +520,24 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir,
 	BUILD_BUG_ON(FSNOTIFY_OBJ_TYPE_VFSMOUNT != (int)FSNOTIFY_ITER_TYPE_VFSMOUNT);
 	BUILD_BUG_ON(FSNOTIFY_OBJ_TYPE_SB != (int)FSNOTIFY_ITER_TYPE_SB);
 
-	iter_info.marks[FSNOTIFY_ITER_TYPE_SB] =
-		fsnotify_first_mark(&sb->s_fsnotify_marks);
-	if (mnt) {
+	/*
+	 * Consider only marks that care about this type of event and marks with
+	 * an ignored mask.
+	 */
+	test_mask |= FS_HAS_IGNORED_MASK;
+	if (test_mask && sb->s_fsnotify_mask) {
+		iter_info.marks[FSNOTIFY_ITER_TYPE_SB] =
+			fsnotify_first_mark(&sb->s_fsnotify_marks);
+	}
+	if (mnt && (test_mask & mnt->mnt_fsnotify_mask)) {
 		iter_info.marks[FSNOTIFY_ITER_TYPE_VFSMOUNT] =
 			fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
 	}
-	if (inode) {
+	if (inode && (test_mask & inode->i_fsnotify_mask)) {
 		iter_info.marks[FSNOTIFY_ITER_TYPE_INODE] =
 			fsnotify_first_mark(&inode->i_fsnotify_marks);
 	}
-	if (parent) {
+	if (parent && (test_mask & parent->i_fsnotify_mask)) {
 		iter_info.marks[FSNOTIFY_ITER_TYPE_PARENT] =
 			fsnotify_first_mark(&parent->i_fsnotify_marks);
 	}
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 046fcfb88492..0615ca2fddf9 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -61,6 +61,14 @@
 #define FS_ISDIR		0x40000000	/* event occurred against dir */
 #define FS_IN_ONESHOT		0x80000000	/* only send event once */
 
+/*
+ * Overload FS_IN_ONESHOT is set only on inotify marks, which never set the
+ * ignored mask and is not relevant in the object's cumulative mask.
+ * Overload the flag to indicate the existence of marks on the object that
+ * have an ignored mask.
+ */
+#define FS_HAS_IGNORED_MASK	FS_IN_ONESHOT
+
 #define FS_MOVE			(FS_MOVED_FROM | FS_MOVED_TO)
 
 /*
@@ -522,13 +530,13 @@ static inline __u32 fsnotify_calc_mask(struct fsnotify_mark *mark)
 	__u32 mask = mark->mask;
 
 	if (!mark->ignored_mask)
-		return mask;
+		return mask & ~FS_HAS_IGNORED_MASK;
 
 	/* Interest in FS_MODIFY may be needed for clearing ignored mask */
 	if (!(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
 		mask |= FS_MODIFY;
 
-	return mask;
+	return mask | FS_HAS_IGNORED_MASK;
 }
 
 /* Get mask of events for a list of marks */
-- 
2.25.1


  parent reply	other threads:[~2020-12-02 12:09 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-02 12:07 [PATCH 0/7] fsnotify fixes and cleanups Amir Goldstein
2020-12-02 12:07 ` [PATCH 1/7] fsnotify: generalize handle_inode_event() Amir Goldstein
2020-12-03  9:51   ` Jan Kara
2020-12-03 10:41     ` Amir Goldstein
2020-12-03 12:02       ` Jan Kara
2020-12-02 12:07 ` [PATCH 2/7] inotify: convert to handle_inode_event() interface Amir Goldstein
2020-12-03  9:55   ` Jan Kara
2020-12-03 10:45     ` Amir Goldstein
2020-12-03 12:37       ` Jan Kara
2020-12-03 12:43         ` Amir Goldstein
2020-12-02 12:07 ` [PATCH 3/7] fsnotify: fix events reported to watching parent and child Amir Goldstein
2020-12-03 11:53   ` Jan Kara
2020-12-03 12:58     ` Amir Goldstein
2020-12-03 14:24       ` Jan Kara
2020-12-02 12:07 ` [PATCH 4/7] fsnotify: clarify object type argument Amir Goldstein
2020-12-02 12:07 ` [PATCH 5/7] fsnotify: separate mark iterator type from object type enum Amir Goldstein
2020-12-02 12:07 ` [PATCH 6/7] fsnotify: optimize FS_MODIFY events with no ignored masks Amir Goldstein
2020-12-02 12:07 ` Amir Goldstein [this message]
2020-12-03 10:35   ` [PATCH 7/7] fsnotify: optimize merging of marks " Jan Kara
2020-12-03 10:56     ` Amir Goldstein
2020-12-03 14:52 ` [PATCH 0/7] fsnotify fixes and cleanups Jan Kara

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=20201202120713.702387-8-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --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;
as well as URLs for NNTP newsgroup(s).