]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fanotify: add support for create/attrib/move/delete events
authorAmir Goldstein <amir73il@gmail.com>
Thu, 10 Jan 2019 17:04:43 +0000 (19:04 +0200)
committerJan Kara <jack@suse.cz>
Thu, 7 Feb 2019 15:43:23 +0000 (16:43 +0100)
Add support for events with data type FSNOTIFY_EVENT_INODE
(e.g. create/attrib/move/delete) for inode and filesystem mark types.

The "inode" events do not carry enough information (i.e. path) to
report event->fd, so we do not allow setting a mask for those events
unless group supports reporting fid.

The "inode" events are not supported on a mount mark, because they do
not carry enough information (i.e. path) to be filtered by mount point.

The "dirent" events (create/move/delete) report the fid of the parent
directory where events took place without specifying the filename of the
child. In the future, fanotify may get support for reporting filename
information for those events.

Cc: <linux-api@vger.kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/notify/fanotify/fanotify.c
fs/notify/fanotify/fanotify_user.c
include/linux/fanotify.h
include/uapi/linux/fanotify.h

index 974239b03442cb2966c10e3dd134f4aef50c4102..158c69acb04db06d6c58b0a601b6aadcc5c42bc4 100644 (file)
@@ -313,9 +313,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);
@@ -324,7 +331,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
        BUILD_BUG_ON(FAN_OPEN_EXEC != FS_OPEN_EXEC);
        BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM);
 
-       BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 12);
+       BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 19);
 
        mask = fanotify_group_event_mask(group, iter_info, mask, data,
                                         data_type);
index bf06fd6ef76169533512719f8f9fd6406436cd67..6c61a06d0ef53695b882eb53bbe6b34f3f171661 100644 (file)
@@ -976,6 +976,18 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
            group->priority == FS_PRIO_0)
                goto fput_and_out;
 
+       /*
+        * Events with data type inode do not carry enough information to report
+        * event->fd, so we do not allow setting a mask for inode events unless
+        * group supports reporting fid.
+        * inode events are not supported on a mount mark, because they do not
+        * carry enough information (i.e. path) to be filtered by mount point.
+        */
+       if (mask & FANOTIFY_INODE_EVENTS &&
+           (!FAN_GROUP_FLAG(group, FAN_REPORT_FID) ||
+            mark_type == FAN_MARK_MOUNT))
+               goto fput_and_out;
+
        if (flags & FAN_MARK_FLUSH) {
                ret = 0;
                if (mark_type == FAN_MARK_MOUNT)
index f59be967f72bead6907f50270b49af20488e5c4e..e9d45387089f3b4728ed5591c9fe91b1652a0b81 100644 (file)
                                 FAN_MARK_IGNORED_SURV_MODIFY | \
                                 FAN_MARK_FLUSH)
 
-/* Events that user can request to be notified on */
-#define FANOTIFY_EVENTS                (FAN_ACCESS | FAN_MODIFY | \
+/*
+ * Events that can be reported with data type FSNOTIFY_EVENT_PATH.
+ * Note that FAN_MODIFY can also be reported with data type
+ * FSNOTIFY_EVENT_INODE.
+ */
+#define FANOTIFY_PATH_EVENTS   (FAN_ACCESS | FAN_MODIFY | \
                                 FAN_CLOSE | FAN_OPEN | FAN_OPEN_EXEC)
 
+/*
+ * Directory entry modification events - reported only to directory
+ * where entry is modified and not to a watching parent.
+ */
+#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE)
+
+/* Events that can only be reported with data type FSNOTIFY_EVENT_INODE */
+#define FANOTIFY_INODE_EVENTS  (FANOTIFY_DIRENT_EVENTS | \
+                                FAN_ATTRIB | FAN_MOVE_SELF | FAN_DELETE_SELF)
+
+/* Events that user can request to be notified on */
+#define FANOTIFY_EVENTS                (FANOTIFY_PATH_EVENTS | \
+                                FANOTIFY_INODE_EVENTS)
+
 /* Events that require a permission response from user */
 #define FANOTIFY_PERM_EVENTS   (FAN_OPEN_PERM | FAN_ACCESS_PERM | \
                                 FAN_OPEN_EXEC_PERM)
index 959ae2bdc7caa9d389ee0484dc7fed61ff49dc6d..b9effa6f8503767a43ba167acd62bce7e94c2eb8 100644 (file)
@@ -7,9 +7,16 @@
 /* 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_OPEN_EXEC          0x00001000      /* File was opened for exec */
 
 #define FAN_Q_OVERFLOW         0x00004000      /* Event queued overflowed */
@@ -24,6 +31,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