inotify: convert to handle_inode_event() interface
authorAmir Goldstein <amir73il@gmail.com>
Wed, 2 Dec 2020 12:07:08 +0000 (14:07 +0200)
committerJan Kara <jack@suse.cz>
Thu, 3 Dec 2020 14:41:29 +0000 (15:41 +0100)
Convert inotify to use the simple handle_inode_event() interface to
get rid of the code duplication between the generic helper
fsnotify_handle_event() and the inotify_handle_event() callback, which
also happen to be buggy code.

The bug will be fixed in the generic helper.

Link: https://lore.kernel.org/r/20201202120713.702387-3-amir73il@gmail.com
CC: stable@vger.kernel.org
Fixes: b9a1b9772509 ("fsnotify: create method handle_inode_event() in fsnotify_operations")
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/notify/inotify/inotify.h
fs/notify/inotify/inotify_fsnotify.c
fs/notify/inotify/inotify_user.c

index 4327d0e..2007e37 100644 (file)
@@ -24,11 +24,10 @@ static inline struct inotify_event_info *INOTIFY_E(struct fsnotify_event *fse)
 
 extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
                                           struct fsnotify_group *group);
-extern int inotify_handle_event(struct fsnotify_group *group, u32 mask,
-                               const void *data, int data_type,
-                               struct inode *dir,
-                               const struct qstr *file_name, u32 cookie,
-                               struct fsnotify_iter_info *iter_info);
+extern int inotify_handle_inode_event(struct fsnotify_mark *inode_mark,
+                                     u32 mask, struct inode *inode,
+                                     struct inode *dir,
+                                     const struct qstr *name, u32 cookie);
 
 extern const struct fsnotify_ops inotify_fsnotify_ops;
 extern struct kmem_cache *inotify_inode_mark_cachep;
index 9ddcbad..1901d79 100644 (file)
@@ -55,25 +55,21 @@ static int inotify_merge(struct list_head *list,
        return event_compare(last_event, event);
 }
 
-static int inotify_one_event(struct fsnotify_group *group, u32 mask,
-                            struct fsnotify_mark *inode_mark,
-                            const struct path *path,
-                            const struct qstr *file_name, u32 cookie)
+int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
+                              struct inode *inode, struct inode *dir,
+                              const struct qstr *name, u32 cookie)
 {
        struct inotify_inode_mark *i_mark;
        struct inotify_event_info *event;
        struct fsnotify_event *fsn_event;
+       struct fsnotify_group *group = inode_mark->group;
        int ret;
        int len = 0;
        int alloc_len = sizeof(struct inotify_event_info);
        struct mem_cgroup *old_memcg;
 
-       if ((inode_mark->mask & FS_EXCL_UNLINK) &&
-           path && d_unlinked(path->dentry))
-               return 0;
-
-       if (file_name) {
-               len = file_name->len;
+       if (name) {
+               len = name->len;
                alloc_len += len + 1;
        }
 
@@ -117,7 +113,7 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask,
        event->sync_cookie = cookie;
        event->name_len = len;
        if (len)
-               strcpy(event->name, file_name->name);
+               strcpy(event->name, name->name);
 
        ret = fsnotify_add_event(group, fsn_event, inotify_merge);
        if (ret) {
@@ -131,37 +127,6 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask,
        return 0;
 }
 
-int inotify_handle_event(struct fsnotify_group *group, u32 mask,
-                        const void *data, int data_type, struct inode *dir,
-                        const struct qstr *file_name, u32 cookie,
-                        struct fsnotify_iter_info *iter_info)
-{
-       const struct path *path = fsnotify_data_path(data, data_type);
-       struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
-       struct fsnotify_mark *child_mark = fsnotify_iter_child_mark(iter_info);
-       int ret = 0;
-
-       if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
-               return 0;
-
-       /*
-        * Some events cannot be sent on both parent and child marks
-        * (e.g. IN_CREATE).  Those events are always sent on inode_mark.
-        * For events that are possible on both parent and child (e.g. IN_OPEN),
-        * event is sent on inode_mark with name if the parent is watching and
-        * is sent on child_mark without name if child is watching.
-        * If both parent and child are watching, report the event with child's
-        * name here and report another event without child's name below.
-        */
-       if (inode_mark)
-               ret = inotify_one_event(group, mask, inode_mark, path,
-                                       file_name, cookie);
-       if (ret || !child_mark)
-               return ret;
-
-       return inotify_one_event(group, mask, child_mark, path, NULL, 0);
-}
-
 static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group)
 {
        inotify_ignored_and_remove_idr(fsn_mark, group);
@@ -227,7 +192,7 @@ static void inotify_free_mark(struct fsnotify_mark *fsn_mark)
 }
 
 const struct fsnotify_ops inotify_fsnotify_ops = {
-       .handle_event = inotify_handle_event,
+       .handle_inode_event = inotify_handle_inode_event,
        .free_group_priv = inotify_free_group_priv,
        .free_event = inotify_free_event,
        .freeing_mark = inotify_freeing_mark,
index 24d1702..59c1770 100644 (file)
@@ -495,14 +495,10 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
                                    struct fsnotify_group *group)
 {
        struct inotify_inode_mark *i_mark;
-       struct fsnotify_iter_info iter_info = { };
-
-       fsnotify_iter_set_report_type_mark(&iter_info, FSNOTIFY_OBJ_TYPE_INODE,
-                                          fsn_mark);
 
        /* Queue ignore event for the watch */
-       inotify_handle_event(group, FS_IN_IGNORED, NULL, FSNOTIFY_EVENT_NONE,
-                            NULL, NULL, 0, &iter_info);
+       inotify_handle_inode_event(fsn_mark, FS_IN_IGNORED, NULL, NULL, NULL,
+                                  0);
 
        i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
        /* remove this mark from the idr */