linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Eric Paris <eparis@redhat.com>,
	Marko Rauhamaa <marko.rauhamaa@f-secure.com>,
	linux-fsdevel@vger.kernel.org
Subject: [RFC][PATCH 2/6] fanotify: report events to sb root with fanotify_file_event_info
Date: Mon, 13 Mar 2017 15:20:19 +0200	[thread overview]
Message-ID: <1489411223-12081-3-git-send-email-amir73il@gmail.com> (raw)
In-Reply-To: <1489411223-12081-1-git-send-email-amir73il@gmail.com>

Allocate variable length fanotify_file_event_info struct to
report events when FAN_EVENT_ON_SB mask is set on event.

This is needed to provide extra info on the event for the
super block watcher.

An exception is made for permission event which use the
fanotify_perm_event_info struct also when reporting to
super block watcher.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c      | 19 +++++++++++++------
 fs/notify/fanotify/fanotify.h      | 21 +++++++++++++++++++++
 fs/notify/fanotify/fanotify_user.c |  8 ++++----
 3 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 67feeb6..8a88d88 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -41,7 +41,7 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
 	 * the event structure we have created in fanotify_handle_event() is the
 	 * one we should check for permission response.
 	 */
-	if (event->mask & FAN_ALL_PERM_EVENTS)
+	if (FANOTIFY_IS_PE(event))
 		return 0;
 #endif
 
@@ -169,11 +169,18 @@ struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
 #endif
 
 	/*
-	 * For filename events (create,delete,rename), path points to the
+	 * For filename events (create,delete,move), path points to the
 	 * directory and name holds the entry name, so allocate a variable
 	 * length fanotify_file_event_info struct.
+	 *
+	 * When non permission events are reported on super block root watch,
+	 * they may need to carry extra file information. So alway allocate
+	 * fanotify_file_event_info struct for those events, even if data len
+	 * end up being 0.
+	 * This makes it easier to know when an event struct should be cast
+	 * to FANOTIFY_FE(), e.g. in fanotify_free_event().
 	 */
-	if (mask & FAN_FILENAME_EVENTS) {
+	if (mask & (FAN_FILENAME_EVENTS | FAN_EVENT_ON_SB)) {
 		struct fanotify_file_event_info *ffe;
 		int alloc_len = sizeof(*ffe);
 		int len = 0;
@@ -276,7 +283,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
 	}
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
-	if (mask & FAN_ALL_PERM_EVENTS) {
+	if (FANOTIFY_IS_PE(fsn_event)) {
 		ret = fanotify_get_response(group, FANOTIFY_PE(fsn_event));
 		fsnotify_destroy_event(group, fsn_event);
 	}
@@ -301,13 +308,13 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event)
 	path_put(&event->path);
 	put_pid(event->tgid);
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
-	if (fsn_event->mask & FAN_ALL_PERM_EVENTS) {
+	if (FANOTIFY_IS_PE(fsn_event)) {
 		kmem_cache_free(fanotify_perm_event_cachep,
 				FANOTIFY_PE(fsn_event));
 		return;
 	}
 #endif
-	if (fsn_event->mask & FAN_FILENAME_EVENTS) {
+	if (FANOTIFY_IS_FE(fsn_event)) {
 		kfree(FANOTIFY_FE(fsn_event));
 		return;
 	}
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index d0bb7acb4..d23b35b 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -54,8 +54,29 @@ FANOTIFY_PE(struct fsnotify_event *fse)
 {
 	return container_of(fse, struct fanotify_perm_event_info, fae.fse);
 }
+
+/* Should use fanotify_perm_event_info for this event? */
+static inline bool FANOTIFY_IS_PE(struct fsnotify_event *fse)
+{
+	return fse->mask & FAN_ALL_PERM_EVENTS;
+}
+#else
+static inline bool FANOTIFY_IS_PE(struct fsnotify_event *fse)
+{
+	return false;
+}
 #endif
 
+/* Should use fanotify_file_event_info for this event? */
+static inline bool FANOTIFY_IS_FE(struct fsnotify_event *fse)
+{
+	if (FANOTIFY_IS_PE(fse))
+		return false;
+
+	/* Non permission events reported on root may carry file info */
+	return fse->mask & (FAN_FILENAME_EVENTS | FAN_EVENT_ON_SB);
+}
+
 static inline struct fanotify_file_event_info *
 FANOTIFY_FE(struct fsnotify_event *fse)
 {
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index e57c82a..191bd7d 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -229,7 +229,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
 	if (ret < 0)
 		return ret;
 
-	if ((event->mask & FAN_FILENAME_EVENTS) &&
+	if (FANOTIFY_IS_FE(event) &&
 	    (group->fanotify_data.flags & FAN_EVENT_INFO_NAME)) {
 		ffe = FANOTIFY_FE(event);
 		pad_name_len = round_event_name_len(ffe);
@@ -261,7 +261,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
 	}
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
-	if (event->mask & FAN_ALL_PERM_EVENTS)
+	if (FANOTIFY_IS_PE(event))
 		FANOTIFY_PE(event)->fd = fd;
 #endif
 
@@ -338,7 +338,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
 		 * Permission events get queued to wait for response.  Other
 		 * events can be destroyed now.
 		 */
-		if (!(kevent->mask & FAN_ALL_PERM_EVENTS)) {
+		if (!FANOTIFY_IS_PE(kevent)) {
 			fsnotify_destroy_event(group, kevent);
 			if (ret < 0)
 				break;
@@ -428,7 +428,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
 	 */
 	while (!fsnotify_notify_queue_is_empty(group)) {
 		fsn_event = fsnotify_remove_first_event(group);
-		if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS)) {
+		if (!FANOTIFY_IS_PE(fsn_event)) {
 			spin_unlock(&group->notification_lock);
 			fsnotify_destroy_event(group, fsn_event);
 			spin_lock(&group->notification_lock);
-- 
2.7.4

  parent reply	other threads:[~2017-03-13 13:21 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-13 13:20 [RFC][PATCH 0/6] fanotify: super block root watch Amir Goldstein
2017-03-13 13:20 ` [RFC][PATCH 1/6] fanotify: add a " Amir Goldstein
2017-03-13 13:20 ` Amir Goldstein [this message]
2017-03-13 13:20 ` [RFC][PATCH 3/6] fanotify: pass file handle on sb root watcher events Amir Goldstein
2017-03-13 13:20 ` [RFC][PATCH 4/6] fanotify: report file name to root inode watch with FS_EVENT_ON_CHILD Amir Goldstein
2017-03-13 13:20 ` [RFC][PATCH 5/6] fanotify: export FAN_ONDIR to user Amir Goldstein
2017-03-13 13:20 ` [RFC][PATCH 6/6] fanotify: filter events by root mark mount point Amir Goldstein

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1489411223-12081-3-git-send-email-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=eparis@redhat.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=marko.rauhamaa@f-secure.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 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).