| From bc498662abc8ea20c517db7e6239d82cc3e2bdf3 Mon Sep 17 00:00:00 2001 |
| From: Amir Goldstein <amir73il@gmail.com> |
| Date: Thu, 19 Mar 2020 17:10:15 +0200 |
| Subject: [PATCH] fsnotify: replace inode pointer with an object id |
| |
| commit dfc2d2594e4a79204a3967585245f00644b8f838 upstream. |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c |
| index 5778d1347b35..14d0ac466459 100644 |
| --- a/fs/notify/fanotify/fanotify.c |
| +++ b/fs/notify/fanotify/fanotify.c |
| @@ -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; |
| |
| @@ -314,7 +314,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)); |
| diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c |
| index d510223d302c..589dee962993 100644 |
| --- a/fs/notify/inotify/inotify_fsnotify.c |
| +++ b/fs/notify/inotify/inotify_fsnotify.c |
| @@ -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; |
| @@ -118,7 +118,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; |
| diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c |
| index cce8de32779f..3f8af1631fbf 100644 |
| --- a/fs/notify/inotify/inotify_user.c |
| +++ b/fs/notify/inotify/inotify_user.c |
| @@ -628,7 +628,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; |
| diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h |
| index d4844cad2c2b..929255d4fdd5 100644 |
| --- a/include/linux/fsnotify_backend.h |
| +++ b/include/linux/fsnotify_backend.h |
| @@ -133,8 +133,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 */ |
| }; |
| |
| /* |
| @@ -499,10 +498,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 |
| -- |
| 2.7.4 |
| |