Commit 482ef06c authored by Jan Kara's avatar Jan Kara

fanotify: Handle overflow in case of permission events

If the event queue overflows when we are handling permission event, we
will never get response from userspace. So we must avoid waiting for it.
Change fsnotify_add_notify_event() to return whether overflow has
happened so that we can detect it in fanotify_handle_event() and act
accordingly.
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 2513190a
......@@ -192,10 +192,12 @@ static int fanotify_handle_event(struct fsnotify_group *group,
ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge);
if (ret) {
BUG_ON(mask & FAN_ALL_PERM_EVENTS);
/* Permission events shouldn't be merged */
BUG_ON(ret == 1 && mask & FAN_ALL_PERM_EVENTS);
/* Our event wasn't used in the end. Free it. */
fsnotify_destroy_event(group, fsn_event);
ret = 0;
return 0;
}
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
......
......@@ -80,7 +80,8 @@ void fsnotify_destroy_event(struct fsnotify_group *group,
/*
* Add an event to the group notification queue. The group can later pull this
* event off the queue to deal with. The function returns 0 if the event was
* added to the queue, 1 if the event was merged with some other queued event.
* added to the queue, 1 if the event was merged with some other queued event,
* 2 if the queue of events has overflown.
*/
int fsnotify_add_notify_event(struct fsnotify_group *group,
struct fsnotify_event *event,
......@@ -95,10 +96,14 @@ int fsnotify_add_notify_event(struct fsnotify_group *group,
mutex_lock(&group->notification_mutex);
if (group->q_len >= group->max_events) {
ret = 2;
/* Queue overflow event only if it isn't already queued */
if (list_empty(&group->overflow_event.list))
event = &group->overflow_event;
ret = 1;
if (!list_empty(&group->overflow_event.list)) {
mutex_unlock(&group->notification_mutex);
return ret;
}
event = &group->overflow_event;
goto queue;
}
if (!list_empty(list) && merge) {
......@@ -109,6 +114,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group,
}
}
queue:
group->q_len++;
list_add_tail(&event->list, list);
mutex_unlock(&group->notification_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment