All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Matthew Bobrowski <mbobrowski@mbobrowski.org>,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH v3 05/13] fanotify: classify events that hold a file identifier
Date: Sun, 25 Nov 2018 15:43:44 +0200	[thread overview]
Message-ID: <20181125134352.21499-6-amir73il@gmail.com> (raw)
In-Reply-To: <20181125134352.21499-1-amir73il@gmail.com>

With group flag FAN_REPORT_FID, we do not store event->path.
Instead, we will store the file handle and fsid in event->info.fid.

Because event->info and event->path share the same union space, set
bit 0 of event->info.flags, so we know how to free and compare the
event objects.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c      | 35 ++++++++++++++++++++++++------
 fs/notify/fanotify/fanotify.h      | 27 +++++++++++++++++++++++
 fs/notify/fanotify/fanotify_user.c |  3 +++
 3 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 59d093923c97..8192d4b1db21 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -25,11 +25,16 @@ static bool should_merge(struct fsnotify_event *old_fsn,
 	old = FANOTIFY_E(old_fsn);
 	new = FANOTIFY_E(new_fsn);
 
-	if (old_fsn->inode == new_fsn->inode && old->pid == new->pid &&
-	    old->path.mnt == new->path.mnt &&
-	    old->path.dentry == new->path.dentry)
-		return true;
-	return false;
+	if (old_fsn->inode != new_fsn->inode || old->pid != new->pid)
+		return false;
+
+	if (FANOTIFY_HAS_FID(new)) {
+		return FANOTIFY_HAS_FID(old) &&
+			fanotify_fid_equal(old->info.fid, new->info.fid);
+	} else {
+		return old->path.mnt == new->path.mnt &&
+			old->path.dentry == new->path.dentry;
+	}
 }
 
 /* and the list better be locked by something too! */
@@ -178,7 +183,10 @@ init: __maybe_unused
 		event->pid = get_pid(task_pid(current));
 	else
 		event->pid = get_pid(task_tgid(current));
-	if (path && !FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
+	if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
+		/* TODO: allocate buffer and encode file handle */
+		fanotify_set_fid(event, NULL);
+	} else if (path) {
 		event->path = *path;
 		path_get(&event->path);
 	} else {
@@ -277,8 +285,21 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event)
 {
 	struct fanotify_event *event;
 
+	/*
+	 * event->path and event->info are a union. Make sure that
+	 * event->info.flags overlaps with path.dentry pointer, so it is safe
+	 * to use bit 0 to classify the event info type (FANOTIFY_HAS_FID).
+	 */
+	BUILD_BUG_ON(offsetof(struct fanotify_event, path.dentry) !=
+		     offsetof(struct fanotify_event, info.flags));
+	BUILD_BUG_ON(!__builtin_types_compatible_p(typeof(event->info.flags),
+						   unsigned long));
+
 	event = FANOTIFY_E(fsn_event);
-	path_put(&event->path);
+	if (FANOTIFY_HAS_FID(event))
+		kfree(event->info.fid);
+	else
+		path_put(&event->path);
 	put_pid(event->pid);
 	if (fanotify_is_perm_event(fsn_event->mask)) {
 		kmem_cache_free(fanotify_perm_event_cachep,
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index 2e4fca30afda..a79dcbd41702 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -13,8 +13,20 @@ extern struct kmem_cache *fanotify_perm_event_cachep;
 
 struct fanotify_info {
 	struct fanotify_event_fid *fid;
+	unsigned long flags;
 };
 
+static inline bool fanotify_fid_equal(const struct fanotify_event_fid *fid1,
+				      const struct fanotify_event_fid *fid2)
+{
+	if (fid1 == fid2)
+		return true;
+
+	return fid1 && fid2 && fid1->handle_bytes == fid2->handle_bytes &&
+		!memcmp((void *)fid1, (void *)fid2,
+			FANOTIFY_FID_LEN(fid1->handle_bytes));
+}
+
 /*
  * Structure for normal fanotify events. It gets allocated in
  * fanotify_handle_event() and freed when the information is retrieved by
@@ -38,6 +50,21 @@ struct fanotify_event {
 	struct pid *pid;
 };
 
+/*
+ * Bit 0 of info.flags is set when event has fid information.
+ * event->info shares the same union address with event->path, so this helps
+ * us tell if event has fid or path.
+ */
+#define __FANOTIFY_FID		1UL
+#define FANOTIFY_HAS_FID(event)	((event)->info.flags & __FANOTIFY_FID)
+
+static inline void fanotify_set_fid(struct fanotify_event *event,
+				    struct fanotify_event_fid *fid)
+{
+	event->info.fid = fid;
+	event->info.flags = fid ? __FANOTIFY_FID : 0;
+}
+
 /*
  * Structure for permission fanotify events. It gets allocated and freed in
  * fanotify_handle_event() since we wait there for user response. When the
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 93e1aa2a389f..47e8bf3bcd28 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -81,6 +81,9 @@ static int create_fd(struct fsnotify_group *group,
 
 	pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
+	if (WARN_ON_ONCE(FANOTIFY_HAS_FID(event)))
+		return -EBADF;
+
 	client_fd = get_unused_fd_flags(group->fanotify_data.f_flags);
 	if (client_fd < 0)
 		return client_fd;
-- 
2.17.1

  parent reply	other threads:[~2018-11-26  0:35 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-25 13:43 [PATCH v3 00/13] fanotify: add support for more event types Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 01/13] fsnotify: annotate directory entry modification events Amir Goldstein
2018-11-28 12:59   ` Jan Kara
2018-11-28 14:39     ` Amir Goldstein
2018-11-28 14:43       ` Jan Kara
2018-11-28 15:01         ` Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 02/13] fsnotify: send all event types to super block marks Amir Goldstein
2018-11-28 14:26   ` Jan Kara
2018-11-25 13:43 ` [PATCH v3 03/13] fanotify: rename struct fanotify_{,perm_}event_info Amir Goldstein
2018-11-28 14:29   ` Jan Kara
2018-11-25 13:43 ` [PATCH v3 04/13] fanotify: define the structures to report a unique file identifier Amir Goldstein
2018-11-28 15:27   ` Jan Kara
2018-11-28 16:24     ` Amir Goldstein
2018-11-28 17:43       ` Jan Kara
2018-11-28 18:34         ` Amir Goldstein
2018-11-29  7:51           ` Jan Kara
2018-11-29  8:16             ` Amir Goldstein
2018-11-29 10:16               ` Jan Kara
2018-11-29 11:10                 ` Amir Goldstein
2018-11-30 15:32                 ` Amir Goldstein
2018-12-01 16:43                   ` Amir Goldstein
2018-11-25 13:43 ` Amir Goldstein [this message]
2018-11-28 15:33   ` [PATCH v3 05/13] fanotify: classify events that hold a " Jan Kara
2018-11-28 15:44     ` Jan Kara
2018-11-28 15:52       ` Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 06/13] fanotify: encode file identifier for FAN_REPORT_FID Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 07/13] fanotify: copy event fid info to user Amir Goldstein
2018-11-29  9:00   ` Jan Kara
     [not found]     ` <CAOQ4uxjcb=UqQiw0XcpDfetK28bM4tOYdvgxPwhkjgE2mxpt=g@mail.gmail.com>
2018-11-29  9:49       ` Jan Kara
2018-11-25 13:43 ` [PATCH v3 08/13] fanotify: enable FAN_REPORT_FID init flag Amir Goldstein
2018-11-29  9:46   ` Jan Kara
2018-11-29 10:52     ` Jan Kara
2018-11-29 11:03     ` Amir Goldstein
2018-11-29 13:08       ` Jan Kara
2018-11-25 13:43 ` [PATCH v3 09/13] fanotify: cache fsid in fsnotify_mark_connector Amir Goldstein
2018-11-29 10:48   ` Jan Kara
2018-11-29 11:42     ` Amir Goldstein
2018-11-29 13:11       ` Jan Kara
2018-11-25 13:43 ` [PATCH v3 10/13] fanotify: check FS_ISDIR flag instead of d_is_dir() Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 11/13] fanotify: support events with data type FSNOTIFY_EVENT_INODE Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 12/13] fanotify: add support for create/attrib/move/delete events Amir Goldstein
2018-11-25 13:43 ` [PATCH v3 13/13] fanotify: report FAN_ONDIR to listener with FAN_REPORT_FID 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=20181125134352.21499-6-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mbobrowski@mbobrowski.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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.