提交 482ef06c 编写于 作者: J 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: NJan Kara <jack@suse.cz>
上级 2513190a
...@@ -192,10 +192,12 @@ static int fanotify_handle_event(struct fsnotify_group *group, ...@@ -192,10 +192,12 @@ static int fanotify_handle_event(struct fsnotify_group *group,
ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge);
if (ret) { 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. */ /* Our event wasn't used in the end. Free it. */
fsnotify_destroy_event(group, fsn_event); fsnotify_destroy_event(group, fsn_event);
ret = 0;
return 0;
} }
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
......
...@@ -80,7 +80,8 @@ void fsnotify_destroy_event(struct fsnotify_group *group, ...@@ -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 * 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 * 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, int fsnotify_add_notify_event(struct fsnotify_group *group,
struct fsnotify_event *event, struct fsnotify_event *event,
...@@ -95,10 +96,14 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, ...@@ -95,10 +96,14 @@ int fsnotify_add_notify_event(struct fsnotify_group *group,
mutex_lock(&group->notification_mutex); mutex_lock(&group->notification_mutex);
if (group->q_len >= group->max_events) { if (group->q_len >= group->max_events) {
ret = 2;
/* Queue overflow event only if it isn't already queued */ /* Queue overflow event only if it isn't already queued */
if (list_empty(&group->overflow_event.list)) if (!list_empty(&group->overflow_event.list)) {
event = &group->overflow_event; mutex_unlock(&group->notification_mutex);
ret = 1; return ret;
}
event = &group->overflow_event;
goto queue;
} }
if (!list_empty(list) && merge) { if (!list_empty(list) && merge) {
...@@ -109,6 +114,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, ...@@ -109,6 +114,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group,
} }
} }
queue:
group->q_len++; group->q_len++;
list_add_tail(&event->list, list); list_add_tail(&event->list, list);
mutex_unlock(&group->notification_mutex); mutex_unlock(&group->notification_mutex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册