diff mbox

[RFC,6/7] fanotify: add support for create/attrib/rename/delete events

Message ID 1476126784-12520-7-git-send-email-amir73il@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Amir Goldstein Oct. 10, 2016, 7:13 p.m. UTC
Add support for create/attrib/rename/delete events with data type
FSNOTIFY_EVENT_DENTRY, which can be reported on a watched
directory inode.

New dentry events may pass parent directory's path on event fd,
which may break old programs that request FAN_ALL_EVENTS.
Ignore dentry events unless user explicitly set the new
FAN_EVENT_INFO_PARENT flag to fanotify_init().

A mount watch cannot get dentry events, because the mount point
from which those events were created is unavailable inforamtion.

Legacy inotify events that are still not supported are
DELETE_SELF and MOVE_FROM, whose event data type is still
FSNOTIFY_EVENT_INODE.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.c      |  7 +++++++
 fs/notify/fanotify/fanotify_user.c | 12 ++++++++++++
 include/uapi/linux/fanotify.h      | 26 ++++++++++++++++++++++----
 3 files changed, 41 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index fb2b852..378101c 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -212,9 +212,16 @@  static int fanotify_handle_event(struct fsnotify_group *group,
 
 	BUILD_BUG_ON(FAN_ACCESS != FS_ACCESS);
 	BUILD_BUG_ON(FAN_MODIFY != FS_MODIFY);
+	BUILD_BUG_ON(FAN_ATTRIB != FS_ATTRIB);
 	BUILD_BUG_ON(FAN_CLOSE_NOWRITE != FS_CLOSE_NOWRITE);
 	BUILD_BUG_ON(FAN_CLOSE_WRITE != FS_CLOSE_WRITE);
 	BUILD_BUG_ON(FAN_OPEN != FS_OPEN);
+	BUILD_BUG_ON(FAN_MOVED_TO != FS_MOVED_TO);
+	BUILD_BUG_ON(FAN_MOVED_FROM != FS_MOVED_FROM);
+	BUILD_BUG_ON(FAN_CREATE != FS_CREATE);
+	BUILD_BUG_ON(FAN_DELETE != FS_DELETE);
+	BUILD_BUG_ON(FAN_DELETE_SELF != FS_DELETE_SELF);
+	BUILD_BUG_ON(FAN_MOVE_SELF != FS_MOVE_SELF);
 	BUILD_BUG_ON(FAN_EVENT_ON_CHILD != FS_EVENT_ON_CHILD);
 	BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW);
 	BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM);
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 789962c..616769a 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -907,6 +907,18 @@  SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags,
 	    group->fanotify_data.flags & FAN_EVENT_INFO_PARENT)
 		mnt = path.mnt;
 
+	/*
+	 * New dentry events may pass parent directory's path on event fd,
+	 * which may break old programs that request FAN_ALL_EVENTS.
+	 * Ignore dentry events unless user explicitly set the new
+	 * FAN_EVENT_INFO_PARENT flag to fanotify_init().
+	 * Mount watch cannot get dentry events, because the mount point
+	 * from which those events were created is unavailable inforamtion.
+	 */
+	if ((flags & FAN_MARK_MOUNT) ||
+	    !(group->fanotify_data.flags & FAN_EVENT_INFO_PARENT))
+		mask &= ~FAN_DENTRY_EVENTS;
+
 	/* create/update an inode mark */
 	switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
 	case FAN_MARK_ADD:
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index 8e58765..3389da0 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -6,9 +6,17 @@ 
 /* the following events that user-space can register for */
 #define FAN_ACCESS		0x00000001	/* File was accessed */
 #define FAN_MODIFY		0x00000002	/* File was modified */
+#define FAN_ATTRIB		0x00000004	/* Metadata changed */
 #define FAN_CLOSE_WRITE		0x00000008	/* Writtable file closed */
 #define FAN_CLOSE_NOWRITE	0x00000010	/* Unwrittable file closed */
 #define FAN_OPEN		0x00000020	/* File was opened */
+#define FAN_MOVED_FROM		0x00000040	/* File was moved from X */
+#define FAN_MOVED_TO		0x00000080	/* File was moved to Y */
+#define FAN_CREATE		0x00000100	/* Subfile was created */
+#define FAN_DELETE		0x00000200	/* Subfile was deleted */
+#define FAN_DELETE_SELF		0x00000400	/* Self was deleted */
+#define FAN_MOVE_SELF		0x00000800	/* Self was moved */
+
 
 #define FAN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
 
@@ -21,6 +29,7 @@ 
 
 /* helper events */
 #define FAN_CLOSE		(FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
+#define FAN_MOVE		(FAN_MOVED_FROM | FAN_MOVED_TO) /* moves */
 
 /* flags used for fanotify_init() */
 #define FAN_CLOEXEC		0x00000001
@@ -69,10 +78,19 @@ 
  * the future and not break backward compatibility.  Apps will get only the
  * events that they originally wanted.  Be sure to add new events here!
  */
-#define FAN_ALL_EVENTS (FAN_ACCESS |\
-			FAN_MODIFY |\
-			FAN_CLOSE |\
-			FAN_OPEN)
+
+/* Events reported with data type FSNOTIFY_EVENT_PATH */
+#define FAN_PATH_EVENTS (FAN_ACCESS |\
+			 FAN_MODIFY |\
+			 FAN_CLOSE |\
+			 FAN_OPEN)
+
+/* Events reported with data type FSNOTIFY_EVENT_DENTRY */
+#define FAN_DENTRY_EVENTS (FAN_ATTRIB |\
+			   FAN_MOVED_TO | FAN_MOVE_SELF |\
+			   FAN_CREATE | FAN_DELETE)
+
+#define FAN_ALL_EVENTS (FAN_PATH_EVENTS | FAN_DENTRY_EVENTS)
 
 /*
  * All events which require a permission response from userspace