fsnotify: replace inode pointer with an object id
[ Upstream commit dfc2d2594e4a79204a3967585245f00644b8f838 ] The event inode field is used only for comparison in queue merges and cannot be dereferenced after handle_event(), because it does not hold a refcount on the inode. Replace it with an abstract id to do the same thing. Link: https://lore.kernel.org/r/20200319151022.31456-8-amir73il@gmail.com Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
03447528a3
commit
4638e0ff0f
@ -26,7 +26,7 @@ static bool should_merge(struct fsnotify_event *old_fsn,
|
|||||||
old = FANOTIFY_E(old_fsn);
|
old = FANOTIFY_E(old_fsn);
|
||||||
new = FANOTIFY_E(new_fsn);
|
new = FANOTIFY_E(new_fsn);
|
||||||
|
|
||||||
if (old_fsn->inode != new_fsn->inode || old->pid != new->pid ||
|
if (old_fsn->objectid != new_fsn->objectid || old->pid != new->pid ||
|
||||||
old->fh_type != new->fh_type || old->fh_len != new->fh_len)
|
old->fh_type != new->fh_type || old->fh_len != new->fh_len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
|
|||||||
if (!event)
|
if (!event)
|
||||||
goto out;
|
goto out;
|
||||||
init: __maybe_unused
|
init: __maybe_unused
|
||||||
fsnotify_init_event(&event->fse, inode);
|
fsnotify_init_event(&event->fse, (unsigned long)inode);
|
||||||
event->mask = mask;
|
event->mask = mask;
|
||||||
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
|
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
|
||||||
event->pid = get_pid(task_pid(current));
|
event->pid = get_pid(task_pid(current));
|
||||||
|
@ -39,7 +39,7 @@ static bool event_compare(struct fsnotify_event *old_fsn,
|
|||||||
if (old->mask & FS_IN_IGNORED)
|
if (old->mask & FS_IN_IGNORED)
|
||||||
return false;
|
return false;
|
||||||
if ((old->mask == new->mask) &&
|
if ((old->mask == new->mask) &&
|
||||||
(old_fsn->inode == new_fsn->inode) &&
|
(old_fsn->objectid == new_fsn->objectid) &&
|
||||||
(old->name_len == new->name_len) &&
|
(old->name_len == new->name_len) &&
|
||||||
(!old->name_len || !strcmp(old->name, new->name)))
|
(!old->name_len || !strcmp(old->name, new->name)))
|
||||||
return true;
|
return true;
|
||||||
@ -118,7 +118,7 @@ int inotify_handle_event(struct fsnotify_group *group,
|
|||||||
mask &= ~IN_ISDIR;
|
mask &= ~IN_ISDIR;
|
||||||
|
|
||||||
fsn_event = &event->fse;
|
fsn_event = &event->fse;
|
||||||
fsnotify_init_event(fsn_event, inode);
|
fsnotify_init_event(fsn_event, (unsigned long)inode);
|
||||||
event->mask = mask;
|
event->mask = mask;
|
||||||
event->wd = i_mark->wd;
|
event->wd = i_mark->wd;
|
||||||
event->sync_cookie = cookie;
|
event->sync_cookie = cookie;
|
||||||
|
@ -635,7 +635,7 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)
|
|||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
group->overflow_event = &oevent->fse;
|
group->overflow_event = &oevent->fse;
|
||||||
fsnotify_init_event(group->overflow_event, NULL);
|
fsnotify_init_event(group->overflow_event, 0);
|
||||||
oevent->mask = FS_Q_OVERFLOW;
|
oevent->mask = FS_Q_OVERFLOW;
|
||||||
oevent->wd = -1;
|
oevent->wd = -1;
|
||||||
oevent->sync_cookie = 0;
|
oevent->sync_cookie = 0;
|
||||||
|
@ -133,8 +133,7 @@ struct fsnotify_ops {
|
|||||||
*/
|
*/
|
||||||
struct fsnotify_event {
|
struct fsnotify_event {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
/* inode may ONLY be dereferenced during handle_event(). */
|
unsigned long objectid; /* identifier for queue merges */
|
||||||
struct inode *inode; /* either the inode the event happened to or its parent */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -500,10 +499,10 @@ extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
|
|||||||
extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
|
extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
|
||||||
|
|
||||||
static inline void fsnotify_init_event(struct fsnotify_event *event,
|
static inline void fsnotify_init_event(struct fsnotify_event *event,
|
||||||
struct inode *inode)
|
unsigned long objectid)
|
||||||
{
|
{
|
||||||
INIT_LIST_HEAD(&event->list);
|
INIT_LIST_HEAD(&event->list);
|
||||||
event->inode = inode;
|
event->objectid = objectid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
Loading…
Reference in New Issue
Block a user