Commit dfc2d259 authored by Amir Goldstein's avatar Amir Goldstein Committed by Jan Kara
Browse files

fsnotify: replace inode pointer with an object id

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: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 017de65f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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;

@@ -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));
+2 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;
+3 −4
Original line number Diff line number Diff line
@@ -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 */
};

/*
@@ -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