All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: <linux-fsdevel@vger.kernel.org>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	Amir Goldstein <amir73il@gmail.com>,
	Paul Moore <paul@paul-moore.com>, Jan Kara <jack@suse.cz>
Subject: [PATCH 25/35] fsnotify: Pass fsnotify_iter_info into handle_event handler
Date: Mon,  3 Apr 2017 17:34:14 +0200	[thread overview]
Message-ID: <20170403153424.24945-26-jack@suse.cz> (raw)
In-Reply-To: <20170403153424.24945-1-jack@suse.cz>

Pass fsnotify_iter_info into ->handle_event() handler so that it can
release and reacquire SRCU lock via fsnotify_prepare_user_wait() and
fsnotify_finish_user_wait() functions.  These functions also make sure
current marks are appropriately pinned so that iteration protected by
srcu in fsnotify() stays safe.

Reviewed-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/notify/dnotify/dnotify.c          |  3 ++-
 fs/notify/fanotify/fanotify.c        |  3 ++-
 fs/notify/fsnotify.c                 | 19 +++++++++++++------
 fs/notify/inotify/inotify.h          |  3 ++-
 fs/notify/inotify/inotify_fsnotify.c |  3 ++-
 fs/notify/inotify/inotify_user.c     |  2 +-
 include/linux/fsnotify_backend.h     |  3 ++-
 kernel/audit_fsnotify.c              |  3 ++-
 kernel/audit_tree.c                  |  3 ++-
 kernel/audit_watch.c                 |  3 ++-
 10 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 41b2a070761c..aba165ae3397 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -85,7 +85,8 @@ static int dnotify_handle_event(struct fsnotify_group *group,
 				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)
+				const unsigned char *file_name, u32 cookie,
+				struct fsnotify_iter_info *iter_info)
 {
 	struct dnotify_mark *dn_mark;
 	struct dnotify_struct *dn;
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index e5f7e47de68e..ec80a51cbb3d 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -174,7 +174,8 @@ static int fanotify_handle_event(struct fsnotify_group *group,
 				 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)
+				 const unsigned char *file_name, u32 cookie,
+				 struct fsnotify_iter_info *iter_info)
 {
 	int ret = 0;
 	struct fanotify_event_info *event;
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index d512ef9f75fc..c4afb6a88268 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -127,7 +127,8 @@ static int send_to_group(struct inode *to_tell,
 			 struct fsnotify_mark *vfsmount_mark,
 			 __u32 mask, const void *data,
 			 int data_is, u32 cookie,
-			 const unsigned char *file_name)
+			 const unsigned char *file_name,
+			 struct fsnotify_iter_info *iter_info)
 {
 	struct fsnotify_group *group = NULL;
 	__u32 inode_test_mask = 0;
@@ -178,7 +179,7 @@ static int send_to_group(struct inode *to_tell,
 
 	return group->ops->handle_event(group, to_tell, inode_mark,
 					vfsmount_mark, mask, data, data_is,
-					file_name, cookie);
+					file_name, cookie, iter_info);
 }
 
 /*
@@ -194,8 +195,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 	struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL;
 	struct fsnotify_group *inode_group, *vfsmount_group;
 	struct fsnotify_mark_connector *inode_conn, *vfsmount_conn;
+	struct fsnotify_iter_info iter_info;
 	struct mount *mnt;
-	int idx, ret = 0;
+	int ret = 0;
 	/* global tests shouldn't care about events on child only the specific event */
 	__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
 
@@ -224,7 +226,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 	    !(mnt && test_mask & mnt->mnt_fsnotify_mask))
 		return 0;
 
-	idx = srcu_read_lock(&fsnotify_mark_srcu);
+	iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
 
 	if ((mask & FS_MODIFY) ||
 	    (test_mask & to_tell->i_fsnotify_mask)) {
@@ -284,8 +286,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 				vfsmount_mark = NULL;
 			}
 		}
+
+		iter_info.inode_mark = inode_mark;
+		iter_info.vfsmount_mark = vfsmount_mark;
+
 		ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
-				    data, data_is, cookie, file_name);
+				    data, data_is, cookie, file_name,
+				    &iter_info);
 
 		if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS))
 			goto out;
@@ -299,7 +306,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 	}
 	ret = 0;
 out:
-	srcu_read_unlock(&fsnotify_mark_srcu, idx);
+	srcu_read_unlock(&fsnotify_mark_srcu, iter_info.srcu_idx);
 
 	return ret;
 }
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h
index 7c461fd49c4c..7a966f456269 100644
--- a/fs/notify/inotify/inotify.h
+++ b/fs/notify/inotify/inotify.h
@@ -27,7 +27,8 @@ extern int inotify_handle_event(struct fsnotify_group *group,
 				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);
+				const unsigned char *file_name, u32 cookie,
+				struct fsnotify_iter_info *iter_info);
 
 extern const struct fsnotify_ops inotify_fsnotify_ops;
 
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index f310d8368a2d..ccd6a4055e0c 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -68,7 +68,8 @@ int inotify_handle_event(struct fsnotify_group *group,
 			 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)
+			 const unsigned char *file_name, u32 cookie,
+			 struct fsnotify_iter_info *iter_info)
 {
 	struct inotify_inode_mark *i_mark;
 	struct inotify_event_info *event;
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 43cbd1b178c9..05b268ec0f5f 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -474,7 +474,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
 
 	/* Queue ignore event for the watch */
 	inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED,
-			     NULL, FSNOTIFY_EVENT_NONE, NULL, 0);
+			     NULL, FSNOTIFY_EVENT_NONE, NULL, 0, NULL);
 
 	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 5bb6d988b9f6..744a4b9076f9 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -99,7 +99,8 @@ struct fsnotify_ops {
 			    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);
+			    const unsigned char *file_name, u32 cookie,
+			    struct fsnotify_iter_info *iter_info);
 	void (*free_group_priv)(struct fsnotify_group *group);
 	void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
 	void (*free_event)(struct fsnotify_event *event);
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c
index 7ea57e516029..e8b371ff1e91 100644
--- a/kernel/audit_fsnotify.c
+++ b/kernel/audit_fsnotify.c
@@ -168,7 +168,8 @@ static int audit_mark_handle_event(struct fsnotify_group *group,
 				    struct fsnotify_mark *inode_mark,
 				    struct fsnotify_mark *vfsmount_mark,
 				    u32 mask, const void *data, int data_type,
-				    const unsigned char *dname, u32 cookie)
+				    const unsigned char *dname, u32 cookie,
+				    struct fsnotify_iter_info *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 672ca1512888..dbd7a9606065 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -989,7 +989,8 @@ static int audit_tree_handle_event(struct fsnotify_group *group,
 				   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)
+				   const unsigned char *file_name, u32 cookie,
+				   struct fsnotify_iter_info *iter_info)
 {
 	return 0;
 }
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index f79e4658433d..6caaf087801f 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -472,7 +472,8 @@ static int audit_watch_handle_event(struct fsnotify_group *group,
 				    struct fsnotify_mark *inode_mark,
 				    struct fsnotify_mark *vfsmount_mark,
 				    u32 mask, const void *data, int data_type,
-				    const unsigned char *dname, u32 cookie)
+				    const unsigned char *dname, u32 cookie,
+				    struct fsnotify_iter_info *iter_info)
 {
 	const struct inode *inode;
 	struct audit_parent *parent;
-- 
2.10.2

  parent reply	other threads:[~2017-04-03 15:34 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-03 15:33 [PATCH 0/35 v7] fsnotify: Avoid SRCU stalls with fanotify permission events Jan Kara
2017-04-03 15:33 ` [PATCH 01/35] fsnotify: Remove unnecessary tests when showing fdinfo Jan Kara
2017-04-03 15:33 ` [PATCH 02/35] inotify: Remove inode pointers from debug messages Jan Kara
2017-04-03 15:33 ` [PATCH 03/35] fanotify: Move recalculation of inode / vfsmount mask under mark_mutex Jan Kara
2017-04-03 15:33 ` [PATCH 04/35] audit: Abstract hash key handling Jan Kara
2017-04-04 20:38   ` Paul Moore
2017-04-03 15:33 ` [PATCH 05/35] audit_tree: Use mark flags to check whether mark is alive Jan Kara
2017-04-04 20:47   ` Paul Moore
2017-04-05  7:38     ` Jan Kara
2017-04-06 11:51       ` Paul Moore
2017-04-10 15:31         ` Jan Kara
2017-04-10 15:43           ` Jan Kara
2017-04-11 20:27             ` Paul Moore
2017-04-03 15:33 ` [PATCH 06/35] fsnotify: Update comments Jan Kara
2017-04-03 15:33 ` [PATCH 07/35] fsnotify: Move mark list head from object into dedicated structure Jan Kara
2017-04-03 15:33 ` [PATCH 08/35] fsnotify: Move object pointer to fsnotify_mark_connector Jan Kara
2017-04-03 15:33 ` [PATCH 09/35] fsnotify: Make fsnotify_mark_connector hold inode reference Jan Kara
2017-04-03 15:33 ` [PATCH 10/35] fsnotify: Remove indirection from mark list addition Jan Kara
2017-04-03 15:34 ` [PATCH 11/35] fsnotify: Move fsnotify_destroy_marks() Jan Kara
2017-04-03 15:34 ` [PATCH 12/35] fsnotify: Move locking into fsnotify_recalc_mask() Jan Kara
2017-04-03 15:34 ` [PATCH 13/35] fsnotify: Move locking into fsnotify_find_mark() Jan Kara
2017-04-03 15:34 ` [PATCH 14/35] fsnotify: Determine lock in fsnotify_destroy_marks() Jan Kara
2017-04-03 15:34 ` [PATCH 15/35] fsnotify: Remove indirection from fsnotify_detach_mark() Jan Kara
2017-04-03 15:34 ` [PATCH 16/35] fsnotify: Avoid double locking in fsnotify_detach_from_object() Jan Kara
2017-04-03 15:34 ` [PATCH 17/35] fsnotify: Remove useless list deletion and comment Jan Kara
2017-04-03 15:34 ` [PATCH 18/35] fsnotify: Lock object list with connector lock Jan Kara
2017-04-03 15:34 ` [PATCH 19/35] fsnotify: Free fsnotify_mark_connector when there is no mark attached Jan Kara
2017-04-03 15:34 ` [PATCH 20/35] inotify: Do not drop mark reference under idr_lock Jan Kara
2017-04-03 15:34 ` [PATCH 21/35] fsnotify: Move queueing of mark for destruction into fsnotify_put_mark() Jan Kara
2017-04-03 15:34 ` [PATCH 22/35] fsnotify: Detach mark from object list when last reference is dropped Jan Kara
2017-04-03 15:34 ` [PATCH 23/35] fsnotify: Remove special handling of mark destruction on group shutdown Jan Kara
2017-04-03 15:34 ` [PATCH 24/35] fsnotify: Provide framework for dropping SRCU lock in ->handle_event Jan Kara
2017-04-03 15:34 ` Jan Kara [this message]
2017-04-03 15:34 ` [PATCH 26/35] fanotify: Release SRCU lock when waiting for userspace response Jan Kara
2017-04-03 15:34 ` [PATCH 27/35] fsnotify: Remove fsnotify_set_mark_{,ignored_}mask_locked() Jan Kara
2017-04-03 15:34 ` [PATCH 28/35] fsnotify: Remove fsnotify_recalc_{inode|vfsmount}_mask() Jan Kara
2017-04-03 15:34 ` [PATCH 29/35] fsnotify: Inline fsnotify_clear_{inode|vfsmount}_mark_group() Jan Kara
2017-04-03 15:34 ` [PATCH 30/35] fsnotify: Rename fsnotify_clear_marks_by_group_flags() Jan Kara
2017-04-03 15:34 ` [PATCH 31/35] fsnotify: Remove fsnotify_detach_group_marks() Jan Kara
2017-04-03 15:34 ` [PATCH 32/35] fsnotify: Remove fsnotify_find_{inode|vfsmount}_mark() Jan Kara
2017-04-03 15:34 ` [PATCH 33/35] fsnotify: Drop inode_mark.c Jan Kara
2017-04-03 15:34 ` [PATCH 34/35] fsnotify: Add group pointer in fsnotify_init_mark() Jan Kara
2017-04-03 15:34 ` [PATCH 35/35] fsnotify: Move ->free_mark callback to fsnotify_ops Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170403153424.24945-26-jack@suse.cz \
    --to=jack@suse.cz \
    --cc=amir73il@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=paul@paul-moore.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.