linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/13] Preparing for fanotify super block marks
@ 2018-04-20 23:10 Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 01/13] fsnotify: use type id to identify connector object type Amir Goldstein
                   ` (13 more replies)
  0 siblings, 14 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Jan,

Per your request, here is the prep series for super block mark, with
all review comments addressed and rebased on your for_next branch.

For those interested in the super block marks work, here are the
patches [1] and ltp tests [2]. I hope we can iron out any remaining
concerns during LSF/MM.

Thanks,
Amir.

[1] https://github.com/amir73il/linux/commits/fanotify_sb
[2] https://github.com/amir73il/ltp/commits/fanotify_sb

Changes since v2:
- Some fix patches already merged
- Remove patches that implement super block mark
- Refernce abstract fsnotify_obj from connector
- Address Jan's review comments on type iteration helpers
- Better names for helpers and report_mask

Amir Goldstein (13):
  fsnotify: use type id to identify connector object type
  fsnotify: remove redundant arguments to handle_event()
  fsnotify: introduce marks iteration helpers
  fsnotify: generalize iteration of marks by object type
  fsnotify: generalize send_to_group()
  fanotify: generalize fanotify_should_send_event()
  fsnotify: add fsnotify_add_inode_mark() wrappers
  fsnotify: introduce prototype struct fsnotify_obj
  fsnotify: pass fsnotify_obj instead of **connp argument
  fsnotify: pass object and object type to fsnotify_add_mark()
  fsnotify: add fsnotify_connector_inode() wrapper
  fsnotify: let connector point to abstract fsnotify_obj
  fanotify: factor out helpers to add/remove mark

 fs/inode.c                           |   2 +-
 fs/mount.h                           |  11 ++-
 fs/notify/dnotify/dnotify.c          |  16 ++--
 fs/notify/fanotify/fanotify.c        |  48 +++++------
 fs/notify/fanotify/fanotify_user.c   |  98 ++++++++-------------
 fs/notify/fdinfo.c                   |  12 +--
 fs/notify/fsnotify.c                 | 160 ++++++++++++++++++++---------------
 fs/notify/fsnotify.h                 |  14 +--
 fs/notify/group.c                    |   2 +-
 fs/notify/inotify/inotify.h          |   2 -
 fs/notify/inotify/inotify_fsnotify.c |   6 +-
 fs/notify/inotify/inotify_user.c     |  16 ++--
 fs/notify/mark.c                     | 140 ++++++++++++++----------------
 include/linux/fs.h                   |   6 +-
 include/linux/fsnotify_backend.h     | 120 +++++++++++++++++++++-----
 include/linux/fsnotify_obj.h         |  14 +++
 kernel/audit_fsnotify.c              |   5 +-
 kernel/audit_tree.c                  |  20 ++---
 kernel/audit_watch.c                 |   7 +-
 kernel/auditsc.c                     |   4 +-
 20 files changed, 392 insertions(+), 311 deletions(-)
 create mode 100644 include/linux/fsnotify_obj.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 01/13] fsnotify: use type id to identify connector object type
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
@ 2018-04-20 23:10 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 02/13] fsnotify: remove redundant arguments to handle_event() Amir Goldstein
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

An fsnotify_mark_connector is referencing a single type of object
(either inode or vfsmount). Instead of storing a type mask in
connector->flags, store a single type id in connector->type to
identify the type of object.

When a connector object is detached from the object, its type is set
to FSNOTIFY_OBJ_TYPE_DETACHED and this object is not going to be
reused.

The function fsnotify_clear_marks_by_group() is the only place where
type mask was used, so use type flags instead of type id to this
function.

This change is going to be more convenient when adding a new object
type (super block).

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fdinfo.c               |  6 +++---
 fs/notify/group.c                |  2 +-
 fs/notify/mark.c                 | 29 ++++++++++++++---------------
 include/linux/fsnotify_backend.h | 21 ++++++++++++++-------
 4 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index d478629c728b..10aac1942c9f 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -77,7 +77,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 	struct inotify_inode_mark *inode_mark;
 	struct inode *inode;
 
-	if (!(mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE))
+	if (mark->connector->type != FSNOTIFY_OBJ_TYPE_INODE)
 		return;
 
 	inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
@@ -116,7 +116,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 	if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)
 		mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
 
-	if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_INODE) {
+	if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
 		inode = igrab(mark->connector->inode);
 		if (!inode)
 			return;
@@ -126,7 +126,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 		show_mark_fhandle(m, inode);
 		seq_putc(m, '\n');
 		iput(inode);
-	} else if (mark->connector->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
+	} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
 		struct mount *mnt = real_mount(mark->connector->mnt);
 
 		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
diff --git a/fs/notify/group.c b/fs/notify/group.c
index b7a4b6a69efa..aa5468f23e45 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -67,7 +67,7 @@ void fsnotify_destroy_group(struct fsnotify_group *group)
 	fsnotify_group_stop_queueing(group);
 
 	/* Clear all marks for this group and queue them for destruction */
-	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES);
+	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_ALL_TYPES_MASK);
 
 	/*
 	 * Some marks can still be pinned when waiting for response from
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index e9191b416434..ef44808b28ca 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -119,9 +119,9 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
 		if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
 			new_mask |= mark->mask;
 	}
-	if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE)
+	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
 		conn->inode->i_fsnotify_mask = new_mask;
-	else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT)
+	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
 		real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask;
 }
 
@@ -139,7 +139,7 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
 	spin_lock(&conn->lock);
 	__fsnotify_recalc_mask(conn);
 	spin_unlock(&conn->lock);
-	if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE)
+	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
 		__fsnotify_update_child_dentry_flags(conn->inode);
 }
 
@@ -166,18 +166,18 @@ static struct inode *fsnotify_detach_connector_from_object(
 {
 	struct inode *inode = NULL;
 
-	if (conn->flags & FSNOTIFY_OBJ_TYPE_INODE) {
+	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
 		inode = conn->inode;
 		rcu_assign_pointer(inode->i_fsnotify_marks, NULL);
 		inode->i_fsnotify_mask = 0;
 		conn->inode = NULL;
-		conn->flags &= ~FSNOTIFY_OBJ_TYPE_INODE;
-	} else if (conn->flags & FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
+		conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
+	} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
 		rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks,
 				   NULL);
 		real_mount(conn->mnt)->mnt_fsnotify_mask = 0;
 		conn->mnt = NULL;
-		conn->flags &= ~FSNOTIFY_OBJ_TYPE_VFSMOUNT;
+		conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
 	}
 
 	return inode;
@@ -442,10 +442,10 @@ static int fsnotify_attach_connector_to_object(
 	spin_lock_init(&conn->lock);
 	INIT_HLIST_HEAD(&conn->list);
 	if (inode) {
-		conn->flags = FSNOTIFY_OBJ_TYPE_INODE;
+		conn->type = FSNOTIFY_OBJ_TYPE_INODE;
 		conn->inode = igrab(inode);
 	} else {
-		conn->flags = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
+		conn->type = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
 		conn->mnt = mnt;
 	}
 	/*
@@ -479,8 +479,7 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector(
 	if (!conn)
 		goto out;
 	spin_lock(&conn->lock);
-	if (!(conn->flags & (FSNOTIFY_OBJ_TYPE_INODE |
-			     FSNOTIFY_OBJ_TYPE_VFSMOUNT))) {
+	if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED) {
 		spin_unlock(&conn->lock);
 		srcu_read_unlock(&fsnotify_mark_srcu, idx);
 		return NULL;
@@ -646,16 +645,16 @@ struct fsnotify_mark *fsnotify_find_mark(
 	return NULL;
 }
 
-/* Clear any marks in a group with given type */
+/* Clear any marks in a group with given type mask */
 void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
-				   unsigned int type)
+				   unsigned int type_mask)
 {
 	struct fsnotify_mark *lmark, *mark;
 	LIST_HEAD(to_free);
 	struct list_head *head = &to_free;
 
 	/* Skip selection step if we want to clear all marks. */
-	if (type == FSNOTIFY_OBJ_ALL_TYPES) {
+	if (type_mask == FSNOTIFY_OBJ_ALL_TYPES_MASK) {
 		head = &group->marks_list;
 		goto clear;
 	}
@@ -670,7 +669,7 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
 	 */
 	mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
 	list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
-		if (mark->connector->flags & type)
+		if ((1U << mark->connector->type) & type_mask)
 			list_move(&mark->g_list, &to_free);
 	}
 	mutex_unlock(&group->mark_mutex);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index e64c0294f50b..435c94a31c8c 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -201,6 +201,17 @@ struct fsnotify_group {
 #define FSNOTIFY_EVENT_PATH	1
 #define FSNOTIFY_EVENT_INODE	2
 
+enum fsnotify_obj_type {
+	FSNOTIFY_OBJ_TYPE_INODE,
+	FSNOTIFY_OBJ_TYPE_VFSMOUNT,
+	FSNOTIFY_OBJ_TYPE_COUNT,
+	FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
+};
+
+#define FSNOTIFY_OBJ_TYPE_INODE_FL	(1U << FSNOTIFY_OBJ_TYPE_INODE)
+#define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL	(1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
+#define FSNOTIFY_OBJ_ALL_TYPES_MASK	((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
+
 /*
  * Inode / vfsmount point to this structure which tracks all marks attached to
  * the inode / vfsmount. The reference to inode / vfsmount is held by this
@@ -209,11 +220,7 @@ struct fsnotify_group {
  */
 struct fsnotify_mark_connector {
 	spinlock_t lock;
-#define FSNOTIFY_OBJ_TYPE_INODE		0x01
-#define FSNOTIFY_OBJ_TYPE_VFSMOUNT	0x02
-#define FSNOTIFY_OBJ_ALL_TYPES		(FSNOTIFY_OBJ_TYPE_INODE | \
-					 FSNOTIFY_OBJ_TYPE_VFSMOUNT)
-	unsigned int flags;	/* Type of object [lock] */
+	unsigned int type;	/* Type of object [lock] */
 	union {	/* Object pointer [lock] */
 		struct inode *inode;
 		struct vfsmount *mnt;
@@ -369,12 +376,12 @@ extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsigned
 /* run all the marks in a group, and clear all of the vfsmount marks */
 static inline void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group)
 {
-	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT);
+	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL);
 }
 /* run all the marks in a group, and clear all of the inode marks */
 static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group)
 {
-	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE);
+	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
 }
 extern void fsnotify_get_mark(struct fsnotify_mark *mark);
 extern void fsnotify_put_mark(struct fsnotify_mark *mark);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 02/13] fsnotify: remove redundant arguments to handle_event()
  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 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 03/13] fsnotify: introduce marks iteration helpers Amir Goldstein
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

inode_mark and vfsmount_mark arguments are passed to handle_event()
operation as function arguments as well as on iter_info struct.
The difference is that iter_info struct may contain marks that should
not be handled and are represented as NULL arguments to inode_mark or
vfsmount_mark.

Instead of passing the inode_mark and vfsmount_mark arguments, add
a report_mask member to iter_info struct to indicate which marks should
be handled, versus marks that should only be kept alive during user
wait.

This change is going to be used for passing more mark types
with handle_event() (i.e. super block marks).

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/dnotify/dnotify.c          |  6 +++---
 fs/notify/fanotify/fanotify.c        | 14 ++++++-------
 fs/notify/fsnotify.c                 | 38 +++++++++++++++++++-----------------
 fs/notify/fsnotify.h                 |  6 ------
 fs/notify/inotify/inotify.h          |  2 --
 fs/notify/inotify/inotify_fsnotify.c |  6 +++---
 fs/notify/inotify/inotify_user.c     |  8 ++++++--
 include/linux/fsnotify_backend.h     | 20 +++++++++++++++++--
 kernel/audit_fsnotify.c              |  3 +--
 kernel/audit_tree.c                  |  2 --
 kernel/audit_watch.c                 |  3 +--
 11 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 63a1ca4b9dee..b4e685b63f33 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -79,12 +79,11 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
  */
 static int dnotify_handle_event(struct fsnotify_group *group,
 				struct inode *inode,
-				struct fsnotify_mark *inode_mark,
-				struct fsnotify_mark *vfsmount_mark,
 				u32 mask, const void *data, int data_type,
 				const unsigned char *file_name, u32 cookie,
 				struct fsnotify_iter_info *iter_info)
 {
+	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
 	struct dnotify_mark *dn_mark;
 	struct dnotify_struct *dn;
 	struct dnotify_struct **prev;
@@ -95,7 +94,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
 	if (!S_ISDIR(inode->i_mode))
 		return 0;
 
-	BUG_ON(vfsmount_mark);
+	if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
+		return 0;
 
 	dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark);
 
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index d94e8031fe5f..f83650486052 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -87,11 +87,12 @@ static int fanotify_get_response(struct fsnotify_group *group,
 	return ret;
 }
 
-static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
-				       struct fsnotify_mark *vfsmnt_mark,
-				       u32 event_mask,
-				       const void *data, int data_type)
+static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
+				       u32 event_mask, const void *data,
+				       int data_type)
 {
+	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
+	struct fsnotify_mark *vfsmnt_mark = fsnotify_iter_vfsmount_mark(iter_info);
 	__u32 marks_mask = 0, marks_ignored_mask = 0;
 	const struct path *path = data;
 
@@ -178,8 +179,6 @@ init: __maybe_unused
 
 static int fanotify_handle_event(struct fsnotify_group *group,
 				 struct inode *inode,
-				 struct fsnotify_mark *inode_mark,
-				 struct fsnotify_mark *fanotify_mark,
 				 u32 mask, const void *data, int data_type,
 				 const unsigned char *file_name, u32 cookie,
 				 struct fsnotify_iter_info *iter_info)
@@ -199,8 +198,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
 	BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM);
 	BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR);
 
-	if (!fanotify_should_send_event(inode_mark, fanotify_mark, mask, data,
-					data_type))
+	if (!fanotify_should_send_event(iter_info, mask, data, data_type))
 		return 0;
 
 	pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode,
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 613ec7e5a465..9a63cf07f858 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -184,22 +184,20 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
 EXPORT_SYMBOL_GPL(__fsnotify_parent);
 
 static int send_to_group(struct inode *to_tell,
-			 struct fsnotify_mark *inode_mark,
-			 struct fsnotify_mark *vfsmount_mark,
 			 __u32 mask, const void *data,
 			 int data_is, u32 cookie,
 			 const unsigned char *file_name,
 			 struct fsnotify_iter_info *iter_info)
 {
+	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
+	struct fsnotify_mark *vfsmount_mark = fsnotify_iter_vfsmount_mark(iter_info);
 	struct fsnotify_group *group = NULL;
 	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
 	__u32 marks_mask = 0;
 	__u32 marks_ignored_mask = 0;
 
-	if (unlikely(!inode_mark && !vfsmount_mark)) {
-		BUG();
+	if (WARN_ON(!iter_info->report_mask))
 		return 0;
-	}
 
 	/* clear ignored on inode modification */
 	if (mask & FS_MODIFY) {
@@ -235,8 +233,7 @@ static int send_to_group(struct inode *to_tell,
 	if (!(test_mask & marks_mask & ~marks_ignored_mask))
 		return 0;
 
-	return group->ops->handle_event(group, to_tell, inode_mark,
-					vfsmount_mark, mask, data, data_is,
+	return group->ops->handle_event(group, to_tell, mask, data, data_is,
 					file_name, cookie, iter_info);
 }
 
@@ -327,27 +324,32 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 	while (iter_info.inode_mark || iter_info.vfsmount_mark) {
 		struct fsnotify_mark *inode_mark = iter_info.inode_mark;
 		struct fsnotify_mark *vfsmount_mark = iter_info.vfsmount_mark;
+		int cmp;
 
 		if (inode_mark && vfsmount_mark) {
-			int cmp = fsnotify_compare_groups(inode_mark->group,
-							  vfsmount_mark->group);
-			if (cmp > 0)
-				inode_mark = NULL;
-			else if (cmp < 0)
-				vfsmount_mark = NULL;
+			cmp = fsnotify_compare_groups(inode_mark->group,
+						      vfsmount_mark->group);
+		} else {
+			cmp = inode_mark ? -1 : 1;
 		}
 
-		ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
-				    data, data_is, cookie, file_name,
-				    &iter_info);
+		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;
+
+		ret = send_to_group(to_tell, mask, data, data_is, cookie,
+				    file_name, &iter_info);
 
 		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
 			goto out;
 
-		if (inode_mark)
+		if (iter_info.report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL)
 			iter_info.inode_mark =
 				fsnotify_next_mark(iter_info.inode_mark);
-		if (vfsmount_mark)
+
+		if (iter_info.report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL)
 			iter_info.vfsmount_mark =
 				fsnotify_next_mark(iter_info.vfsmount_mark);
 	}
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index 60f365dc1408..34515d2c4ba3 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -9,12 +9,6 @@
 
 #include "../mount.h"
 
-struct fsnotify_iter_info {
-	struct fsnotify_mark *inode_mark;
-	struct fsnotify_mark *vfsmount_mark;
-	int srcu_idx;
-};
-
 /* destroy all events sitting in this groups notification queue */
 extern void fsnotify_flush_notify(struct fsnotify_group *group);
 
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h
index c00d2caca894..7e4578d35b61 100644
--- a/fs/notify/inotify/inotify.h
+++ b/fs/notify/inotify/inotify.h
@@ -25,8 +25,6 @@ extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
 					   struct fsnotify_group *group);
 extern int inotify_handle_event(struct fsnotify_group *group,
 				struct inode *inode,
-				struct fsnotify_mark *inode_mark,
-				struct fsnotify_mark *vfsmount_mark,
 				u32 mask, const void *data, int data_type,
 				const unsigned char *file_name, u32 cookie,
 				struct fsnotify_iter_info *iter_info);
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 40dedb37a1f3..9ab6dde38a14 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -65,12 +65,11 @@ static int inotify_merge(struct list_head *list,
 
 int inotify_handle_event(struct fsnotify_group *group,
 			 struct inode *inode,
-			 struct fsnotify_mark *inode_mark,
-			 struct fsnotify_mark *vfsmount_mark,
 			 u32 mask, const void *data, int data_type,
 			 const unsigned char *file_name, u32 cookie,
 			 struct fsnotify_iter_info *iter_info)
 {
+	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
 	struct inotify_inode_mark *i_mark;
 	struct inotify_event_info *event;
 	struct fsnotify_event *fsn_event;
@@ -78,7 +77,8 @@ int inotify_handle_event(struct fsnotify_group *group,
 	int len = 0;
 	int alloc_len = sizeof(struct inotify_event_info);
 
-	BUG_ON(vfsmount_mark);
+	if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
+		return 0;
 
 	if ((inode_mark->mask & FS_EXCL_UNLINK) &&
 	    (data_type == FSNOTIFY_EVENT_PATH)) {
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index ef32f3657958..22a3d0471fee 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -485,10 +485,14 @@ 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,
+	};
 
 	/* Queue ignore event for the watch */
-	inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED,
-			     NULL, FSNOTIFY_EVENT_NONE, NULL, 0, NULL);
+	inotify_handle_event(group, NULL, FS_IN_IGNORED, NULL,
+			     FSNOTIFY_EVENT_NONE, NULL, 0, &iter_info);
 
 	i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
 	/* remove this mark from the idr */
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 435c94a31c8c..9da5edf4ac0f 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -98,8 +98,6 @@ struct fsnotify_iter_info;
 struct fsnotify_ops {
 	int (*handle_event)(struct fsnotify_group *group,
 			    struct inode *inode,
-			    struct fsnotify_mark *inode_mark,
-			    struct fsnotify_mark *vfsmount_mark,
 			    u32 mask, const void *data, int data_type,
 			    const unsigned char *file_name, u32 cookie,
 			    struct fsnotify_iter_info *iter_info);
@@ -212,6 +210,24 @@ enum fsnotify_obj_type {
 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL	(1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
 #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;
+	unsigned int report_mask;
+	int srcu_idx;
+};
+
+#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; \
+}
+
+FSNOTIFY_ITER_FUNCS(inode, INODE)
+FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
+
 /*
  * Inode / vfsmount point to this structure which tracks all marks attached to
  * the inode / vfsmount. The reference to inode / vfsmount is held by this
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index 52f368b6561e..1b80ff8d6632 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -165,12 +165,11 @@ static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark)
 /* Update mark data in audit rules based on fsnotify events. */
 static int audit_mark_handle_event(struct fsnotify_group *group,
 				    struct inode *to_tell,
-				    struct fsnotify_mark *inode_mark,
-				    struct fsnotify_mark *vfsmount_mark,
 				    u32 mask, const void *data, int data_type,
 				    const unsigned char *dname, u32 cookie,
 				    struct fsnotify_iter_info *iter_info)
 {
+	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
 	struct audit_fsnotify_mark *audit_mark;
 	const struct inode *inode = NULL;
 
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 67e6956c0b61..1f4de0517fb6 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -989,8 +989,6 @@ static void evict_chunk(struct audit_chunk *chunk)
 
 static int audit_tree_handle_event(struct fsnotify_group *group,
 				   struct inode *to_tell,
-				   struct fsnotify_mark *inode_mark,
-				   struct fsnotify_mark *vfsmount_mark,
 				   u32 mask, const void *data, int data_type,
 				   const unsigned char *file_name, u32 cookie,
 				   struct fsnotify_iter_info *iter_info)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 9eb8b3511636..43fcae4b0500 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -472,12 +472,11 @@ void audit_remove_watch_rule(struct audit_krule *krule)
 /* Update watch data in audit rules based on fsnotify events. */
 static int audit_watch_handle_event(struct fsnotify_group *group,
 				    struct inode *to_tell,
-				    struct fsnotify_mark *inode_mark,
-				    struct fsnotify_mark *vfsmount_mark,
 				    u32 mask, const void *data, int data_type,
 				    const unsigned char *dname, u32 cookie,
 				    struct fsnotify_iter_info *iter_info)
 {
+	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
 	const struct inode *inode;
 	struct audit_parent *parent;
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 03/13] fsnotify: introduce marks iteration helpers
  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 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 04/13] fsnotify: generalize iteration of marks by object type Amir Goldstein
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Introduce helpers fsnotify_iter_select_report_types() and
fsnotify_iter_next() to abstract the inode/vfsmount marks merged
list iteration.

This is a preparation patch before generalizing mark list
iteration to more mark object types (i.e. super block marks).

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

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 9a63cf07f858..98e91037b11d 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -261,6 +261,53 @@ static struct fsnotify_mark *fsnotify_next_mark(struct fsnotify_mark *mark)
 }
 
 /*
+ * iter_info is a multi head priority queue of marks.
+ * Pick a subset of marks from queue heads, all with the
+ * same group and set the report_mask for selected subset.
+ * Returns the report_mask of the selected subset.
+ */
+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;
+
+	if (!inode_mark && !vfsmount_mark)
+		return 0;
+
+	if (inode_mark && vfsmount_mark) {
+		cmp = fsnotify_compare_groups(inode_mark->group,
+					      vfsmount_mark->group);
+	} else {
+		cmp = inode_mark ? -1 : 1;
+	}
+
+	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;
+
+	return iter_info->report_mask;
+}
+
+/*
+ * Pop from iter_info multi head queue, the marks that were iterated in the
+ * current iteration step.
+ */
+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);
+
+	if (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL)
+		iter_info->vfsmount_mark =
+			fsnotify_next_mark(iter_info->vfsmount_mark);
+}
+
+/*
  * This is the main call to fsnotify.  The VFS calls into hook specific functions
  * in linux/fsnotify.h.  Those functions then in turn call here.  Here will call
  * out to all of the registered fsnotify_group.  Those groups can then use the
@@ -321,37 +368,14 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 	 * ignore masks are properly reflected for mount mark notifications.
 	 * That's why this traversal is so complicated...
 	 */
-	while (iter_info.inode_mark || iter_info.vfsmount_mark) {
-		struct fsnotify_mark *inode_mark = iter_info.inode_mark;
-		struct fsnotify_mark *vfsmount_mark = iter_info.vfsmount_mark;
-		int cmp;
-
-		if (inode_mark && vfsmount_mark) {
-			cmp = fsnotify_compare_groups(inode_mark->group,
-						      vfsmount_mark->group);
-		} else {
-			cmp = inode_mark ? -1 : 1;
-		}
-
-		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;
-
+	while (fsnotify_iter_select_report_types(&iter_info)) {
 		ret = send_to_group(to_tell, mask, data, data_is, cookie,
 				    file_name, &iter_info);
 
 		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
 			goto out;
 
-		if (iter_info.report_mask & FSNOTIFY_OBJ_TYPE_INODE_FL)
-			iter_info.inode_mark =
-				fsnotify_next_mark(iter_info.inode_mark);
-
-		if (iter_info.report_mask & FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL)
-			iter_info.vfsmount_mark =
-				fsnotify_next_mark(iter_info.vfsmount_mark);
+		fsnotify_iter_next(&iter_info);
 	}
 	ret = 0;
 out:
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 04/13] fsnotify: generalize iteration of marks by object type
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (2 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 03/13] fsnotify: introduce marks iteration helpers Amir Goldstein
@ 2018-04-20 23:10 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 05/13] fsnotify: generalize send_to_group() Amir Goldstein
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 05/13] fsnotify: generalize send_to_group()
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (3 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 04/13] fsnotify: generalize iteration of marks by object type Amir Goldstein
@ 2018-04-20 23:10 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 06/13] fanotify: generalize fanotify_should_send_event() Amir Goldstein
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Use fsnotify_foreach_obj_type macros to generalize the code that filters
events by marks mask and ignored_mask.

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

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

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index bc9a51480156..f174397b63a0 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -189,46 +189,44 @@ static int send_to_group(struct inode *to_tell,
 			 const unsigned char *file_name,
 			 struct fsnotify_iter_info *iter_info)
 {
-	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
-	struct fsnotify_mark *vfsmount_mark = fsnotify_iter_vfsmount_mark(iter_info);
 	struct fsnotify_group *group = NULL;
 	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
 	__u32 marks_mask = 0;
 	__u32 marks_ignored_mask = 0;
+	struct fsnotify_mark *mark;
+	int type;
 
 	if (WARN_ON(!iter_info->report_mask))
 		return 0;
 
 	/* clear ignored on inode modification */
 	if (mask & FS_MODIFY) {
-		if (inode_mark &&
-		    !(inode_mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
-			inode_mark->ignored_mask = 0;
-		if (vfsmount_mark &&
-		    !(vfsmount_mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
-			vfsmount_mark->ignored_mask = 0;
-	}
-
-	/* does the inode mark tell us to do something? */
-	if (inode_mark) {
-		group = inode_mark->group;
-		marks_mask |= inode_mark->mask;
-		marks_ignored_mask |= inode_mark->ignored_mask;
+		fsnotify_foreach_obj_type(type) {
+			if (!fsnotify_iter_should_report_type(iter_info, type))
+				continue;
+			mark = iter_info->marks[type];
+			if (mark &&
+			    !(mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY))
+				mark->ignored_mask = 0;
+		}
 	}
 
-	/* does the vfsmount_mark tell us to do something? */
-	if (vfsmount_mark) {
-		group = vfsmount_mark->group;
-		marks_mask |= vfsmount_mark->mask;
-		marks_ignored_mask |= vfsmount_mark->ignored_mask;
+	fsnotify_foreach_obj_type(type) {
+		if (!fsnotify_iter_should_report_type(iter_info, type))
+			continue;
+		mark = iter_info->marks[type];
+		/* does the object mark tell us to do something? */
+		if (mark) {
+			group = mark->group;
+			marks_mask |= mark->mask;
+			marks_ignored_mask |= mark->ignored_mask;
+		}
 	}
 
-	pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
-		 " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
+	pr_debug("%s: group=%p to_tell=%p mask=%x marks_mask=%x marks_ignored_mask=%x"
 		 " data=%p data_is=%d cookie=%d\n",
-		 __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
-		 marks_mask, marks_ignored_mask, data,
-		 data_is, cookie);
+		 __func__, group, to_tell, mask, marks_mask, marks_ignored_mask,
+		 data, data_is, cookie);
 
 	if (!(test_mask & marks_mask & ~marks_ignored_mask))
 		return 0;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 06/13] fanotify: generalize fanotify_should_send_event()
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (4 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 05/13] fsnotify: generalize send_to_group() Amir Goldstein
@ 2018-04-20 23:10 ` 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
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Use fsnotify_foreach_obj_type macros to generalize the code that filters
events by marks mask and ignored_mask.

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

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index f83650486052..53cff1902e41 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -91,14 +91,13 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
 				       u32 event_mask, const void *data,
 				       int data_type)
 {
-	struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
-	struct fsnotify_mark *vfsmnt_mark = fsnotify_iter_vfsmount_mark(iter_info);
 	__u32 marks_mask = 0, marks_ignored_mask = 0;
 	const struct path *path = data;
+	struct fsnotify_mark *mark;
+	int type;
 
-	pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p"
-		 " data_type=%d\n", __func__, inode_mark, vfsmnt_mark,
-		 event_mask, data, data_type);
+	pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n",
+		 __func__, iter_info->report_mask, event_mask, data, data_type);
 
 	/* if we don't have enough info to send an event to userspace say no */
 	if (data_type != FSNOTIFY_EVENT_PATH)
@@ -109,20 +108,23 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info,
 	    !d_can_lookup(path->dentry))
 		return false;
 
-	/*
-	 * if the event is for a child and this inode doesn't care about
-	 * events on the child, don't send it!
-	 */
-	if (inode_mark &&
-	    (!(event_mask & FS_EVENT_ON_CHILD) ||
-	     (inode_mark->mask & FS_EVENT_ON_CHILD))) {
-		marks_mask |= inode_mark->mask;
-		marks_ignored_mask |= inode_mark->ignored_mask;
-	}
+	fsnotify_foreach_obj_type(type) {
+		if (!fsnotify_iter_should_report_type(iter_info, type))
+			continue;
+		mark = iter_info->marks[type];
+		if (!mark)
+			continue;
+		/*
+		 * if the event is for a child and this inode doesn't care about
+		 * events on the child, don't send it!
+		 */
+		if (type == FSNOTIFY_OBJ_TYPE_INODE &&
+		    (event_mask & FS_EVENT_ON_CHILD) &&
+		    !(mark->mask & FS_EVENT_ON_CHILD))
+			continue;
 
-	if (vfsmnt_mark) {
-		marks_mask |= vfsmnt_mark->mask;
-		marks_ignored_mask |= vfsmnt_mark->ignored_mask;
+		marks_mask |= mark->mask;
+		marks_ignored_mask |= mark->ignored_mask;
 	}
 
 	if (d_is_dir(path->dentry) &&
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 07/13] fsnotify: add fsnotify_add_inode_mark() wrappers
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (5 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 06/13] fanotify: generalize fanotify_should_send_event() Amir Goldstein
@ 2018-04-20 23:10 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 08/13] fsnotify: introduce prototype struct fsnotify_obj Amir Goldstein
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Before changing the arguments of the functions fsnotify_add_mark()
and fsnotify_add_mark_locked(), convert most callers to use a wrapper.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/dnotify/dnotify.c      |  2 +-
 fs/notify/inotify/inotify_user.c |  2 +-
 include/linux/fsnotify_backend.h | 16 +++++++++++++++-
 kernel/audit_fsnotify.c          |  2 +-
 kernel/audit_tree.c              | 10 +++++-----
 kernel/audit_watch.c             |  2 +-
 6 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index b4e685b63f33..e2bea2ac5dfb 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -319,7 +319,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 		dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
 		spin_lock(&fsn_mark->lock);
 	} else {
-		error = fsnotify_add_mark_locked(new_fsn_mark, inode, NULL, 0);
+		error = fsnotify_add_inode_mark_locked(new_fsn_mark, inode, 0);
 		if (error) {
 			mutex_unlock(&dnotify_group->mark_mutex);
 			goto out_err;
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 6a408ab3169d..1cf5b779d862 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -582,7 +582,7 @@ static int inotify_new_watch(struct fsnotify_group *group,
 	}
 
 	/* we are on the idr, now get on the inode */
-	ret = fsnotify_add_mark_locked(&tmp_i_mark->fsn_mark, inode, NULL, 0);
+	ret = fsnotify_add_inode_mark_locked(&tmp_i_mark->fsn_mark, inode, 0);
 	if (ret) {
 		/* we failed to get on the inode, get off the idr */
 		inotify_remove_from_idr(group, tmp_i_mark);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 763423bfa3d6..b38964a7a521 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -401,7 +401,21 @@ extern struct fsnotify_mark *fsnotify_find_mark(
 extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
 			     struct vfsmount *mnt, int allow_dups);
 extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
-				    struct inode *inode, struct vfsmount *mnt, int allow_dups);
+				    struct inode *inode, struct vfsmount *mnt,
+				    int allow_dups);
+/* attach the mark to the inode */
+static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
+					  struct inode *inode,
+					  int allow_dups)
+{
+	return fsnotify_add_mark(mark, inode, NULL, allow_dups);
+}
+static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,
+						 struct inode *inode,
+						 int allow_dups)
+{
+	return fsnotify_add_mark_locked(mark, inode, NULL, allow_dups);
+}
 /* given a group and a mark, flag mark to be freed when all references are dropped */
 extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
 				  struct fsnotify_group *group);
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index 1b80ff8d6632..fba78047fb37 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -109,7 +109,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa
 	audit_update_mark(audit_mark, dentry->d_inode);
 	audit_mark->rule = krule;
 
-	ret = fsnotify_add_mark(&audit_mark->mark, inode, NULL, true);
+	ret = fsnotify_add_inode_mark(&audit_mark->mark, inode, true);
 	if (ret < 0) {
 		fsnotify_put_mark(&audit_mark->mark);
 		audit_mark = ERR_PTR(ret);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 1f4de0517fb6..c99ebaae5abc 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -288,8 +288,8 @@ static void untag_chunk(struct node *p)
 	if (!new)
 		goto Fallback;
 
-	if (fsnotify_add_mark_locked(&new->mark, entry->connector->inode,
-				     NULL, 1)) {
+	if (fsnotify_add_inode_mark_locked(&new->mark, entry->connector->inode,
+					   1)) {
 		fsnotify_put_mark(&new->mark);
 		goto Fallback;
 	}
@@ -354,7 +354,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
 		return -ENOMEM;
 
 	entry = &chunk->mark;
-	if (fsnotify_add_mark(entry, inode, NULL, 0)) {
+	if (fsnotify_add_inode_mark(entry, inode, 0)) {
 		fsnotify_put_mark(entry);
 		return -ENOSPC;
 	}
@@ -434,8 +434,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
 		return -ENOENT;
 	}
 
-	if (fsnotify_add_mark_locked(chunk_entry,
-			     old_entry->connector->inode, NULL, 1)) {
+	if (fsnotify_add_inode_mark_locked(chunk_entry,
+			     old_entry->connector->inode, 1)) {
 		spin_unlock(&old_entry->lock);
 		mutex_unlock(&old_entry->group->mark_mutex);
 		fsnotify_put_mark(chunk_entry);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 43fcae4b0500..439a3a01368c 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -160,7 +160,7 @@ static struct audit_parent *audit_init_parent(struct path *path)
 
 	fsnotify_init_mark(&parent->mark, audit_watch_group);
 	parent->mark.mask = AUDIT_FS_WATCH;
-	ret = fsnotify_add_mark(&parent->mark, inode, NULL, 0);
+	ret = fsnotify_add_inode_mark(&parent->mark, inode, 0);
 	if (ret < 0) {
 		audit_free_parent(parent);
 		return ERR_PTR(ret);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 08/13] fsnotify: introduce prototype struct fsnotify_obj
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (6 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 07/13] fsnotify: add fsnotify_add_inode_mark() wrappers Amir Goldstein
@ 2018-04-20 23:10 ` 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
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

struct inode and struct mount are both types of objects, which marks
can be attached to. Let them "inherit" from a prototype struct, so that
marks manipulation code can be made more generic.

Introduce helpers fsnotify_obj_{inode,mount} to get the concrete object
from the abstract object.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/inode.c                         |  2 +-
 fs/mount.h                         | 11 +++++++++--
 fs/notify/dnotify/dnotify.c        |  8 ++++----
 fs/notify/fanotify/fanotify_user.c | 24 ++++++++++++------------
 fs/notify/fsnotify.c               | 22 +++++++++++-----------
 fs/notify/fsnotify.h               |  4 ++--
 fs/notify/inotify/inotify_user.c   |  6 +++---
 fs/notify/mark.c                   | 16 ++++++++--------
 include/linux/fs.h                 |  6 ++----
 include/linux/fsnotify_backend.h   | 10 ++++++++--
 include/linux/fsnotify_obj.h       | 14 ++++++++++++++
 kernel/audit_tree.c                |  2 +-
 kernel/audit_watch.c               |  2 +-
 kernel/auditsc.c                   |  4 ++--
 14 files changed, 78 insertions(+), 53 deletions(-)
 create mode 100644 include/linux/fsnotify_obj.h

diff --git a/fs/inode.c b/fs/inode.c
index 13ceb98c3bd3..9eadddd2be94 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -190,7 +190,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 #endif
 
 #ifdef CONFIG_FSNOTIFY
-	inode->i_fsnotify_mask = 0;
+	inode->i_fsnotify.mask = 0;
 #endif
 	inode->i_flctx = NULL;
 	this_cpu_inc(nr_inodes);
diff --git a/fs/mount.h b/fs/mount.h
index f39bc9da4d73..718bb8073b90 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -4,6 +4,7 @@
 #include <linux/poll.h>
 #include <linux/ns_common.h>
 #include <linux/fs_pin.h>
+#include <linux/fsnotify_obj.h>
 
 struct mnt_namespace {
 	atomic_t		count;
@@ -61,8 +62,7 @@ struct mount {
 	struct hlist_node mnt_mp_list;	/* list mounts with the same mountpoint */
 	struct list_head mnt_umounting; /* list entry for umount propagation */
 #ifdef CONFIG_FSNOTIFY
-	struct fsnotify_mark_connector __rcu *mnt_fsnotify_marks;
-	__u32 mnt_fsnotify_mask;
+	struct fsnotify_obj mnt_fsnotify;
 #endif
 	int mnt_id;			/* mount identifier */
 	int mnt_group_id;		/* peer group identifier */
@@ -79,6 +79,13 @@ static inline struct mount *real_mount(struct vfsmount *mnt)
 	return container_of(mnt, struct mount, mnt);
 }
 
+#ifdef CONFIG_FSNOTIFY
+static inline struct mount *fsnotify_obj_mount(struct fsnotify_obj *obj)
+{
+	return container_of(obj, struct mount, mnt_fsnotify);
+}
+#endif
+
 static inline int mnt_has_parent(struct mount *mnt)
 {
 	return mnt != mnt->mnt_parent;
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index e2bea2ac5dfb..d46167c69c99 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -33,7 +33,7 @@ static struct kmem_cache *dnotify_mark_cache __read_mostly;
 static struct fsnotify_group *dnotify_group __read_mostly;
 
 /*
- * dnotify will attach one of these to each inode (i_fsnotify_marks) which
+ * dnotify will attach one of these to each inode (i_fsnotify.marks) which
  * is being watched by dnotify.  If multiple userspace applications are watching
  * the same directory with dnotify their information is chained in dn
  */
@@ -158,7 +158,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
 	if (!S_ISDIR(inode->i_mode))
 		return;
 
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, dnotify_group);
 	if (!fsn_mark)
 		return;
 	dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
@@ -218,7 +218,7 @@ static __u32 convert_arg(unsigned long arg)
 
 /*
  * If multiple processes watch the same inode with dnotify there is only one
- * dnotify mark in inode->i_fsnotify_marks but we chain a dnotify_struct
+ * dnotify mark in inode->i_fsnotify.marks but we chain a dnotify_struct
  * onto that mark.  This function either attaches the new dnotify_struct onto
  * that list, or it |= the mask onto an existing dnofiy_struct.
  */
@@ -314,7 +314,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 	mutex_lock(&dnotify_group->mark_mutex);
 
 	/* add the new_fsn_mark or find an old one. */
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, dnotify_group);
 	if (fsn_mark) {
 		dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
 		spin_lock(&fsn_mark->lock);
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index ec4d8c59d0e3..ed87880c42f0 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -533,7 +533,7 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
 	int destroy_mark;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify_marks,
+	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify.marks,
 				      group);
 	if (!fsn_mark) {
 		mutex_unlock(&group->mark_mutex);
@@ -542,8 +542,8 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
 
 	removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
 						 &destroy_mark);
-	if (removed & real_mount(mnt)->mnt_fsnotify_mask)
-		fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks);
+	if (removed & real_mount(mnt)->mnt_fsnotify.mask)
+		fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify.marks);
 	if (destroy_mark)
 		fsnotify_detach_mark(fsn_mark);
 	mutex_unlock(&group->mark_mutex);
@@ -563,7 +563,7 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
 	int destroy_mark;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, group);
 	if (!fsn_mark) {
 		mutex_unlock(&group->mark_mutex);
 		return -ENOENT;
@@ -571,8 +571,8 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
 
 	removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
 						 &destroy_mark);
-	if (removed & inode->i_fsnotify_mask)
-		fsnotify_recalc_mask(inode->i_fsnotify_marks);
+	if (removed & inode->i_fsnotify.mask)
+		fsnotify_recalc_mask(inode->i_fsnotify.marks);
 	if (destroy_mark)
 		fsnotify_detach_mark(fsn_mark);
 	mutex_unlock(&group->mark_mutex);
@@ -647,7 +647,7 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 	__u32 added;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify_marks,
+	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify.marks,
 				      group);
 	if (!fsn_mark) {
 		fsn_mark = fanotify_add_new_mark(group, NULL, mnt);
@@ -657,8 +657,8 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 		}
 	}
 	added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-	if (added & ~real_mount(mnt)->mnt_fsnotify_mask)
-		fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify_marks);
+	if (added & ~real_mount(mnt)->mnt_fsnotify.mask)
+		fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify.marks);
 	mutex_unlock(&group->mark_mutex);
 
 	fsnotify_put_mark(fsn_mark);
@@ -685,7 +685,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 		return 0;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, group);
 	if (!fsn_mark) {
 		fsn_mark = fanotify_add_new_mark(group, inode, NULL);
 		if (IS_ERR(fsn_mark)) {
@@ -694,8 +694,8 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 		}
 	}
 	added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-	if (added & ~inode->i_fsnotify_mask)
-		fsnotify_recalc_mask(inode->i_fsnotify_marks);
+	if (added & ~inode->i_fsnotify.mask)
+		fsnotify_recalc_mask(inode->i_fsnotify.marks);
 	mutex_unlock(&group->mark_mutex);
 
 	fsnotify_put_mark(fsn_mark);
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index f174397b63a0..ea1003bc39d3 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -160,7 +160,7 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
 
 	if (unlikely(!fsnotify_inode_watches_children(p_inode)))
 		__fsnotify_update_child_dentry_flags(p_inode);
-	else if (p_inode->i_fsnotify_mask & mask) {
+	else if (p_inode->i_fsnotify.mask & mask) {
 		struct name_snapshot name;
 
 		/* we are notifying a parent so come up with the new mask which
@@ -331,13 +331,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 
 	/*
 	 * Optimization: srcu_read_lock() has a memory barrier which can
-	 * be expensive.  It protects walking the *_fsnotify_marks lists.
+	 * be expensive.  It protects walking the *_fsnotify.marks lists.
 	 * However, if we do not walk the lists, we do not have to do
 	 * SRCU because we have no references to any objects and do not
 	 * need SRCU to keep them "alive".
 	 */
-	if (!to_tell->i_fsnotify_marks &&
-	    (!mnt || !mnt->mnt_fsnotify_marks))
+	if (!to_tell->i_fsnotify.marks &&
+	    (!mnt || !mnt->mnt_fsnotify.marks))
 		return 0;
 	/*
 	 * if this is a modify event we may need to clear the ignored masks
@@ -345,24 +345,24 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 	 * this type of event.
 	 */
 	if (!(mask & FS_MODIFY) &&
-	    !(test_mask & to_tell->i_fsnotify_mask) &&
-	    !(mnt && test_mask & mnt->mnt_fsnotify_mask))
+	    !(test_mask & to_tell->i_fsnotify.mask) &&
+	    !(mnt && test_mask & mnt->mnt_fsnotify.mask))
 		return 0;
 
 	iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
 
 	if ((mask & FS_MODIFY) ||
-	    (test_mask & to_tell->i_fsnotify_mask)) {
+	    (test_mask & to_tell->i_fsnotify.mask)) {
 		iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
-			fsnotify_first_mark(&to_tell->i_fsnotify_marks);
+			fsnotify_first_mark(&to_tell->i_fsnotify.marks);
 	}
 
 	if (mnt && ((mask & FS_MODIFY) ||
-		    (test_mask & mnt->mnt_fsnotify_mask))) {
+		    (test_mask & mnt->mnt_fsnotify.mask))) {
 		iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
-			fsnotify_first_mark(&to_tell->i_fsnotify_marks);
+			fsnotify_first_mark(&to_tell->i_fsnotify.marks);
 		iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] =
-			fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
+			fsnotify_first_mark(&mnt->mnt_fsnotify.marks);
 	}
 
 	/*
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index 34515d2c4ba3..8f4d3e43b5b5 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -24,12 +24,12 @@ extern void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp)
 /* run the list of all marks associated with inode and destroy them */
 static inline void fsnotify_clear_marks_by_inode(struct inode *inode)
 {
-	fsnotify_destroy_marks(&inode->i_fsnotify_marks);
+	fsnotify_destroy_marks(&inode->i_fsnotify.marks);
 }
 /* run the list of all marks associated with vfsmount and destroy them */
 static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
 {
-	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks);
+	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify.marks);
 }
 /* Wait until all marks queued for destruction are destroyed */
 extern void fsnotify_wait_marks_destroyed(void);
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 1cf5b779d862..8eaa3b468b5c 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -514,7 +514,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
 
 	mask = inotify_arg_to_mask(arg);
 
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, group);
 	if (!fsn_mark)
 		return -ENOENT;
 
@@ -533,11 +533,11 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
 		/* more bits in old than in new? */
 		int dropped = (old_mask & ~new_mask);
 		/* more bits in this fsn_mark than the inode's mask? */
-		int do_inode = (new_mask & ~inode->i_fsnotify_mask);
+		int do_inode = (new_mask & ~inode->i_fsnotify.mask);
 
 		/* update the inode with this new fsn_mark */
 		if (dropped || do_inode)
-			fsnotify_recalc_mask(inode->i_fsnotify_marks);
+			fsnotify_recalc_mask(inode->i_fsnotify.marks);
 
 	}
 
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 61f4c5fa34c7..4f0c17e5db53 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -120,9 +120,9 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
 			new_mask |= mark->mask;
 	}
 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
-		conn->inode->i_fsnotify_mask = new_mask;
+		conn->inode->i_fsnotify.mask = new_mask;
 	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
-		real_mount(conn->mnt)->mnt_fsnotify_mask = new_mask;
+		real_mount(conn->mnt)->mnt_fsnotify.mask = new_mask;
 }
 
 /*
@@ -168,14 +168,14 @@ static struct inode *fsnotify_detach_connector_from_object(
 
 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
 		inode = conn->inode;
-		rcu_assign_pointer(inode->i_fsnotify_marks, NULL);
-		inode->i_fsnotify_mask = 0;
+		rcu_assign_pointer(inode->i_fsnotify.marks, NULL);
+		inode->i_fsnotify.mask = 0;
 		conn->inode = NULL;
 		conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
 	} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
-		rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify_marks,
+		rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify.marks,
 				   NULL);
-		real_mount(conn->mnt)->mnt_fsnotify_mask = 0;
+		real_mount(conn->mnt)->mnt_fsnotify.mask = 0;
 		conn->mnt = NULL;
 		conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
 	}
@@ -515,9 +515,9 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
 	if (WARN_ON(!inode && !mnt))
 		return -EINVAL;
 	if (inode)
-		connp = &inode->i_fsnotify_marks;
+		connp = &inode->i_fsnotify.marks;
 	else
-		connp = &real_mount(mnt)->mnt_fsnotify_marks;
+		connp = &real_mount(mnt)->mnt_fsnotify.marks;
 restart:
 	spin_lock(&mark->lock);
 	conn = fsnotify_grab_connector(connp);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 760d8da1b6c7..46af8e9a1111 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -36,6 +36,7 @@
 #include <linux/delayed_call.h>
 #include <linux/uuid.h>
 #include <linux/errseq.h>
+#include <linux/fsnotify_obj.h>
 
 #include <asm/byteorder.h>
 #include <uapi/linux/fs.h>
@@ -560,8 +561,6 @@ is_uncached_acl(struct posix_acl *acl)
 #define IOP_XATTR	0x0008
 #define IOP_DEFAULT_READLINK	0x0010
 
-struct fsnotify_mark_connector;
-
 /*
  * Keep mostly read-only and often accessed (especially for
  * the RCU path lookup and 'stat' data) fields at the beginning
@@ -661,8 +660,7 @@ struct inode {
 	__u32			i_generation;
 
 #ifdef CONFIG_FSNOTIFY
-	__u32			i_fsnotify_mask; /* all events this inode cares about */
-	struct fsnotify_mark_connector __rcu	*i_fsnotify_marks;
+	struct fsnotify_obj	i_fsnotify;
 #endif
 
 #if IS_ENABLED(CONFIG_FS_ENCRYPTION)
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index b38964a7a521..a2cd8c51860e 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -19,6 +19,7 @@
 #include <linux/atomic.h>
 #include <linux/user_namespace.h>
 #include <linux/refcount.h>
+#include <linux/fsnotify_obj.h>
 
 /*
  * IN_* from inotfy.h lines up EXACTLY with FS_*, this is so we can easily
@@ -268,6 +269,11 @@ struct fsnotify_mark_connector {
 	struct hlist_head list;
 };
 
+static inline struct inode *fsnotify_obj_inode(struct fsnotify_obj *obj)
+{
+	return container_of(obj, struct inode, i_fsnotify);
+}
+
 /*
  * A mark is simply an object attached to an in core inode which allows an
  * fsnotify listener to indicate they are either no longer interested in events
@@ -324,11 +330,11 @@ extern u32 fsnotify_get_cookie(void);
 static inline int fsnotify_inode_watches_children(struct inode *inode)
 {
 	/* FS_EVENT_ON_CHILD is set if the inode may care */
-	if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD))
+	if (!(inode->i_fsnotify.mask & FS_EVENT_ON_CHILD))
 		return 0;
 	/* this inode might care about child events, does it care about the
 	 * specific set of events that can happen on a child? */
-	return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD;
+	return inode->i_fsnotify.mask & FS_EVENTS_POSS_ON_CHILD;
 }
 
 /*
diff --git a/include/linux/fsnotify_obj.h b/include/linux/fsnotify_obj.h
new file mode 100644
index 000000000000..437e78e60f82
--- /dev/null
+++ b/include/linux/fsnotify_obj.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_FSNOTIFY_OBJ_H
+#define _LINUX_FSNOTIFY_OBJ_H
+
+struct fsnotify_mark_connector;
+
+/* struct to embed in objects, which marks can be attached to */
+struct fsnotify_obj {
+	struct fsnotify_mark_connector __rcu *marks;
+	/* all events this object cares about */
+	__u32 mask;
+};
+
+#endif
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index c99ebaae5abc..0124eb3999a5 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -393,7 +393,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
 	struct node *p;
 	int n;
 
-	old_entry = fsnotify_find_mark(&inode->i_fsnotify_marks,
+	old_entry = fsnotify_find_mark(&inode->i_fsnotify.marks,
 				       audit_tree_group);
 	if (!old_entry)
 		return create_chunk(inode, tree);
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 439a3a01368c..1b017875b8d2 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -103,7 +103,7 @@ static inline struct audit_parent *audit_find_parent(struct inode *inode)
 	struct audit_parent *parent = NULL;
 	struct fsnotify_mark *entry;
 
-	entry = fsnotify_find_mark(&inode->i_fsnotify_marks, audit_watch_group);
+	entry = fsnotify_find_mark(&inode->i_fsnotify.marks, audit_watch_group);
 	if (entry)
 		parent = container_of(entry, struct audit_parent, mark);
 
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4e0a4ac803db..87098b93ab79 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1598,7 +1598,7 @@ static inline void handle_one(const struct inode *inode)
 	struct audit_tree_refs *p;
 	struct audit_chunk *chunk;
 	int count;
-	if (likely(!inode->i_fsnotify_marks))
+	if (likely(!inode->i_fsnotify.marks))
 		return;
 	context = current->audit_context;
 	p = context->trees;
@@ -1641,7 +1641,7 @@ static void handle_path(const struct dentry *dentry)
 	seq = read_seqbegin(&rename_lock);
 	for(;;) {
 		struct inode *inode = d_backing_inode(d);
-		if (inode && unlikely(inode->i_fsnotify_marks)) {
+		if (inode && unlikely(inode->i_fsnotify.marks)) {
 			struct audit_chunk *chunk;
 			chunk = audit_tree_lookup(inode);
 			if (chunk) {
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 09/13] fsnotify: pass fsnotify_obj instead of **connp argument
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (7 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 08/13] fsnotify: introduce prototype struct fsnotify_obj Amir Goldstein
@ 2018-04-20 23:10 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 10/13] fsnotify: pass object and object type to fsnotify_add_mark() Amir Goldstein
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

The object marks manipulation functions fsnotify_destroy_marks()
fsnotify_find_mark() and their helpers take a **connp argument to
dereference the connector pointer. Pass the container fsnotify_obj pointer
argument instead to prepare for more cleanups.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/dnotify/dnotify.c        |  4 ++--
 fs/notify/fanotify/fanotify_user.c | 10 ++++-----
 fs/notify/fsnotify.h               |  8 ++++----
 fs/notify/inotify/inotify_user.c   |  2 +-
 fs/notify/mark.c                   | 42 ++++++++++++++++++--------------------
 include/linux/fsnotify_backend.h   |  7 +++----
 kernel/audit_tree.c                |  3 +--
 kernel/audit_watch.c               |  2 +-
 8 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index d46167c69c99..c7a74ee4b7a3 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -158,7 +158,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
 	if (!S_ISDIR(inode->i_mode))
 		return;
 
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, dnotify_group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, dnotify_group);
 	if (!fsn_mark)
 		return;
 	dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
@@ -314,7 +314,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 	mutex_lock(&dnotify_group->mark_mutex);
 
 	/* add the new_fsn_mark or find an old one. */
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, dnotify_group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, dnotify_group);
 	if (fsn_mark) {
 		dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
 		spin_lock(&fsn_mark->lock);
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index ed87880c42f0..c15de35c3ebc 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -533,8 +533,7 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
 	int destroy_mark;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify.marks,
-				      group);
+	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify, group);
 	if (!fsn_mark) {
 		mutex_unlock(&group->mark_mutex);
 		return -ENOENT;
@@ -563,7 +562,7 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
 	int destroy_mark;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, group);
 	if (!fsn_mark) {
 		mutex_unlock(&group->mark_mutex);
 		return -ENOENT;
@@ -647,8 +646,7 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 	__u32 added;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify.marks,
-				      group);
+	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify, group);
 	if (!fsn_mark) {
 		fsn_mark = fanotify_add_new_mark(group, NULL, mnt);
 		if (IS_ERR(fsn_mark)) {
@@ -685,7 +683,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 		return 0;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, group);
 	if (!fsn_mark) {
 		fsn_mark = fanotify_add_new_mark(group, inode, NULL);
 		if (IS_ERR(fsn_mark)) {
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index 8f4d3e43b5b5..6459481c964f 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -19,17 +19,17 @@ extern struct srcu_struct fsnotify_mark_srcu;
 extern int fsnotify_compare_groups(struct fsnotify_group *a,
 				   struct fsnotify_group *b);
 
-/* Destroy all marks connected via given connector */
-extern void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp);
+/* Destroy all marks connected to a given object */
+extern void fsnotify_destroy_marks(struct fsnotify_obj *obj);
 /* run the list of all marks associated with inode and destroy them */
 static inline void fsnotify_clear_marks_by_inode(struct inode *inode)
 {
-	fsnotify_destroy_marks(&inode->i_fsnotify.marks);
+	fsnotify_destroy_marks(&inode->i_fsnotify);
 }
 /* run the list of all marks associated with vfsmount and destroy them */
 static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
 {
-	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify.marks);
+	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify);
 }
 /* Wait until all marks queued for destruction are destroyed */
 extern void fsnotify_wait_marks_destroyed(void);
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 8eaa3b468b5c..0ef8e2be7ee5 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -514,7 +514,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group,
 
 	mask = inotify_arg_to_mask(arg);
 
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify.marks, group);
+	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, group);
 	if (!fsn_mark)
 		return -ENOENT;
 
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 4f0c17e5db53..2cd2a872bd66 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -436,10 +436,9 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
 	return -1;
 }
 
-static int fsnotify_attach_connector_to_object(
-				struct fsnotify_mark_connector __rcu **connp,
-				struct inode *inode,
-				struct vfsmount *mnt)
+static int fsnotify_attach_connector_to_object(struct fsnotify_obj *obj,
+					       struct inode *inode,
+					       struct vfsmount *mnt)
 {
 	struct fsnotify_mark_connector *conn;
 
@@ -456,10 +455,10 @@ static int fsnotify_attach_connector_to_object(
 		conn->mnt = mnt;
 	}
 	/*
-	 * cmpxchg() provides the barrier so that readers of *connp can see
+	 * cmpxchg() provides the barrier so that readers of obj->marks can see
 	 * only initialized structure
 	 */
-	if (cmpxchg(connp, NULL, conn)) {
+	if (cmpxchg(&obj->marks, NULL, conn)) {
 		/* Someone else created list structure for us */
 		if (inode)
 			iput(inode);
@@ -476,13 +475,13 @@ static int fsnotify_attach_connector_to_object(
  * they are sure list cannot go away under them.
  */
 static struct fsnotify_mark_connector *fsnotify_grab_connector(
-				struct fsnotify_mark_connector __rcu **connp)
+				struct fsnotify_obj *obj)
 {
 	struct fsnotify_mark_connector *conn;
 	int idx;
 
 	idx = srcu_read_lock(&fsnotify_mark_srcu);
-	conn = srcu_dereference(*connp, &fsnotify_mark_srcu);
+	conn = srcu_dereference(obj->marks, &fsnotify_mark_srcu);
 	if (!conn)
 		goto out;
 	spin_lock(&conn->lock);
@@ -508,22 +507,22 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
 {
 	struct fsnotify_mark *lmark, *last = NULL;
 	struct fsnotify_mark_connector *conn;
-	struct fsnotify_mark_connector __rcu **connp;
+	struct fsnotify_obj *obj;
 	int cmp;
 	int err = 0;
 
 	if (WARN_ON(!inode && !mnt))
 		return -EINVAL;
 	if (inode)
-		connp = &inode->i_fsnotify.marks;
+		obj = &inode->i_fsnotify;
 	else
-		connp = &real_mount(mnt)->mnt_fsnotify.marks;
+		obj = &real_mount(mnt)->mnt_fsnotify;
 restart:
 	spin_lock(&mark->lock);
-	conn = fsnotify_grab_connector(connp);
+	conn = fsnotify_grab_connector(obj);
 	if (!conn) {
 		spin_unlock(&mark->lock);
-		err = fsnotify_attach_connector_to_object(connp, inode, mnt);
+		err = fsnotify_attach_connector_to_object(obj, inode, mnt);
 		if (err)
 			return err;
 		goto restart;
@@ -626,17 +625,16 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
 }
 
 /*
- * Given a list of marks, find the mark associated with given group. If found
- * take a reference to that mark and return it, else return NULL.
+ * Given a list of object marks, find the mark associated with given group.
+ * If found take a reference to that mark and return it, else return NULL.
  */
-struct fsnotify_mark *fsnotify_find_mark(
-				struct fsnotify_mark_connector __rcu **connp,
-				struct fsnotify_group *group)
+struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_obj *obj,
+					 struct fsnotify_group *group)
 {
 	struct fsnotify_mark_connector *conn;
 	struct fsnotify_mark *mark;
 
-	conn = fsnotify_grab_connector(connp);
+	conn = fsnotify_grab_connector(obj);
 	if (!conn)
 		return NULL;
 
@@ -697,14 +695,14 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
 	}
 }
 
-/* Destroy all marks attached to inode / vfsmount */
-void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp)
+/* Destroy all marks attached to an object */
+void fsnotify_destroy_marks(struct fsnotify_obj *obj)
 {
 	struct fsnotify_mark_connector *conn;
 	struct fsnotify_mark *mark, *old_mark = NULL;
 	struct inode *inode;
 
-	conn = fsnotify_grab_connector(connp);
+	conn = fsnotify_grab_connector(obj);
 	if (!conn)
 		return;
 	/*
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index a2cd8c51860e..15ea4661995d 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -399,10 +399,9 @@ extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group
 extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn);
 extern void fsnotify_init_mark(struct fsnotify_mark *mark,
 			       struct fsnotify_group *group);
-/* Find mark belonging to given group in the list of marks */
-extern struct fsnotify_mark *fsnotify_find_mark(
-				struct fsnotify_mark_connector __rcu **connp,
-				struct fsnotify_group *group);
+/* Find mark belonging to given group in the list of object marks */
+extern struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_obj *obj,
+						struct fsnotify_group *group);
 /* attach the mark to the inode or vfsmount */
 extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
 			     struct vfsmount *mnt, int allow_dups);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 0124eb3999a5..eadee98f5a12 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -393,8 +393,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
 	struct node *p;
 	int n;
 
-	old_entry = fsnotify_find_mark(&inode->i_fsnotify.marks,
-				       audit_tree_group);
+	old_entry = fsnotify_find_mark(&inode->i_fsnotify, audit_tree_group);
 	if (!old_entry)
 		return create_chunk(inode, tree);
 
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 1b017875b8d2..cafec7b3985f 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -103,7 +103,7 @@ static inline struct audit_parent *audit_find_parent(struct inode *inode)
 	struct audit_parent *parent = NULL;
 	struct fsnotify_mark *entry;
 
-	entry = fsnotify_find_mark(&inode->i_fsnotify.marks, audit_watch_group);
+	entry = fsnotify_find_mark(&inode->i_fsnotify, audit_watch_group);
 	if (entry)
 		parent = container_of(entry, struct audit_parent, mark);
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 10/13] fsnotify: pass object and object type to fsnotify_add_mark()
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (8 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 09/13] fsnotify: pass fsnotify_obj instead of **connp argument Amir Goldstein
@ 2018-04-20 23:10 ` Amir Goldstein
  2018-04-20 23:10 ` [PATCH v3 11/13] fsnotify: add fsnotify_connector_inode() wrapper Amir Goldstein
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Instead of passing inode and vfsmount arguments to fsnotify_add_mark()
and its _locked variant, pass an abstract fsnotify_obj and the object
type.

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

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify_user.c | 16 ++++++++-------
 fs/notify/mark.c                   | 42 +++++++++++++++-----------------------
 include/linux/fsnotify_backend.h   | 18 +++++++++++-----
 3 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index c15de35c3ebc..42ec185be089 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -614,8 +614,8 @@ static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
 }
 
 static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
-						   struct inode *inode,
-						   struct vfsmount *mnt)
+						   struct fsnotify_obj *obj,
+						   unsigned int type)
 {
 	struct fsnotify_mark *mark;
 	int ret;
@@ -628,7 +628,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
 		return ERR_PTR(-ENOMEM);
 
 	fsnotify_init_mark(mark, group);
-	ret = fsnotify_add_mark_locked(mark, inode, mnt, 0);
+	ret = fsnotify_add_mark_locked(mark, obj, type, 0);
 	if (ret) {
 		fsnotify_put_mark(mark);
 		return ERR_PTR(ret);
@@ -642,13 +642,14 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 				      struct vfsmount *mnt, __u32 mask,
 				      unsigned int flags)
 {
+	struct fsnotify_obj *obj = &real_mount(mnt)->mnt_fsnotify;
 	struct fsnotify_mark *fsn_mark;
 	__u32 added;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify, group);
+	fsn_mark = fsnotify_find_mark(obj, group);
 	if (!fsn_mark) {
-		fsn_mark = fanotify_add_new_mark(group, NULL, mnt);
+		fsn_mark = fanotify_add_new_mark(group, obj, FSNOTIFY_OBJ_TYPE_VFSMOUNT);
 		if (IS_ERR(fsn_mark)) {
 			mutex_unlock(&group->mark_mutex);
 			return PTR_ERR(fsn_mark);
@@ -667,6 +668,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 				   struct inode *inode, __u32 mask,
 				   unsigned int flags)
 {
+	struct fsnotify_obj *obj = &inode->i_fsnotify;
 	struct fsnotify_mark *fsn_mark;
 	__u32 added;
 
@@ -683,9 +685,9 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 		return 0;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, group);
+	fsn_mark = fsnotify_find_mark(obj, group);
 	if (!fsn_mark) {
-		fsn_mark = fanotify_add_new_mark(group, inode, NULL);
+		fsn_mark = fanotify_add_new_mark(group, obj, FSNOTIFY_OBJ_TYPE_INODE);
 		if (IS_ERR(fsn_mark)) {
 			mutex_unlock(&group->mark_mutex);
 			return PTR_ERR(fsn_mark);
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 2cd2a872bd66..771178c46eeb 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -437,9 +437,9 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
 }
 
 static int fsnotify_attach_connector_to_object(struct fsnotify_obj *obj,
-					       struct inode *inode,
-					       struct vfsmount *mnt)
+					       unsigned int type)
 {
+	struct inode *inode = NULL;
 	struct fsnotify_mark_connector *conn;
 
 	conn = kmem_cache_alloc(fsnotify_mark_connector_cachep, GFP_KERNEL);
@@ -447,13 +447,11 @@ static int fsnotify_attach_connector_to_object(struct fsnotify_obj *obj,
 		return -ENOMEM;
 	spin_lock_init(&conn->lock);
 	INIT_HLIST_HEAD(&conn->list);
-	if (inode) {
-		conn->type = FSNOTIFY_OBJ_TYPE_INODE;
-		conn->inode = igrab(inode);
-	} else {
-		conn->type = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
-		conn->mnt = mnt;
-	}
+	conn->type = type;
+	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
+		inode = conn->inode = igrab(fsnotify_obj_inode(obj));
+	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
+		conn->mnt = &fsnotify_obj_mount(obj)->mnt;
 	/*
 	 * cmpxchg() provides the barrier so that readers of obj->marks can see
 	 * only initialized structure
@@ -502,27 +500,22 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector(
  * priority, highest number first, and then by the group's location in memory.
  */
 static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
-				  struct inode *inode, struct vfsmount *mnt,
+				  struct fsnotify_obj *obj, unsigned int type,
 				  int allow_dups)
 {
 	struct fsnotify_mark *lmark, *last = NULL;
 	struct fsnotify_mark_connector *conn;
-	struct fsnotify_obj *obj;
 	int cmp;
 	int err = 0;
 
-	if (WARN_ON(!inode && !mnt))
+	if (WARN_ON(!fsnotify_valid_obj_type(type)))
 		return -EINVAL;
-	if (inode)
-		obj = &inode->i_fsnotify;
-	else
-		obj = &real_mount(mnt)->mnt_fsnotify;
 restart:
 	spin_lock(&mark->lock);
 	conn = fsnotify_grab_connector(obj);
 	if (!conn) {
 		spin_unlock(&mark->lock);
-		err = fsnotify_attach_connector_to_object(obj, inode, mnt);
+		err = fsnotify_attach_connector_to_object(obj, type);
 		if (err)
 			return err;
 		goto restart;
@@ -568,14 +561,13 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
  * These marks may be used for the fsnotify backend to determine which
  * event types should be delivered to which group.
  */
-int fsnotify_add_mark_locked(struct fsnotify_mark *mark, struct inode *inode,
-			     struct vfsmount *mnt, int allow_dups)
+int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
+			     struct fsnotify_obj *obj, unsigned int type,
+			     int allow_dups)
 {
 	struct fsnotify_group *group = mark->group;
 	int ret = 0;
 
-	BUG_ON(inode && mnt);
-	BUG_ON(!inode && !mnt);
 	BUG_ON(!mutex_is_locked(&group->mark_mutex));
 
 	/*
@@ -592,7 +584,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, struct inode *inode,
 	fsnotify_get_mark(mark); /* for g_list */
 	spin_unlock(&mark->lock);
 
-	ret = fsnotify_add_mark_list(mark, inode, mnt, allow_dups);
+	ret = fsnotify_add_mark_list(mark, obj, type, allow_dups);
 	if (ret)
 		goto err;
 
@@ -612,14 +604,14 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, struct inode *inode,
 	return ret;
 }
 
-int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
-		      struct vfsmount *mnt, int allow_dups)
+int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_obj *obj,
+		      unsigned int type, int allow_dups)
 {
 	int ret;
 	struct fsnotify_group *group = mark->group;
 
 	mutex_lock(&group->mark_mutex);
-	ret = fsnotify_add_mark_locked(mark, inode, mnt, allow_dups);
+	ret = fsnotify_add_mark_locked(mark, obj, type, allow_dups);
 	mutex_unlock(&group->mark_mutex);
 	return ret;
 }
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 15ea4661995d..b2826dd1e68c 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -211,6 +211,11 @@ enum fsnotify_obj_type {
 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL	(1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
 #define FSNOTIFY_OBJ_ALL_TYPES_MASK	((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
 
+static inline bool fsnotify_valid_obj_type(unsigned int type)
+{
+	return (type < FSNOTIFY_OBJ_TYPE_COUNT);
+}
+
 struct fsnotify_iter_info {
 	struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT];
 	unsigned int report_mask;
@@ -403,23 +408,26 @@ extern void fsnotify_init_mark(struct fsnotify_mark *mark,
 extern struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_obj *obj,
 						struct fsnotify_group *group);
 /* attach the mark to the inode or vfsmount */
-extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
-			     struct vfsmount *mnt, int allow_dups);
+extern int fsnotify_add_mark(struct fsnotify_mark *mark,
+			     struct fsnotify_obj *obj, unsigned int type,
+			     int allow_dups);
 extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
-				    struct inode *inode, struct vfsmount *mnt,
+				    struct fsnotify_obj *obj, unsigned int type,
 				    int allow_dups);
 /* attach the mark to the inode */
 static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
 					  struct inode *inode,
 					  int allow_dups)
 {
-	return fsnotify_add_mark(mark, inode, NULL, allow_dups);
+	return fsnotify_add_mark(mark, &inode->i_fsnotify,
+				 FSNOTIFY_OBJ_TYPE_INODE, allow_dups);
 }
 static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,
 						 struct inode *inode,
 						 int allow_dups)
 {
-	return fsnotify_add_mark_locked(mark, inode, NULL, allow_dups);
+	return fsnotify_add_mark_locked(mark, &inode->i_fsnotify,
+					FSNOTIFY_OBJ_TYPE_INODE, allow_dups);
 }
 /* given a group and a mark, flag mark to be freed when all references are dropped */
 extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 11/13] fsnotify: add fsnotify_connector_inode() wrapper
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (9 preceding siblings ...)
  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 ` 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
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:10 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Soon we will be changing the way to dereference an inode object from
connector object. Introduce a wrapper to abstract this dereference.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fdinfo.c               |  4 ++--
 fs/notify/mark.c                 |  3 ++-
 include/linux/fsnotify_backend.h |  6 ++++++
 kernel/audit_tree.c              | 11 ++++++-----
 4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index 10aac1942c9f..b3cf03e347a8 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -81,7 +81,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 		return;
 
 	inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
-	inode = igrab(mark->connector->inode);
+	inode = igrab(fsnotify_connector_inode(mark->connector));
 	if (inode) {
 		/*
 		 * IN_ALL_EVENTS represents all of the mask bits
@@ -117,7 +117,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 		mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
 
 	if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
-		inode = igrab(mark->connector->inode);
+		inode = igrab(fsnotify_connector_inode(mark->connector));
 		if (!inode)
 			return;
 		seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ",
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 771178c46eeb..7103a0a442e7 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -140,7 +140,8 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
 	__fsnotify_recalc_mask(conn);
 	spin_unlock(&conn->lock);
 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
-		__fsnotify_update_child_dentry_flags(conn->inode);
+		__fsnotify_update_child_dentry_flags(
+				fsnotify_connector_inode(conn));
 }
 
 /* Free all connectors queued for freeing once SRCU period ends */
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index b2826dd1e68c..6e9397c16124 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -279,6 +279,12 @@ static inline struct inode *fsnotify_obj_inode(struct fsnotify_obj *obj)
 	return container_of(obj, struct inode, i_fsnotify);
 }
 
+static inline struct inode *fsnotify_connector_inode(
+		struct fsnotify_mark_connector *conn)
+{
+	return conn->inode;
+}
+
 /*
  * A mark is simply an object attached to an in core inode which allows an
  * fsnotify listener to indicate they are either no longer interested in events
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index eadee98f5a12..529e4757f4e1 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -183,7 +183,7 @@ static unsigned long chunk_to_key(struct audit_chunk *chunk)
 	 */
 	if (WARN_ON_ONCE(!chunk->mark.connector))
 		return 0;
-	return (unsigned long)chunk->mark.connector->inode;
+	return (unsigned long)fsnotify_connector_inode(chunk->mark.connector);
 }
 
 static inline struct list_head *chunk_hash(unsigned long key)
@@ -258,7 +258,7 @@ static void untag_chunk(struct node *p)
 	spin_lock(&entry->lock);
 	/*
 	 * mark_mutex protects mark from getting detached and thus also from
-	 * mark->connector->inode getting NULL.
+	 * mark->connector->obj getting NULL.
 	 */
 	if (chunk->dead || !(entry->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) {
 		spin_unlock(&entry->lock);
@@ -288,8 +288,9 @@ static void untag_chunk(struct node *p)
 	if (!new)
 		goto Fallback;
 
-	if (fsnotify_add_inode_mark_locked(&new->mark, entry->connector->inode,
-					   1)) {
+	if (fsnotify_add_inode_mark_locked(&new->mark,
+				fsnotify_connector_inode(entry->connector),
+				1)) {
 		fsnotify_put_mark(&new->mark);
 		goto Fallback;
 	}
@@ -434,7 +435,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
 	}
 
 	if (fsnotify_add_inode_mark_locked(chunk_entry,
-			     old_entry->connector->inode, 1)) {
+			fsnotify_connector_inode(old_entry->connector), 1)) {
 		spin_unlock(&old_entry->lock);
 		mutex_unlock(&old_entry->group->mark_mutex);
 		fsnotify_put_mark(chunk_entry);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 12/13] fsnotify: let connector point to abstract fsnotify_obj
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (10 preceding siblings ...)
  2018-04-20 23:10 ` [PATCH v3 11/13] fsnotify: add fsnotify_connector_inode() wrapper Amir Goldstein
@ 2018-04-20 23:11 ` 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
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:11 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Make the code to attach/detach a connector to object more generic
by letting the fsnotify connector point to the abstract fsnotify_obj.
Code that needs to dereference an inode or mount object now uses the
macros fsnotify_obj_{inode,mount}.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fdinfo.c               |  2 +-
 fs/notify/mark.c                 | 35 ++++++++++++++---------------------
 include/linux/fsnotify_backend.h |  8 ++++----
 3 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index b3cf03e347a8..725c92bf2dc3 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -127,7 +127,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 		seq_putc(m, '\n');
 		iput(inode);
 	} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
-		struct mount *mnt = real_mount(mark->connector->mnt);
+		struct mount *mnt = fsnotify_obj_mount(mark->connector->obj);
 
 		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
 			   mnt->mnt_id, mflags, mark->mask, mark->ignored_mask);
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 7103a0a442e7..9642d6c14bfc 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -119,15 +119,12 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
 		if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
 			new_mask |= mark->mask;
 	}
-	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
-		conn->inode->i_fsnotify.mask = new_mask;
-	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
-		real_mount(conn->mnt)->mnt_fsnotify.mask = new_mask;
+	conn->obj->mask = new_mask;
 }
 
 /*
  * Calculate mask of events for a list of marks. The caller must make sure
- * connector and connector->inode cannot disappear under us.  Callers achieve
+ * connector and connector->obj cannot disappear under us.  Callers achieve
  * this by holding a mark->lock or mark->group->mark_mutex for a mark on this
  * list.
  */
@@ -167,19 +164,16 @@ static struct inode *fsnotify_detach_connector_from_object(
 {
 	struct inode *inode = NULL;
 
-	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) {
-		inode = conn->inode;
-		rcu_assign_pointer(inode->i_fsnotify.marks, NULL);
-		inode->i_fsnotify.mask = 0;
-		conn->inode = NULL;
-		conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
-	} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
-		rcu_assign_pointer(real_mount(conn->mnt)->mnt_fsnotify.marks,
-				   NULL);
-		real_mount(conn->mnt)->mnt_fsnotify.mask = 0;
-		conn->mnt = NULL;
-		conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
-	}
+	if (conn->type == FSNOTIFY_OBJ_TYPE_DETACHED)
+		return NULL;
+
+	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
+		inode = fsnotify_obj_inode(conn->obj);
+
+	rcu_assign_pointer(conn->obj->marks, NULL);
+	conn->obj->mask = 0;
+	conn->obj = NULL;
+	conn->type = FSNOTIFY_OBJ_TYPE_DETACHED;
 
 	return inode;
 }
@@ -449,10 +443,9 @@ static int fsnotify_attach_connector_to_object(struct fsnotify_obj *obj,
 	spin_lock_init(&conn->lock);
 	INIT_HLIST_HEAD(&conn->list);
 	conn->type = type;
+	conn->obj = obj;
 	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
-		inode = conn->inode = igrab(fsnotify_obj_inode(obj));
-	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
-		conn->mnt = &fsnotify_obj_mount(obj)->mnt;
+		inode = igrab(fsnotify_obj_inode(obj));
 	/*
 	 * cmpxchg() provides the barrier so that readers of obj->marks can see
 	 * only initialized structure
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 6e9397c16124..b7ba56b9feb8 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -265,9 +265,9 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
 struct fsnotify_mark_connector {
 	spinlock_t lock;
 	unsigned int type;	/* Type of object [lock] */
-	union {	/* Object pointer [lock] */
-		struct inode *inode;
-		struct vfsmount *mnt;
+	union {
+		/* Object pointer [lock] */
+		struct fsnotify_obj *obj;
 		/* Used listing heads to free after srcu period expires */
 		struct fsnotify_mark_connector *destroy_next;
 	};
@@ -282,7 +282,7 @@ static inline struct inode *fsnotify_obj_inode(struct fsnotify_obj *obj)
 static inline struct inode *fsnotify_connector_inode(
 		struct fsnotify_mark_connector *conn)
 {
-	return conn->inode;
+	return fsnotify_obj_inode(conn->obj);
 }
 
 /*
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 13/13] fanotify: factor out helpers to add/remove mark
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (11 preceding siblings ...)
  2018-04-20 23:11 ` [PATCH v3 12/13] fsnotify: let connector point to abstract fsnotify_obj Amir Goldstein
@ 2018-04-20 23:11 ` Amir Goldstein
  2018-05-18 13:09 ` [PATCH v3 00/13] Preparing for fanotify super block marks Jan Kara
  13 siblings, 0 replies; 18+ messages in thread
From: Amir Goldstein @ 2018-04-20 23:11 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel

Factor out helpers fanotify_add_mark() and fanotify_remove_mark()
to reduce duplicated code.

These helpers are going to be used for adding functions to add/remove
a super block mark.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify_user.c | 90 ++++++++++++++------------------------
 1 file changed, 32 insertions(+), 58 deletions(-)

diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 42ec185be089..892618fb065f 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -524,16 +524,16 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
 	return mask & oldmask;
 }
 
-static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
-					 struct vfsmount *mnt, __u32 mask,
-					 unsigned int flags)
+static int fanotify_remove_mark(struct fsnotify_group *group,
+				struct fsnotify_obj *obj,
+				__u32 mask, unsigned int flags)
 {
 	struct fsnotify_mark *fsn_mark = NULL;
 	__u32 removed;
 	int destroy_mark;
 
 	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&real_mount(mnt)->mnt_fsnotify, group);
+	fsn_mark = fsnotify_find_mark(obj, group);
 	if (!fsn_mark) {
 		mutex_unlock(&group->mark_mutex);
 		return -ENOENT;
@@ -541,47 +541,32 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
 
 	removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
 						 &destroy_mark);
-	if (removed & real_mount(mnt)->mnt_fsnotify.mask)
-		fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify.marks);
+	if (removed & obj->mask)
+		fsnotify_recalc_mask(obj->marks);
 	if (destroy_mark)
 		fsnotify_detach_mark(fsn_mark);
 	mutex_unlock(&group->mark_mutex);
 	if (destroy_mark)
 		fsnotify_free_mark(fsn_mark);
 
+	/* matches the fsnotify_find_mark() */
 	fsnotify_put_mark(fsn_mark);
 	return 0;
 }
 
+static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
+					 struct vfsmount *mnt, __u32 mask,
+					 unsigned int flags)
+{
+	return fanotify_remove_mark(group, &real_mount(mnt)->mnt_fsnotify,
+				    mask, flags);
+}
+
 static int fanotify_remove_inode_mark(struct fsnotify_group *group,
 				      struct inode *inode, __u32 mask,
 				      unsigned int flags)
 {
-	struct fsnotify_mark *fsn_mark = NULL;
-	__u32 removed;
-	int destroy_mark;
-
-	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify, group);
-	if (!fsn_mark) {
-		mutex_unlock(&group->mark_mutex);
-		return -ENOENT;
-	}
-
-	removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
-						 &destroy_mark);
-	if (removed & inode->i_fsnotify.mask)
-		fsnotify_recalc_mask(inode->i_fsnotify.marks);
-	if (destroy_mark)
-		fsnotify_detach_mark(fsn_mark);
-	mutex_unlock(&group->mark_mutex);
-	if (destroy_mark)
-		fsnotify_free_mark(fsn_mark);
-
-	/* matches the fsnotify_find_mark() */
-	fsnotify_put_mark(fsn_mark);
-
-	return 0;
+	return fanotify_remove_mark(group, &inode->i_fsnotify, mask, flags);
 }
 
 static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
@@ -638,40 +623,43 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
 }
 
 
-static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
-				      struct vfsmount *mnt, __u32 mask,
-				      unsigned int flags)
+static int fanotify_add_mark(struct fsnotify_group *group,
+			     struct fsnotify_obj *obj, unsigned int type,
+			     __u32 mask, unsigned int flags)
 {
-	struct fsnotify_obj *obj = &real_mount(mnt)->mnt_fsnotify;
 	struct fsnotify_mark *fsn_mark;
 	__u32 added;
 
 	mutex_lock(&group->mark_mutex);
 	fsn_mark = fsnotify_find_mark(obj, group);
 	if (!fsn_mark) {
-		fsn_mark = fanotify_add_new_mark(group, obj, FSNOTIFY_OBJ_TYPE_VFSMOUNT);
+		fsn_mark = fanotify_add_new_mark(group, obj, type);
 		if (IS_ERR(fsn_mark)) {
 			mutex_unlock(&group->mark_mutex);
 			return PTR_ERR(fsn_mark);
 		}
 	}
 	added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-	if (added & ~real_mount(mnt)->mnt_fsnotify.mask)
-		fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify.marks);
+	if (added & ~obj->mask)
+		fsnotify_recalc_mask(obj->marks);
 	mutex_unlock(&group->mark_mutex);
 
 	fsnotify_put_mark(fsn_mark);
 	return 0;
 }
 
+static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
+				      struct vfsmount *mnt, __u32 mask,
+				      unsigned int flags)
+{
+	return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify,
+				 FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags);
+}
+
 static int fanotify_add_inode_mark(struct fsnotify_group *group,
 				   struct inode *inode, __u32 mask,
 				   unsigned int flags)
 {
-	struct fsnotify_obj *obj = &inode->i_fsnotify;
-	struct fsnotify_mark *fsn_mark;
-	__u32 added;
-
 	pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
 	/*
@@ -684,22 +672,8 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 	    (atomic_read(&inode->i_writecount) > 0))
 		return 0;
 
-	mutex_lock(&group->mark_mutex);
-	fsn_mark = fsnotify_find_mark(obj, group);
-	if (!fsn_mark) {
-		fsn_mark = fanotify_add_new_mark(group, obj, FSNOTIFY_OBJ_TYPE_INODE);
-		if (IS_ERR(fsn_mark)) {
-			mutex_unlock(&group->mark_mutex);
-			return PTR_ERR(fsn_mark);
-		}
-	}
-	added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-	if (added & ~inode->i_fsnotify.mask)
-		fsnotify_recalc_mask(inode->i_fsnotify.marks);
-	mutex_unlock(&group->mark_mutex);
-
-	fsnotify_put_mark(fsn_mark);
-	return 0;
+	return fanotify_add_mark(group, &inode->i_fsnotify,
+				 FSNOTIFY_OBJ_TYPE_INODE, mask, flags);
 }
 
 /* fanotify syscalls */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 06/13] fanotify: generalize fanotify_should_send_event()
  2018-04-20 23:10 ` [PATCH v3 06/13] fanotify: generalize fanotify_should_send_event() Amir Goldstein
@ 2018-05-18 10:47   ` Jan Kara
  0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2018-05-18 10:47 UTC (permalink / raw)
  To: Amir Goldstein; +Cc: Jan Kara, linux-fsdevel

Hi Amir,

I'm just going through your patches and pushing them to my tree and I have
one question here:

On Fri 20-04-18 16`:10:54, Amir Goldstein wrote:
> +	fsnotify_foreach_obj_type(type) {
> +		if (!fsnotify_iter_should_report_type(iter_info, type))
> +			continue;
> +		mark = iter_info->marks[type];
> +		if (!mark)
> +			continue;

How could possibly mark be NULL here when
fsnotify_iter_should_report_type() returned true? I suppose it's a leftover
from some older version of the series but wanted to check whether I'm not
missing something.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 08/13] fsnotify: introduce prototype struct fsnotify_obj
  2018-04-20 23:10 ` [PATCH v3 08/13] fsnotify: introduce prototype struct fsnotify_obj Amir Goldstein
@ 2018-05-18 12:02   ` Jan Kara
  0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2018-05-18 12:02 UTC (permalink / raw)
  To: Amir Goldstein; +Cc: Jan Kara, linux-fsdevel

On Fri 20-04-18 16:10:56, Amir Goldstein wrote:
> struct inode and struct mount are both types of objects, which marks
> can be attached to. Let them "inherit" from a prototype struct, so that
> marks manipulation code can be made more generic.
> 
> Introduce helpers fsnotify_obj_{inode,mount} to get the concrete object
> from the abstract object.

...

> @@ -661,8 +660,7 @@ struct inode {
>  	__u32			i_generation;
>  
>  #ifdef CONFIG_FSNOTIFY
> -	__u32			i_fsnotify_mask; /* all events this inode cares about */
> -	struct fsnotify_mark_connector __rcu	*i_fsnotify_marks;
> +	struct fsnotify_obj	i_fsnotify;
>  #endif

So this grows struct inode by 8 bytes due to padding. I've made
struct fsnotify_obj packed (so that it's really 12 bytes and not 16) and
put i_generation after i_fsnotify_mask to avoid additional padding.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 11/13] fsnotify: add fsnotify_connector_inode() wrapper
  2018-04-20 23:10 ` [PATCH v3 11/13] fsnotify: add fsnotify_connector_inode() wrapper Amir Goldstein
@ 2018-05-18 12:48   ` Jan Kara
  0 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2018-05-18 12:48 UTC (permalink / raw)
  To: Amir Goldstein; +Cc: Jan Kara, linux-fsdevel

On Fri 20-04-18 16:10:59, Amir Goldstein wrote:
> Soon we will be changing the way to dereference an inode object from
> connector object. Introduce a wrapper to abstract this dereference.
> 
> Signed-off-by: Amir Goldstein <amir73il@gmail.com>

I don't think this helper helps us much. It just changes (after the
following patch):

fsnotify_obj_inode(conn->obj)

to

fsnotify_connector_inode(conn).

So the result is even longer to type and we are speaking only about 6
places so it's not like this is going to make the following patch that much
easier. Also mounts don't have similar helper. I'll just drop this patch
and fixup the following one for now. If you really want the helper, then we
can talk about that but I find fsnotify_mark_inode() helper more useful -
most places actually want mark -> inode transition and that's also a bit
longer (fsnotify_obj_inode(mark->conn->obj)).

								Honza

> ---
>  fs/notify/fdinfo.c               |  4 ++--
>  fs/notify/mark.c                 |  3 ++-
>  include/linux/fsnotify_backend.h |  6 ++++++
>  kernel/audit_tree.c              | 11 ++++++-----
>  4 files changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
> index 10aac1942c9f..b3cf03e347a8 100644
> --- a/fs/notify/fdinfo.c
> +++ b/fs/notify/fdinfo.c
> @@ -81,7 +81,7 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
>  		return;
>  
>  	inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
> -	inode = igrab(mark->connector->inode);
> +	inode = igrab(fsnotify_connector_inode(mark->connector));
>  	if (inode) {
>  		/*
>  		 * IN_ALL_EVENTS represents all of the mask bits
> @@ -117,7 +117,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
>  		mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
>  
>  	if (mark->connector->type == FSNOTIFY_OBJ_TYPE_INODE) {
> -		inode = igrab(mark->connector->inode);
> +		inode = igrab(fsnotify_connector_inode(mark->connector));
>  		if (!inode)
>  			return;
>  		seq_printf(m, "fanotify ino:%lx sdev:%x mflags:%x mask:%x ignored_mask:%x ",
> diff --git a/fs/notify/mark.c b/fs/notify/mark.c
> index 771178c46eeb..7103a0a442e7 100644
> --- a/fs/notify/mark.c
> +++ b/fs/notify/mark.c
> @@ -140,7 +140,8 @@ void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
>  	__fsnotify_recalc_mask(conn);
>  	spin_unlock(&conn->lock);
>  	if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
> -		__fsnotify_update_child_dentry_flags(conn->inode);
> +		__fsnotify_update_child_dentry_flags(
> +				fsnotify_connector_inode(conn));
>  }
>  
>  /* Free all connectors queued for freeing once SRCU period ends */
> diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
> index b2826dd1e68c..6e9397c16124 100644
> --- a/include/linux/fsnotify_backend.h
> +++ b/include/linux/fsnotify_backend.h
> @@ -279,6 +279,12 @@ static inline struct inode *fsnotify_obj_inode(struct fsnotify_obj *obj)
>  	return container_of(obj, struct inode, i_fsnotify);
>  }
>  
> +static inline struct inode *fsnotify_connector_inode(
> +		struct fsnotify_mark_connector *conn)
> +{
> +	return conn->inode;
> +}
> +
>  /*
>   * A mark is simply an object attached to an in core inode which allows an
>   * fsnotify listener to indicate they are either no longer interested in events
> diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
> index eadee98f5a12..529e4757f4e1 100644
> --- a/kernel/audit_tree.c
> +++ b/kernel/audit_tree.c
> @@ -183,7 +183,7 @@ static unsigned long chunk_to_key(struct audit_chunk *chunk)
>  	 */
>  	if (WARN_ON_ONCE(!chunk->mark.connector))
>  		return 0;
> -	return (unsigned long)chunk->mark.connector->inode;
> +	return (unsigned long)fsnotify_connector_inode(chunk->mark.connector);
>  }
>  
>  static inline struct list_head *chunk_hash(unsigned long key)
> @@ -258,7 +258,7 @@ static void untag_chunk(struct node *p)
>  	spin_lock(&entry->lock);
>  	/*
>  	 * mark_mutex protects mark from getting detached and thus also from
> -	 * mark->connector->inode getting NULL.
> +	 * mark->connector->obj getting NULL.
>  	 */
>  	if (chunk->dead || !(entry->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) {
>  		spin_unlock(&entry->lock);
> @@ -288,8 +288,9 @@ static void untag_chunk(struct node *p)
>  	if (!new)
>  		goto Fallback;
>  
> -	if (fsnotify_add_inode_mark_locked(&new->mark, entry->connector->inode,
> -					   1)) {
> +	if (fsnotify_add_inode_mark_locked(&new->mark,
> +				fsnotify_connector_inode(entry->connector),
> +				1)) {
>  		fsnotify_put_mark(&new->mark);
>  		goto Fallback;
>  	}
> @@ -434,7 +435,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
>  	}
>  
>  	if (fsnotify_add_inode_mark_locked(chunk_entry,
> -			     old_entry->connector->inode, 1)) {
> +			fsnotify_connector_inode(old_entry->connector), 1)) {
>  		spin_unlock(&old_entry->lock);
>  		mutex_unlock(&old_entry->group->mark_mutex);
>  		fsnotify_put_mark(chunk_entry);
> -- 
> 2.7.4
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 00/13] Preparing for fanotify super block marks
  2018-04-20 23:10 [PATCH v3 00/13] Preparing for fanotify super block marks Amir Goldstein
                   ` (12 preceding siblings ...)
  2018-04-20 23:11 ` [PATCH v3 13/13] fanotify: factor out helpers to add/remove mark Amir Goldstein
@ 2018-05-18 13:09 ` Jan Kara
  13 siblings, 0 replies; 18+ messages in thread
From: Jan Kara @ 2018-05-18 13:09 UTC (permalink / raw)
  To: Amir Goldstein; +Cc: Jan Kara, linux-fsdevel

Hi Amir,

On Fri 20-04-18 16:10:48, Amir Goldstein wrote:
> Per your request, here is the prep series for super block mark, with
> all review comments addressed and rebased on your for_next branch.
> 
> For those interested in the super block marks work, here are the
> patches [1] and ltp tests [2]. I hope we can iron out any remaining
> concerns during LSF/MM.

I'm sorry that it took me long to get to this again but I've merged all
your patches with small modifications mentioned in replies to individual
patches and plan on pushing them to Linus in the next merge window.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2018-05-18 13:09 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH v3 04/13] fsnotify: generalize iteration of marks by object type Amir Goldstein
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

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).