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.com Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
a1aae0570a
commit
aa93bdc550
@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
return 0;
|
||||||
|
|
||||||
if (d_unlinked(path->dentry))
|
|
||||||
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 {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user