Commit aa93bdc5 authored by Amir Goldstein's avatar Amir Goldstein Committed by Jan Kara

fsnotify: use helpers to access data by data_type

Create helpers to access path and inode from different data types.

Link: https://lore.kernel.org/r/20200319151022.31456-5-amir73il@gmail.comSigned-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent a1aae057
...@@ -151,7 +151,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, ...@@ -151,7 +151,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
{ {
__u32 marks_mask = 0, marks_ignored_mask = 0; __u32 marks_mask = 0, marks_ignored_mask = 0;
__u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS; __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; struct fsnotify_mark *mark;
int type; int type;
...@@ -160,7 +160,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, ...@@ -160,7 +160,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
if (!FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { if (!FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
/* Do we have path to open a file descriptor? */ /* Do we have path to open a file descriptor? */
if (data_type != FSNOTIFY_EVENT_PATH) if (!path)
return 0; return 0;
/* Path type events are only relevant for files and dirs */ /* Path type events are only relevant for files and dirs */
if (!d_is_reg(path->dentry) && !d_can_lookup(path->dentry)) 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, ...@@ -269,11 +269,8 @@ static struct inode *fanotify_fid_inode(struct inode *to_tell, u32 event_mask,
{ {
if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS) if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS)
return to_tell; return to_tell;
else if (data_type == FSNOTIFY_EVENT_INODE)
return (struct inode *)data; return (struct inode *)fsnotify_data_inode(data, data_type);
else if (data_type == FSNOTIFY_EVENT_PATH)
return d_inode(((struct path *)data)->dentry);
return NULL;
} }
struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
...@@ -284,6 +281,7 @@ 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; struct fanotify_event *event = NULL;
gfp_t gfp = GFP_KERNEL_ACCOUNT; gfp_t gfp = GFP_KERNEL_ACCOUNT;
struct inode *id = fanotify_fid_inode(inode, mask, data, data_type); 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 * For queues with unlimited length lost events are not expected and
...@@ -324,10 +322,10 @@ init: __maybe_unused ...@@ -324,10 +322,10 @@ init: __maybe_unused
if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
/* Report the event without a file identifier on encode error */ /* Report the event without a file identifier on encode error */
event->fh_type = fanotify_encode_fid(event, id, gfp, fsid); 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->fh_type = FILEID_ROOT;
event->path = *((struct path *)data); event->path = *path;
path_get(&event->path); path_get(path);
} else { } else {
event->fh_type = FILEID_INVALID; event->fh_type = FILEID_INVALID;
event->path.mnt = NULL; event->path.mnt = NULL;
......
...@@ -318,6 +318,7 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info) ...@@ -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, int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
const struct qstr *file_name, u32 cookie) const struct qstr *file_name, u32 cookie)
{ {
const struct path *path = fsnotify_data_path(data, data_is);
struct fsnotify_iter_info iter_info = {}; struct fsnotify_iter_info iter_info = {};
struct super_block *sb = to_tell->i_sb; struct super_block *sb = to_tell->i_sb;
struct mount *mnt = NULL; struct mount *mnt = NULL;
...@@ -325,8 +326,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, ...@@ -325,8 +326,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
int ret = 0; int ret = 0;
__u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS); __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS);
if (data_is == FSNOTIFY_EVENT_PATH) { if (path) {
mnt = real_mount(((const struct path *)data)->mnt); mnt = real_mount(path->mnt);
mnt_or_sb_mask |= mnt->mnt_fsnotify_mask; mnt_or_sb_mask |= mnt->mnt_fsnotify_mask;
} }
/* An event "on child" is not intended for a mount/sb mark */ /* An event "on child" is not intended for a mount/sb mark */
......
...@@ -61,6 +61,7 @@ int inotify_handle_event(struct fsnotify_group *group, ...@@ -61,6 +61,7 @@ int inotify_handle_event(struct fsnotify_group *group,
const struct qstr *file_name, u32 cookie, const struct qstr *file_name, u32 cookie,
struct fsnotify_iter_info *iter_info) 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 *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct inotify_inode_mark *i_mark; struct inotify_inode_mark *i_mark;
struct inotify_event_info *event; struct inotify_event_info *event;
...@@ -73,12 +74,9 @@ int inotify_handle_event(struct fsnotify_group *group, ...@@ -73,12 +74,9 @@ int inotify_handle_event(struct fsnotify_group *group,
return 0; return 0;
if ((inode_mark->mask & FS_EXCL_UNLINK) && if ((inode_mark->mask & FS_EXCL_UNLINK) &&
(data_type == FSNOTIFY_EVENT_PATH)) { path && d_unlinked(path->dentry))
const struct path *path = data;
if (d_unlinked(path->dentry))
return 0; return 0;
}
if (file_name) { if (file_name) {
len = file_name->len; len = file_name->len;
alloc_len += len + 1; alloc_len += len + 1;
......
...@@ -212,10 +212,36 @@ struct fsnotify_group { ...@@ -212,10 +212,36 @@ struct fsnotify_group {
}; };
}; };
/* when calling fsnotify tell it if the data is a path or inode */ /* When calling fsnotify tell it if the data is a path or inode */
#define FSNOTIFY_EVENT_NONE 0 enum fsnotify_data_type {
#define FSNOTIFY_EVENT_PATH 1 FSNOTIFY_EVENT_NONE,
#define FSNOTIFY_EVENT_INODE 2 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 { enum fsnotify_obj_type {
FSNOTIFY_OBJ_TYPE_INODE, FSNOTIFY_OBJ_TYPE_INODE,
......
...@@ -160,23 +160,14 @@ static int audit_mark_handle_event(struct fsnotify_group *group, ...@@ -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 fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
struct audit_fsnotify_mark *audit_mark; 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); audit_mark = container_of(inode_mark, struct audit_fsnotify_mark, mark);
BUG_ON(group != audit_fsnotify_group); BUG_ON(group != audit_fsnotify_group);
switch (data_type) { if (WARN_ON(!inode))
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();
return 0; return 0;
}
if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) { if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) {
if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL)) if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL))
......
...@@ -473,25 +473,13 @@ static int audit_watch_handle_event(struct fsnotify_group *group, ...@@ -473,25 +473,13 @@ static int audit_watch_handle_event(struct fsnotify_group *group,
struct fsnotify_iter_info *iter_info) struct fsnotify_iter_info *iter_info)
{ {
struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(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; struct audit_parent *parent;
parent = container_of(inode_mark, struct audit_parent, mark); parent = container_of(inode_mark, struct audit_parent, mark);
BUG_ON(group != audit_watch_group); BUG_ON(group != audit_watch_group);
WARN_ON(!inode);
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;
}
if (mask & (FS_CREATE|FS_MOVED_TO) && inode) if (mask & (FS_CREATE|FS_MOVED_TO) && inode)
audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0); audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment