Skip to content

Commit

Permalink
fsnotify: replace inode pointer with an object id
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Amir Goldstein authored and Jan Kara committed Mar 24, 2020
1 parent 017de65 commit dfc2d25
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 9 deletions.
4 changes: 2 additions & 2 deletions fs/notify/fanotify/fanotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static bool should_merge(struct fsnotify_event *old_fsn,
old = FANOTIFY_E(old_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)
return false;

Expand Down Expand Up @@ -312,7 +312,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
if (!event)
goto out;
init: __maybe_unused
fsnotify_init_event(&event->fse, inode);
fsnotify_init_event(&event->fse, (unsigned long)inode);
event->mask = mask;
if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
event->pid = get_pid(task_pid(current));
Expand Down
4 changes: 2 additions & 2 deletions fs/notify/inotify/inotify_fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static bool event_compare(struct fsnotify_event *old_fsn,
if (old->mask & FS_IN_IGNORED)
return false;
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 || !strcmp(old->name, new->name)))
return true;
Expand Down Expand Up @@ -116,7 +116,7 @@ int inotify_handle_event(struct fsnotify_group *group,
mask &= ~IN_ISDIR;

fsn_event = &event->fse;
fsnotify_init_event(fsn_event, inode);
fsnotify_init_event(fsn_event, (unsigned long)inode);
event->mask = mask;
event->wd = i_mark->wd;
event->sync_cookie = cookie;
Expand Down
2 changes: 1 addition & 1 deletion fs/notify/inotify/inotify_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)
return ERR_PTR(-ENOMEM);
}
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->wd = -1;
oevent->sync_cookie = 0;
Expand Down
7 changes: 3 additions & 4 deletions include/linux/fsnotify_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,7 @@ struct fsnotify_ops {
*/
struct fsnotify_event {
struct list_head list;
/* inode may ONLY be dereferenced during handle_event(). */
struct inode *inode; /* either the inode the event happened to or its parent */
unsigned long objectid; /* identifier for queue merges */
};

/*
Expand Down Expand Up @@ -526,10 +525,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);

static inline void fsnotify_init_event(struct fsnotify_event *event,
struct inode *inode)
unsigned long objectid)
{
INIT_LIST_HEAD(&event->list);
event->inode = inode;
event->objectid = objectid;
}

#else
Expand Down

0 comments on commit dfc2d25

Please sign in to comment.