aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/notification.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify/notification.c')
-rw-r--r--fs/notify/notification.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 959b73e756fd..3816d5750dd5 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -136,18 +136,28 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new
136{ 136{
137 if ((old->mask == new->mask) && 137 if ((old->mask == new->mask) &&
138 (old->to_tell == new->to_tell) && 138 (old->to_tell == new->to_tell) &&
139 (old->data_type == new->data_type)) { 139 (old->data_type == new->data_type) &&
140 (old->name_len == new->name_len)) {
140 switch (old->data_type) { 141 switch (old->data_type) {
141 case (FSNOTIFY_EVENT_INODE): 142 case (FSNOTIFY_EVENT_INODE):
142 if (old->inode == new->inode) 143 /* remember, after old was put on the wait_q we aren't
144 * allowed to look at the inode any more, only thing
145 * left to check was if the file_name is the same */
146 if (old->name_len &&
147 !strcmp(old->file_name, new->file_name))
143 return true; 148 return true;
144 break; 149 break;
145 case (FSNOTIFY_EVENT_PATH): 150 case (FSNOTIFY_EVENT_PATH):
146 if ((old->path.mnt == new->path.mnt) && 151 if ((old->path.mnt == new->path.mnt) &&
147 (old->path.dentry == new->path.dentry)) 152 (old->path.dentry == new->path.dentry))
148 return true; 153 return true;
154 break;
149 case (FSNOTIFY_EVENT_NONE): 155 case (FSNOTIFY_EVENT_NONE):
150 return true; 156 if (old->mask & FS_Q_OVERFLOW)
157 return true;
158 else if (old->mask & FS_IN_IGNORED)
159 return false;
160 return false;
151 }; 161 };
152 } 162 }
153 return false; 163 return false;
@@ -165,9 +175,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_even
165 struct list_head *list = &group->notification_list; 175 struct list_head *list = &group->notification_list;
166 struct fsnotify_event_holder *last_holder; 176 struct fsnotify_event_holder *last_holder;
167 struct fsnotify_event *last_event; 177 struct fsnotify_event *last_event;
168 178 int ret = 0;
169 /* easy to tell if priv was attached to the event */
170 INIT_LIST_HEAD(&priv->event_list);
171 179
172 /* 180 /*
173 * There is one fsnotify_event_holder embedded inside each fsnotify_event. 181 * There is one fsnotify_event_holder embedded inside each fsnotify_event.
@@ -188,6 +196,7 @@ alloc_holder:
188 196
189 if (group->q_len >= group->max_events) { 197 if (group->q_len >= group->max_events) {
190 event = &q_overflow_event; 198 event = &q_overflow_event;
199 ret = -EOVERFLOW;
191 /* sorry, no private data on the overflow event */ 200 /* sorry, no private data on the overflow event */
192 priv = NULL; 201 priv = NULL;
193 } 202 }
@@ -229,7 +238,7 @@ alloc_holder:
229 mutex_unlock(&group->notification_mutex); 238 mutex_unlock(&group->notification_mutex);
230 239
231 wake_up(&group->notification_waitq); 240 wake_up(&group->notification_waitq);
232 return 0; 241 return ret;
233} 242}
234 243
235/* 244/*
@@ -339,18 +348,19 @@ static void initialize_event(struct fsnotify_event *event)
339 * @name the filename, if available 348 * @name the filename, if available
340 */ 349 */
341struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, void *data, 350struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, void *data,
342 int data_type, const char *name, u32 cookie) 351 int data_type, const char *name, u32 cookie,
352 gfp_t gfp)
343{ 353{
344 struct fsnotify_event *event; 354 struct fsnotify_event *event;
345 355
346 event = kmem_cache_alloc(fsnotify_event_cachep, GFP_KERNEL); 356 event = kmem_cache_alloc(fsnotify_event_cachep, gfp);
347 if (!event) 357 if (!event)
348 return NULL; 358 return NULL;
349 359
350 initialize_event(event); 360 initialize_event(event);
351 361
352 if (name) { 362 if (name) {
353 event->file_name = kstrdup(name, GFP_KERNEL); 363 event->file_name = kstrdup(name, gfp);
354 if (!event->file_name) { 364 if (!event->file_name) {
355 kmem_cache_free(fsnotify_event_cachep, event); 365 kmem_cache_free(fsnotify_event_cachep, event);
356 return NULL; 366 return NULL;