summaryrefslogtreecommitdiff
path: root/fs/notify/inotify
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-01-28 18:53:22 +0100
committerJan Kara <jack@suse.cz>2014-01-29 13:57:10 +0100
commit83c0e1b442b488571f4fef4a91c2fe52eed6c705 (patch)
treeb29a85223f2e5e166f075266edb1bf2e0ef5cf57 /fs/notify/inotify
parent13116dfd13c8c9d60ea04ece13419af2de8e2e37 (diff)
fsnotify: Do not return merged event from fsnotify_add_notify_event()
The event returned from fsnotify_add_notify_event() cannot ever be used safely as the event may be freed by the time the function returns (after dropping notification_mutex). So change the prototype to just return whether the event was added or merged into some existing event. Reported-and-tested-by: Jiri Kosina <jkosina@suse.cz> Reported-and-tested-by: Dave Jones <davej@fedoraproject.org> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/inotify')
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index aad1a35e9af1..d5ee56348bb8 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -53,15 +53,13 @@ static bool event_compare(struct fsnotify_event *old_fsn,
return false;
}
-static struct fsnotify_event *inotify_merge(struct list_head *list,
- struct fsnotify_event *event)
+static int inotify_merge(struct list_head *list,
+ struct fsnotify_event *event)
{
struct fsnotify_event *last_event;
last_event = list_entry(list->prev, struct fsnotify_event, list);
- if (!event_compare(last_event, event))
- return NULL;
- return last_event;
+ return event_compare(last_event, event);
}
int inotify_handle_event(struct fsnotify_group *group,
@@ -73,9 +71,8 @@ int inotify_handle_event(struct fsnotify_group *group,
{
struct inotify_inode_mark *i_mark;
struct inotify_event_info *event;
- struct fsnotify_event *added_event;
struct fsnotify_event *fsn_event;
- int ret = 0;
+ int ret;
int len = 0;
int alloc_len = sizeof(struct inotify_event_info);
@@ -110,18 +107,16 @@ int inotify_handle_event(struct fsnotify_group *group,
if (len)
strcpy(event->name, file_name);
- added_event = fsnotify_add_notify_event(group, fsn_event, inotify_merge);
- if (added_event) {
+ ret = fsnotify_add_notify_event(group, fsn_event, inotify_merge);
+ if (ret) {
/* Our event wasn't used in the end. Free it. */
fsnotify_destroy_event(group, fsn_event);
- if (IS_ERR(added_event))
- ret = PTR_ERR(added_event);
}
if (inode_mark->mask & IN_ONESHOT)
fsnotify_destroy_mark(inode_mark, group);
- return ret;
+ return 0;
}
static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group)