summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c13
-rw-r--r--fs/notify/inotify/inotify_user.c9
-rw-r--r--fs/notify/notification.c11
3 files changed, 18 insertions, 15 deletions
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 47cd258fd24d..5dcbafe72d71 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -62,13 +62,14 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev
event_priv->wd = wd;
ret = fsnotify_add_notify_event(group, event, fsn_event_priv);
- /* EEXIST is not an error */
- if (ret == -EEXIST)
- ret = 0;
-
- /* did event_priv get attached? */
- if (list_empty(&fsn_event_priv->event_list))
+ if (ret) {
inotify_free_event_priv(fsn_event_priv);
+ /* EEXIST says we tail matched, EOVERFLOW isn't something
+ * to report up the stack. */
+ if ((ret == -EEXIST) ||
+ (ret == -EOVERFLOW))
+ ret = 0;
+ }
/*
* If we hold the entry until after the event is on the queue
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index f30d9bbc2e1b..dc32ed8323ba 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -386,6 +386,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry,
struct fsnotify_event *ignored_event;
struct inotify_event_private_data *event_priv;
struct fsnotify_event_private_data *fsn_event_priv;
+ int ret;
ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL,
FSNOTIFY_EVENT_NONE, NULL, 0,
@@ -404,10 +405,8 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry,
fsn_event_priv->group = group;
event_priv->wd = ientry->wd;
- fsnotify_add_notify_event(group, ignored_event, fsn_event_priv);
-
- /* did the private data get added? */
- if (list_empty(&fsn_event_priv->event_list))
+ ret = fsnotify_add_notify_event(group, ignored_event, fsn_event_priv);
+ if (ret)
inotify_free_event_priv(fsn_event_priv);
skip_send_ignore:
@@ -568,7 +567,7 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign
spin_lock_init(&group->inotify_data.idr_lock);
idr_init(&group->inotify_data.idr);
- group->inotify_data.last_wd = 0;
+ group->inotify_data.last_wd = 1;
group->inotify_data.user = user;
group->inotify_data.fa = NULL;
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 521368574e97..3816d5750dd5 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -153,6 +153,10 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new
return true;
break;
case (FSNOTIFY_EVENT_NONE):
+ if (old->mask & FS_Q_OVERFLOW)
+ return true;
+ else if (old->mask & FS_IN_IGNORED)
+ return false;
return false;
};
}
@@ -171,9 +175,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_even
struct list_head *list = &group->notification_list;
struct fsnotify_event_holder *last_holder;
struct fsnotify_event *last_event;
-
- /* easy to tell if priv was attached to the event */
- INIT_LIST_HEAD(&priv->event_list);
+ int ret = 0;
/*
* There is one fsnotify_event_holder embedded inside each fsnotify_event.
@@ -194,6 +196,7 @@ alloc_holder:
if (group->q_len >= group->max_events) {
event = &q_overflow_event;
+ ret = -EOVERFLOW;
/* sorry, no private data on the overflow event */
priv = NULL;
}
@@ -235,7 +238,7 @@ alloc_holder:
mutex_unlock(&group->notification_mutex);
wake_up(&group->notification_waitq);
- return 0;
+ return ret;
}
/*