Commit 1a2620a9 authored by Amir Goldstein's avatar Amir Goldstein Committed by Jan Kara

inotify: convert to handle_inode_event() interface

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: b9a1b977 ("fsnotify: create method handle_inode_event() in fsnotify_operations")
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 950cc0d2
...@@ -24,11 +24,10 @@ static inline struct inotify_event_info *INOTIFY_E(struct fsnotify_event *fse) ...@@ -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, extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
struct fsnotify_group *group); struct fsnotify_group *group);
extern int inotify_handle_event(struct fsnotify_group *group, u32 mask, extern int inotify_handle_inode_event(struct fsnotify_mark *inode_mark,
const void *data, int data_type, u32 mask, struct inode *inode,
struct inode *dir, struct inode *dir,
const struct qstr *file_name, u32 cookie, const struct qstr *name, u32 cookie);
struct fsnotify_iter_info *iter_info);
extern const struct fsnotify_ops inotify_fsnotify_ops; extern const struct fsnotify_ops inotify_fsnotify_ops;
extern struct kmem_cache *inotify_inode_mark_cachep; extern struct kmem_cache *inotify_inode_mark_cachep;
......
...@@ -55,25 +55,21 @@ static int inotify_merge(struct list_head *list, ...@@ -55,25 +55,21 @@ static int inotify_merge(struct list_head *list,
return event_compare(last_event, event); return event_compare(last_event, event);
} }
static int inotify_one_event(struct fsnotify_group *group, u32 mask, int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
struct fsnotify_mark *inode_mark, struct inode *inode, struct inode *dir,
const struct path *path, const struct qstr *name, u32 cookie)
const struct qstr *file_name, u32 cookie)
{ {
struct inotify_inode_mark *i_mark; struct inotify_inode_mark *i_mark;
struct inotify_event_info *event; struct inotify_event_info *event;
struct fsnotify_event *fsn_event; struct fsnotify_event *fsn_event;
struct fsnotify_group *group = inode_mark->group;
int ret; int ret;
int len = 0; int len = 0;
int alloc_len = sizeof(struct inotify_event_info); int alloc_len = sizeof(struct inotify_event_info);
struct mem_cgroup *old_memcg; struct mem_cgroup *old_memcg;
if ((inode_mark->mask & FS_EXCL_UNLINK) && if (name) {
path && d_unlinked(path->dentry)) len = name->len;
return 0;
if (file_name) {
len = file_name->len;
alloc_len += len + 1; alloc_len += len + 1;
} }
...@@ -117,7 +113,7 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask, ...@@ -117,7 +113,7 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask,
event->sync_cookie = cookie; event->sync_cookie = cookie;
event->name_len = len; event->name_len = len;
if (len) if (len)
strcpy(event->name, file_name->name); strcpy(event->name, name->name);
ret = fsnotify_add_event(group, fsn_event, inotify_merge); ret = fsnotify_add_event(group, fsn_event, inotify_merge);
if (ret) { if (ret) {
...@@ -131,37 +127,6 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask, ...@@ -131,37 +127,6 @@ static int inotify_one_event(struct fsnotify_group *group, u32 mask,
return 0; 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) static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group)
{ {
inotify_ignored_and_remove_idr(fsn_mark, group); inotify_ignored_and_remove_idr(fsn_mark, group);
...@@ -227,7 +192,7 @@ static void inotify_free_mark(struct fsnotify_mark *fsn_mark) ...@@ -227,7 +192,7 @@ static void inotify_free_mark(struct fsnotify_mark *fsn_mark)
} }
const struct fsnotify_ops inotify_fsnotify_ops = { 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_group_priv = inotify_free_group_priv,
.free_event = inotify_free_event, .free_event = inotify_free_event,
.freeing_mark = inotify_freeing_mark, .freeing_mark = inotify_freeing_mark,
......
...@@ -495,14 +495,10 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, ...@@ -495,14 +495,10 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
struct fsnotify_group *group) struct fsnotify_group *group)
{ {
struct inotify_inode_mark *i_mark; 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 */ /* Queue ignore event for the watch */
inotify_handle_event(group, FS_IN_IGNORED, NULL, FSNOTIFY_EVENT_NONE, inotify_handle_inode_event(fsn_mark, FS_IN_IGNORED, NULL, NULL, NULL,
NULL, NULL, 0, &iter_info); 0);
i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
/* remove this mark from the idr */ /* remove this mark from the idr */
......
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