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 v3 04/13] fsnotify: generalize iteration of marks by object type
Date: Fri, 20 Apr 2018 16:10:52 -0700	[thread overview]
Message-ID: <1524265861-6316-5-git-send-email-amir73il@gmail.com> (raw)
In-Reply-To: <1524265861-6316-1-git-send-email-amir73il@gmail.com>

Make some code that handles marks of object types inode and vfsmount
generic, so it can handle other object types.

Introduce fsnotify_foreach_obj_type macro to iterate marks by object type
and fsnotify_iter_{should|set}_report_type macros to set/test report_mask.

This is going to be used for adding mark of another object type
(super block mark).

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fsnotify.c             | 52 +++++++++++++++++++++-------------------
 fs/notify/inotify/inotify_user.c |  8 +++----
 fs/notify/mark.c                 | 23 +++++++++++-------
 include/linux/fsnotify_backend.h | 28 +++++++++++++++++++---
 4 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 98e91037b11d..bc9a51480156 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -269,25 +269,29 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark)
 static unsigned int fsnotify_iter_select_report_types(
 		struct fsnotify_iter_info *iter_info)
 {
-	struct fsnotify_mark *inode_mark = iter_info->inode_mark;
-	struct fsnotify_mark *vfsmount_mark = iter_info->vfsmount_mark;
-	int cmp;
+	struct fsnotify_group *max_prio_group = NULL;
+	struct fsnotify_mark *mark;
+	int type;
+
+	/* Choose max prio group among groups of all queue heads */
+	fsnotify_foreach_obj_type(type) {
+		mark = iter_info->marks[type];
+		if (mark &&
+		    fsnotify_compare_groups(max_prio_group, mark->group) > 0)
+			max_prio_group = mark->group;
+	}
 
-	if (!inode_mark && !vfsmount_mark)
+	if (!max_prio_group)
 		return 0;
 
-	if (inode_mark && vfsmount_mark) {
-		cmp = fsnotify_compare_groups(inode_mark->group,
-					      vfsmount_mark->group);
-	} else {
-		cmp = inode_mark ? -1 : 1;
-	}
-
+	/* Set the report mask for marks from same group as max prio group */
 	iter_info->report_mask = 0;
-	if (cmp <= 0)
-		iter_info->report_mask |= FSNOTIFY_OBJ_TYPE_INODE_FL;
-	if (cmp >= 0)
-		iter_info->report_mask |= FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL;
+	fsnotify_foreach_obj_type(type) {
+		mark = iter_info->marks[type];
+		if (mark &&
+		    fsnotify_compare_groups(max_prio_group, mark->group) == 0)
+			fsnotify_iter_set_report_type(iter_info, type);
+	}
 
 	return iter_info->report_mask;
 }
@@ -298,13 +302,13 @@ static unsigned int fsnotify_iter_select_report_types(
  */
 static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
 {
-	if (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL)
-		iter_info->inode_mark =
-			fsnotify_next_mark(iter_info->inode_mark);
+	int type;
 
-	if (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL)
-		iter_info->vfsmount_mark =
-			fsnotify_next_mark(iter_info->vfsmount_mark);
+	fsnotify_foreach_obj_type(type) {
+		if (fsnotify_iter_should_report_type(iter_info, type))
+			iter_info->marks[type] =
+				fsnotify_next_mark(iter_info->marks[type]);
+	}
 }
 
 /*
@@ -351,15 +355,15 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 
 	if ((mask & FS_MODIFY) ||
 	    (test_mask & to_tell->i_fsnotify_mask)) {
-		iter_info.inode_mark =
+		iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
 			fsnotify_first_mark(&to_tell->i_fsnotify_marks);
 	}
 
 	if (mnt && ((mask & FS_MODIFY) ||
 		    (test_mask & mnt->mnt_fsnotify_mask))) {
-		iter_info.inode_mark =
+		iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
 			fsnotify_first_mark(&to_tell->i_fsnotify_marks);
-		iter_info.vfsmount_mark =
+		iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] =
 			fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
 	}
 
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 22a3d0471fee..6a408ab3169d 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -485,10 +485,10 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
 				    struct fsnotify_group *group)
 {
 	struct inotify_inode_mark *i_mark;
-	struct fsnotify_iter_info iter_info = {
-		.inode_mark = fsn_mark,
-		.report_mask = FSNOTIFY_OBJ_TYPE_INODE_FL,
-	};
+	struct fsnotify_iter_info iter_info = { };
+
+	fsnotify_iter_set_report_type_mark(&iter_info, FSNOTIFY_OBJ_TYPE_INODE,
+					   fsn_mark);
 
 	/* Queue ignore event for the watch */
 	inotify_handle_event(group, NULL, FS_IN_IGNORED, NULL,
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index ef44808b28ca..61f4c5fa34c7 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -294,12 +294,12 @@ static void fsnotify_put_mark_wake(struct fsnotify_mark *mark)
 
 bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info)
 {
-	/* This can fail if mark is being removed */
-	if (!fsnotify_get_mark_safe(iter_info->inode_mark))
-		return false;
-	if (!fsnotify_get_mark_safe(iter_info->vfsmount_mark)) {
-		fsnotify_put_mark_wake(iter_info->inode_mark);
-		return false;
+	int type;
+
+	fsnotify_foreach_obj_type(type) {
+		/* This can fail if mark is being removed */
+		if (!fsnotify_get_mark_safe(iter_info->marks[type]))
+			goto fail;
 	}
 
 	/*
@@ -310,13 +310,20 @@ bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info)
 	srcu_read_unlock(&fsnotify_mark_srcu, iter_info->srcu_idx);
 
 	return true;
+
+fail:
+	for (type--; type >= 0; type--)
+		fsnotify_put_mark_wake(iter_info->marks[type]);
+	return false;
 }
 
 void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info)
 {
+	int type;
+
 	iter_info->srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
-	fsnotify_put_mark_wake(iter_info->inode_mark);
-	fsnotify_put_mark_wake(iter_info->vfsmount_mark);
+	fsnotify_foreach_obj_type(type)
+		fsnotify_put_mark_wake(iter_info->marks[type]);
 }
 
 /*
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 9da5edf4ac0f..763423bfa3d6 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -211,23 +211,45 @@ enum fsnotify_obj_type {
 #define FSNOTIFY_OBJ_ALL_TYPES_MASK	((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
 
 struct fsnotify_iter_info {
-	struct fsnotify_mark *inode_mark;
-	struct fsnotify_mark *vfsmount_mark;
+	struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT];
 	unsigned int report_mask;
 	int srcu_idx;
 };
 
+static inline bool fsnotify_iter_should_report_type(
+		struct fsnotify_iter_info *iter_info, int type)
+{
+	return (iter_info->report_mask & (1U << type));
+}
+
+static inline void fsnotify_iter_set_report_type(
+		struct fsnotify_iter_info *iter_info, int type)
+{
+	iter_info->report_mask |= (1U << type);
+}
+
+static inline void fsnotify_iter_set_report_type_mark(
+		struct fsnotify_iter_info *iter_info, int type,
+		struct fsnotify_mark *mark)
+{
+	iter_info->marks[type] = mark;
+	iter_info->report_mask |= (1U << type);
+}
+
 #define FSNOTIFY_ITER_FUNCS(name, NAME) \
 static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \
 		struct fsnotify_iter_info *iter_info) \
 { \
 	return (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_##NAME##_FL) ? \
-		iter_info->name##_mark : NULL; \
+		iter_info->marks[FSNOTIFY_OBJ_TYPE_##NAME] : NULL; \
 }
 
 FSNOTIFY_ITER_FUNCS(inode, INODE)
 FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
 
+#define fsnotify_foreach_obj_type(type) \
+	for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++)
+
 /*
  * Inode / vfsmount point to this structure which tracks all marks attached to
  * the inode / vfsmount. The reference to inode / vfsmount is held by this
-- 
2.7.4

  parent reply	other threads:[~2018-04-20 23:09 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 01/13] fsnotify: use type id to identify connector object type Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 02/13] fsnotify: remove redundant arguments to handle_event() Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 03/13] fsnotify: introduce marks iteration helpers Amir Goldstein
2018-04-20 23:10 ` Amir Goldstein [this message]
2018-04-20 23:10 ` [PATCH v3 05/13] fsnotify: generalize send_to_group() Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 06/13] fanotify: generalize fanotify_should_send_event() Amir Goldstein
2018-05-18 10:47   ` Jan Kara
2018-04-20 23:10 ` [PATCH v3 07/13] fsnotify: add fsnotify_add_inode_mark() wrappers Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 08/13] fsnotify: introduce prototype struct fsnotify_obj Amir Goldstein
2018-05-18 12:02   ` Jan Kara
2018-04-20 23:10 ` [PATCH v3 09/13] fsnotify: pass fsnotify_obj instead of **connp argument Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 10/13] fsnotify: pass object and object type to fsnotify_add_mark() Amir Goldstein
2018-04-20 23:10 ` [PATCH v3 11/13] fsnotify: add fsnotify_connector_inode() wrapper Amir Goldstein
2018-05-18 12:48   ` Jan Kara
2018-04-20 23:11 ` [PATCH v3 12/13] fsnotify: let connector point to abstract fsnotify_obj Amir Goldstein
2018-04-20 23:11 ` [PATCH v3 13/13] fanotify: factor out helpers to add/remove mark Amir Goldstein
2018-05-18 13:09 ` [PATCH v3 00/13] Preparing for fanotify super block marks 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=1524265861-6316-5-git-send-email-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).