fsnotify: use helpers to access data by data_type
authorAmir Goldstein <amir73il@gmail.com>
Thu, 19 Mar 2020 15:10:12 +0000 (17:10 +0200)
committerJan Kara <jack@suse.cz>
Mon, 23 Mar 2020 17:19:06 +0000 (18:19 +0100)
Create helpers to access path and inode from different data types.

Link: https://lore.kernel.org/r/20200319151022.31456-5-amir73il@gmail.com
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/notify/fanotify/fanotify.c
fs/notify/fsnotify.c
fs/notify/inotify/inotify_fsnotify.c
include/linux/fsnotify_backend.h
kernel/audit_fsnotify.c
kernel/audit_watch.c

index 5778d13..19ec7a4 100644 (file)
@@ -151,7 +151,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
 {
        __u32 marks_mask = 0, marks_ignored_mask = 0;
        __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS;
-       const struct path *path = data;
+       const struct path *path = fsnotify_data_path(data, data_type);
        struct fsnotify_mark *mark;
        int type;
 
@@ -160,7 +160,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
 
        if (!FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
                /* Do we have path to open a file descriptor? */
-               if (data_type != FSNOTIFY_EVENT_PATH)
+               if (!path)
                        return 0;
                /* Path type events are only relevant for files and dirs */
                if (!d_is_reg(path->dentry) && !d_can_lookup(path->dentry))
@@ -269,11 +269,8 @@ static struct inode *fanotify_fid_inode(struct inode *to_tell, u32 event_mask,
 {
        if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS)
                return to_tell;
-       else if (data_type == FSNOTIFY_EVENT_INODE)
-               return (struct inode *)data;
-       else if (data_type == FSNOTIFY_EVENT_PATH)
-               return d_inode(((struct path *)data)->dentry);
-       return NULL;
+
+       return (struct inode *)fsnotify_data_inode(data, data_type);
 }
 
 struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
@@ -284,6 +281,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
        struct fanotify_event *event = NULL;
        gfp_t gfp = GFP_KERNEL_ACCOUNT;
        struct inode *id = fanotify_fid_inode(inode, mask, data, data_type);
+       const struct path *path = fsnotify_data_path(data, data_type);
 
        /*
         * For queues with unlimited length lost events are not expected and
@@ -324,10 +322,10 @@ init: __maybe_unused
        if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
                /* Report the event without a file identifier on encode error */
                event->fh_type = fanotify_encode_fid(event, id, gfp, fsid);
-       } else if (data_type == FSNOTIFY_EVENT_PATH) {
+       } else if (path) {
                event->fh_type = FILEID_ROOT;
-               event->path = *((struct path *)data);
-               path_get(&event->path);
+               event->path = *path;
+               path_get(path);
        } else {
                event->fh_type = FILEID_INVALID;
                event->path.mnt = NULL;
index 46f2255..a5d6467 100644 (file)
@@ -318,6 +318,7 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info)
 int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
             const struct qstr *file_name, u32 cookie)
 {
+       const struct path *path = fsnotify_data_path(data, data_is);
        struct fsnotify_iter_info iter_info = {};
        struct super_block *sb = to_tell->i_sb;
        struct mount *mnt = NULL;
@@ -325,8 +326,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
        int ret = 0;
        __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);
 
-       if (data_is == FSNOTIFY_EVENT_PATH) {
-               mnt = real_mount(((const struct path *)data)->mnt);
+       if (path) {
+               mnt = real_mount(path->mnt);
                mnt_or_sb_mask |= mnt->mnt_fsnotify_mask;
        }
        /* An event "on child" is not intended for a mount/sb mark */
index d510223..6bb9852 100644 (file)
@@ -61,6 +61,7 @@ int inotify_handle_event(struct fsnotify_group *group,
                         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 inotify_inode_mark *i_mark;
        struct inotify_event_info *event;
@@ -73,12 +74,9 @@ int inotify_handle_event(struct fsnotify_group *group,
                return 0;
 
        if ((inode_mark->mask & FS_EXCL_UNLINK) &&
-           (data_type == FSNOTIFY_EVENT_PATH)) {
-               const struct path *path = data;
+           path && d_unlinked(path->dentry))
+               return 0;
 
-               if (d_unlinked(path->dentry))
-                       return 0;
-       }
        if (file_name) {
                len = file_name->len;
                alloc_len += len + 1;
index db3cabb..5cc838d 100644 (file)
@@ -212,10 +212,36 @@ struct fsnotify_group {
        };
 };
 
-/* when calling fsnotify tell it if the data is a path or inode */
-#define FSNOTIFY_EVENT_NONE    0
-#define FSNOTIFY_EVENT_PATH    1
-#define FSNOTIFY_EVENT_INODE   2
+/* When calling fsnotify tell it if the data is a path or inode */
+enum fsnotify_data_type {
+       FSNOTIFY_EVENT_NONE,
+       FSNOTIFY_EVENT_PATH,
+       FSNOTIFY_EVENT_INODE,
+};
+
+static inline const struct inode *fsnotify_data_inode(const void *data,
+                                                     int data_type)
+{
+       switch (data_type) {
+       case FSNOTIFY_EVENT_INODE:
+               return data;
+       case FSNOTIFY_EVENT_PATH:
+               return d_inode(((const struct path *)data)->dentry);
+       default:
+               return NULL;
+       }
+}
+
+static inline const struct path *fsnotify_data_path(const void *data,
+                                                   int data_type)
+{
+       switch (data_type) {
+       case FSNOTIFY_EVENT_PATH:
+               return data;
+       default:
+               return NULL;
+       }
+}
 
 enum fsnotify_obj_type {
        FSNOTIFY_OBJ_TYPE_INODE,
index f0d2433..3596448 100644 (file)
@@ -160,23 +160,14 @@ static int audit_mark_handle_event(struct fsnotify_group *group,
 {
        struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
        struct audit_fsnotify_mark *audit_mark;
-       const struct inode *inode = NULL;
+       const struct inode *inode = fsnotify_data_inode(data, data_type);
 
        audit_mark = container_of(inode_mark, struct audit_fsnotify_mark, mark);
 
        BUG_ON(group != audit_fsnotify_group);
 
-       switch (data_type) {
-       case (FSNOTIFY_EVENT_PATH):
-               inode = ((const struct path *)data)->dentry->d_inode;
-               break;
-       case (FSNOTIFY_EVENT_INODE):
-               inode = (const struct inode *)data;
-               break;
-       default:
-               BUG();
+       if (WARN_ON(!inode))
                return 0;
-       }
 
        if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) {
                if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL))
index 4508d5e..dcfbb44 100644 (file)
@@ -473,25 +473,13 @@ static int audit_watch_handle_event(struct fsnotify_group *group,
                                    struct fsnotify_iter_info *iter_info)
 {
        struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
-       const struct inode *inode;
+       const struct inode *inode = fsnotify_data_inode(data, data_type);
        struct audit_parent *parent;
 
        parent = container_of(inode_mark, struct audit_parent, mark);
 
        BUG_ON(group != audit_watch_group);
-
-       switch (data_type) {
-       case (FSNOTIFY_EVENT_PATH):
-               inode = d_backing_inode(((const struct path *)data)->dentry);
-               break;
-       case (FSNOTIFY_EVENT_INODE):
-               inode = (const struct inode *)data;
-               break;
-       default:
-               BUG();
-               inode = NULL;
-               break;
-       }
+       WARN_ON(!inode);
 
        if (mask & (FS_CREATE|FS_MOVED_TO) && inode)
                audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0);