forked from luck/tmp_suning_uos_patched
inotify: convert to handle_inode_event() interface
commit 1a2620a99803ad660edc5d22fd9c66cce91ceb1c upstream.
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: b9a1b97725
("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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c9be99c861
commit
5e78c6bd90
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -486,14 +486,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 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user