diff options
Diffstat (limited to 'fs/notify/notification.c')
-rw-r--r-- | fs/notify/notification.c | 30 |
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 | */ |
341 | struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, void *data, | 350 | struct 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; |