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; |
