aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/notify/dnotify/dnotify.c4
-rw-r--r--fs/notify/fanotify/fanotify.c6
-rw-r--r--fs/notify/fanotify/fanotify_user.c37
-rw-r--r--fs/notify/fdinfo.c4
-rw-r--r--fs/notify/group.c47
-rw-r--r--fs/notify/inode_mark.c14
-rw-r--r--fs/notify/inotify/inotify_fsnotify.c4
-rw-r--r--fs/notify/inotify/inotify_user.c34
-rw-r--r--fs/notify/mark.c91
-rw-r--r--fs/notify/notification.c1
-rw-r--r--fs/notify/vfsmount_mark.c14
-rw-r--r--include/linux/fsnotify_backend.h31
-rw-r--r--kernel/audit_tree.c10
-rw-r--r--kernel/audit_watch.c4
14 files changed, 180 insertions, 121 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 3344bdd5506e..08b886f119ce 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -201,7 +201,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
201 201
202 /* nothing else could have found us thanks to the dnotify_mark_mutex */ 202 /* nothing else could have found us thanks to the dnotify_mark_mutex */
203 if (dn_mark->dn == NULL) 203 if (dn_mark->dn == NULL)
204 fsnotify_destroy_mark(fsn_mark); 204 fsnotify_destroy_mark(fsn_mark, dnotify_group);
205 205
206 mutex_unlock(&dnotify_mark_mutex); 206 mutex_unlock(&dnotify_mark_mutex);
207 207
@@ -385,7 +385,7 @@ out:
385 spin_unlock(&fsn_mark->lock); 385 spin_unlock(&fsn_mark->lock);
386 386
387 if (destroy) 387 if (destroy)
388 fsnotify_destroy_mark(fsn_mark); 388 fsnotify_destroy_mark(fsn_mark, dnotify_group);
389 389
390 mutex_unlock(&dnotify_mark_mutex); 390 mutex_unlock(&dnotify_mark_mutex);
391 fsnotify_put_mark(fsn_mark); 391 fsnotify_put_mark(fsn_mark);
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index a50636025364..0c2f9122b262 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -18,6 +18,12 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
18 old->tgid == new->tgid) { 18 old->tgid == new->tgid) {
19 switch (old->data_type) { 19 switch (old->data_type) {
20 case (FSNOTIFY_EVENT_PATH): 20 case (FSNOTIFY_EVENT_PATH):
21#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
22 /* dont merge two permission events */
23 if ((old->mask & FAN_ALL_PERM_EVENTS) &&
24 (new->mask & FAN_ALL_PERM_EVENTS))
25 return false;
26#endif
21 if ((old->path.mnt == new->path.mnt) && 27 if ((old->path.mnt == new->path.mnt) &&
22 (old->path.dentry == new->path.dentry)) 28 (old->path.dentry == new->path.dentry))
23 return true; 29 return true;
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index a5cd9bba022f..9ff4a5ee6e20 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -397,8 +397,12 @@ static int fanotify_release(struct inode *ignored, struct file *file)
397 397
398 wake_up(&group->fanotify_data.access_waitq); 398 wake_up(&group->fanotify_data.access_waitq);
399#endif 399#endif
400
401 if (file->f_flags & FASYNC)
402 fsnotify_fasync(-1, file, 0);
403
400 /* matches the fanotify_init->fsnotify_alloc_group */ 404 /* matches the fanotify_init->fsnotify_alloc_group */
401 fsnotify_put_group(group); 405 fsnotify_destroy_group(group);
402 406
403 return 0; 407 return 0;
404} 408}
@@ -493,7 +497,8 @@ out:
493 497
494static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, 498static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
495 __u32 mask, 499 __u32 mask,
496 unsigned int flags) 500 unsigned int flags,
501 int *destroy)
497{ 502{
498 __u32 oldmask; 503 __u32 oldmask;
499 504
@@ -507,8 +512,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
507 } 512 }
508 spin_unlock(&fsn_mark->lock); 513 spin_unlock(&fsn_mark->lock);
509 514
510 if (!(oldmask & ~mask)) 515 *destroy = !(oldmask & ~mask);
511 fsnotify_destroy_mark(fsn_mark);
512 516
513 return mask & oldmask; 517 return mask & oldmask;
514} 518}
@@ -519,12 +523,17 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
519{ 523{
520 struct fsnotify_mark *fsn_mark = NULL; 524 struct fsnotify_mark *fsn_mark = NULL;
521 __u32 removed; 525 __u32 removed;
526 int destroy_mark;
522 527
523 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 528 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
524 if (!fsn_mark) 529 if (!fsn_mark)
525 return -ENOENT; 530 return -ENOENT;
526 531
527 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags); 532 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
533 &destroy_mark);
534 if (destroy_mark)
535 fsnotify_destroy_mark(fsn_mark, group);
536
528 fsnotify_put_mark(fsn_mark); 537 fsnotify_put_mark(fsn_mark);
529 if (removed & real_mount(mnt)->mnt_fsnotify_mask) 538 if (removed & real_mount(mnt)->mnt_fsnotify_mask)
530 fsnotify_recalc_vfsmount_mask(mnt); 539 fsnotify_recalc_vfsmount_mask(mnt);
@@ -538,12 +547,16 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
538{ 547{
539 struct fsnotify_mark *fsn_mark = NULL; 548 struct fsnotify_mark *fsn_mark = NULL;
540 __u32 removed; 549 __u32 removed;
550 int destroy_mark;
541 551
542 fsn_mark = fsnotify_find_inode_mark(group, inode); 552 fsn_mark = fsnotify_find_inode_mark(group, inode);
543 if (!fsn_mark) 553 if (!fsn_mark)
544 return -ENOENT; 554 return -ENOENT;
545 555
546 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags); 556 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
557 &destroy_mark);
558 if (destroy_mark)
559 fsnotify_destroy_mark(fsn_mark, group);
547 /* matches the fsnotify_find_inode_mark() */ 560 /* matches the fsnotify_find_inode_mark() */
548 fsnotify_put_mark(fsn_mark); 561 fsnotify_put_mark(fsn_mark);
549 if (removed & inode->i_fsnotify_mask) 562 if (removed & inode->i_fsnotify_mask)
@@ -710,13 +723,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
710 break; 723 break;
711 default: 724 default:
712 fd = -EINVAL; 725 fd = -EINVAL;
713 goto out_put_group; 726 goto out_destroy_group;
714 } 727 }
715 728
716 if (flags & FAN_UNLIMITED_QUEUE) { 729 if (flags & FAN_UNLIMITED_QUEUE) {
717 fd = -EPERM; 730 fd = -EPERM;
718 if (!capable(CAP_SYS_ADMIN)) 731 if (!capable(CAP_SYS_ADMIN))
719 goto out_put_group; 732 goto out_destroy_group;
720 group->max_events = UINT_MAX; 733 group->max_events = UINT_MAX;
721 } else { 734 } else {
722 group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS; 735 group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
@@ -725,7 +738,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
725 if (flags & FAN_UNLIMITED_MARKS) { 738 if (flags & FAN_UNLIMITED_MARKS) {
726 fd = -EPERM; 739 fd = -EPERM;
727 if (!capable(CAP_SYS_ADMIN)) 740 if (!capable(CAP_SYS_ADMIN))
728 goto out_put_group; 741 goto out_destroy_group;
729 group->fanotify_data.max_marks = UINT_MAX; 742 group->fanotify_data.max_marks = UINT_MAX;
730 } else { 743 } else {
731 group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS; 744 group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
@@ -733,12 +746,12 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
733 746
734 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags); 747 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
735 if (fd < 0) 748 if (fd < 0)
736 goto out_put_group; 749 goto out_destroy_group;
737 750
738 return fd; 751 return fd;
739 752
740out_put_group: 753out_destroy_group:
741 fsnotify_put_group(group); 754 fsnotify_destroy_group(group);
742 return fd; 755 return fd;
743} 756}
744 757
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index 514c4b81483d..238a5930cb3c 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -27,13 +27,13 @@ static int show_fdinfo(struct seq_file *m, struct file *f,
27 struct fsnotify_mark *mark; 27 struct fsnotify_mark *mark;
28 int ret = 0; 28 int ret = 0;
29 29
30 spin_lock(&group->mark_lock); 30 mutex_lock(&group->mark_mutex);
31 list_for_each_entry(mark, &group->marks_list, g_list) { 31 list_for_each_entry(mark, &group->marks_list, g_list) {
32 ret = show(m, mark); 32 ret = show(m, mark);
33 if (ret) 33 if (ret)
34 break; 34 break;
35 } 35 }
36 spin_unlock(&group->mark_lock); 36 mutex_unlock(&group->mark_mutex);
37 return ret; 37 return ret;
38} 38}
39 39
diff --git a/fs/notify/group.c b/fs/notify/group.c
index 63fc294a4692..bd2625bd88b4 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -33,9 +33,6 @@
33 */ 33 */
34void fsnotify_final_destroy_group(struct fsnotify_group *group) 34void fsnotify_final_destroy_group(struct fsnotify_group *group)
35{ 35{
36 /* clear the notification queue of all events */
37 fsnotify_flush_notify(group);
38
39 if (group->ops->free_group_priv) 36 if (group->ops->free_group_priv)
40 group->ops->free_group_priv(group); 37 group->ops->free_group_priv(group);
41 38
@@ -43,23 +40,30 @@ void fsnotify_final_destroy_group(struct fsnotify_group *group)
43} 40}
44 41
45/* 42/*
46 * Trying to get rid of a group. We need to first get rid of any outstanding 43 * Trying to get rid of a group. Remove all marks, flush all events and release
47 * allocations and then free the group. Remember that fsnotify_clear_marks_by_group 44 * the group reference.
48 * could miss marks that are being freed by inode and those marks could still 45 * Note that another thread calling fsnotify_clear_marks_by_group() may still
49 * hold a reference to this group (via group->num_marks) If we get into that 46 * hold a ref to the group.
50 * situtation, the fsnotify_final_destroy_group will get called when that final
51 * mark is freed.
52 */ 47 */
53static void fsnotify_destroy_group(struct fsnotify_group *group) 48void fsnotify_destroy_group(struct fsnotify_group *group)
54{ 49{
55 /* clear all inode marks for this group */ 50 /* clear all inode marks for this group */
56 fsnotify_clear_marks_by_group(group); 51 fsnotify_clear_marks_by_group(group);
57 52
58 synchronize_srcu(&fsnotify_mark_srcu); 53 synchronize_srcu(&fsnotify_mark_srcu);
59 54
60 /* past the point of no return, matches the initial value of 1 */ 55 /* clear the notification queue of all events */
61 if (atomic_dec_and_test(&group->num_marks)) 56 fsnotify_flush_notify(group);
62 fsnotify_final_destroy_group(group); 57
58 fsnotify_put_group(group);
59}
60
61/*
62 * Get reference to a group.
63 */
64void fsnotify_get_group(struct fsnotify_group *group)
65{
66 atomic_inc(&group->refcnt);
63} 67}
64 68
65/* 69/*
@@ -68,7 +72,7 @@ static void fsnotify_destroy_group(struct fsnotify_group *group)
68void fsnotify_put_group(struct fsnotify_group *group) 72void fsnotify_put_group(struct fsnotify_group *group)
69{ 73{
70 if (atomic_dec_and_test(&group->refcnt)) 74 if (atomic_dec_and_test(&group->refcnt))
71 fsnotify_destroy_group(group); 75 fsnotify_final_destroy_group(group);
72} 76}
73 77
74/* 78/*
@@ -84,21 +88,24 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
84 88
85 /* set to 0 when there a no external references to this group */ 89 /* set to 0 when there a no external references to this group */
86 atomic_set(&group->refcnt, 1); 90 atomic_set(&group->refcnt, 1);
87 /* 91 atomic_set(&group->num_marks, 0);
88 * hits 0 when there are no external references AND no marks for
89 * this group
90 */
91 atomic_set(&group->num_marks, 1);
92 92
93 mutex_init(&group->notification_mutex); 93 mutex_init(&group->notification_mutex);
94 INIT_LIST_HEAD(&group->notification_list); 94 INIT_LIST_HEAD(&group->notification_list);
95 init_waitqueue_head(&group->notification_waitq); 95 init_waitqueue_head(&group->notification_waitq);
96 group->max_events = UINT_MAX; 96 group->max_events = UINT_MAX;
97 97
98 spin_lock_init(&group->mark_lock); 98 mutex_init(&group->mark_mutex);
99 INIT_LIST_HEAD(&group->marks_list); 99 INIT_LIST_HEAD(&group->marks_list);
100 100
101 group->ops = ops; 101 group->ops = ops;
102 102
103 return group; 103 return group;
104} 104}
105
106int fsnotify_fasync(int fd, struct file *file, int on)
107{
108 struct fsnotify_group *group = file->private_data;
109
110 return fasync_helper(fd, file, on, &group->fsn_fa) >= 0 ? 0 : -EIO;
111}
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index f3035691f528..f31e90fc050d 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -63,8 +63,8 @@ void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark)
63{ 63{
64 struct inode *inode = mark->i.inode; 64 struct inode *inode = mark->i.inode;
65 65
66 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex));
66 assert_spin_locked(&mark->lock); 67 assert_spin_locked(&mark->lock);
67 assert_spin_locked(&mark->group->mark_lock);
68 68
69 spin_lock(&inode->i_lock); 69 spin_lock(&inode->i_lock);
70 70
@@ -99,8 +99,16 @@ void fsnotify_clear_marks_by_inode(struct inode *inode)
99 spin_unlock(&inode->i_lock); 99 spin_unlock(&inode->i_lock);
100 100
101 list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) { 101 list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) {
102 fsnotify_destroy_mark(mark); 102 struct fsnotify_group *group;
103
104 spin_lock(&mark->lock);
105 fsnotify_get_group(mark->group);
106 group = mark->group;
107 spin_unlock(&mark->lock);
108
109 fsnotify_destroy_mark(mark, group);
103 fsnotify_put_mark(mark); 110 fsnotify_put_mark(mark);
111 fsnotify_put_group(group);
104 } 112 }
105} 113}
106 114
@@ -192,8 +200,8 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
192 200
193 mark->flags |= FSNOTIFY_MARK_FLAG_INODE; 201 mark->flags |= FSNOTIFY_MARK_FLAG_INODE;
194 202
203 BUG_ON(!mutex_is_locked(&group->mark_mutex));
195 assert_spin_locked(&mark->lock); 204 assert_spin_locked(&mark->lock);
196 assert_spin_locked(&group->mark_lock);
197 205
198 spin_lock(&inode->i_lock); 206 spin_lock(&inode->i_lock);
199 207
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index e3cbd746f64a..871569c7d609 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -118,6 +118,7 @@ static int inotify_handle_event(struct fsnotify_group *group,
118 118
119 fsn_event_priv = &event_priv->fsnotify_event_priv_data; 119 fsn_event_priv = &event_priv->fsnotify_event_priv_data;
120 120
121 fsnotify_get_group(group);
121 fsn_event_priv->group = group; 122 fsn_event_priv->group = group;
122 event_priv->wd = wd; 123 event_priv->wd = wd;
123 124
@@ -131,7 +132,7 @@ static int inotify_handle_event(struct fsnotify_group *group,
131 } 132 }
132 133
133 if (inode_mark->mask & IN_ONESHOT) 134 if (inode_mark->mask & IN_ONESHOT)
134 fsnotify_destroy_mark(inode_mark); 135 fsnotify_destroy_mark(inode_mark, group);
135 136
136 return ret; 137 return ret;
137} 138}
@@ -210,6 +211,7 @@ void inotify_free_event_priv(struct fsnotify_event_private_data *fsn_event_priv)
210 event_priv = container_of(fsn_event_priv, struct inotify_event_private_data, 211 event_priv = container_of(fsn_event_priv, struct inotify_event_private_data,
211 fsnotify_event_priv_data); 212 fsnotify_event_priv_data);
212 213
214 fsnotify_put_group(fsn_event_priv->group);
213 kmem_cache_free(event_priv_cachep, event_priv); 215 kmem_cache_free(event_priv_cachep, event_priv);
214} 216}
215 217
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 36cb013c7c13..228a2c2ad8d7 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -265,7 +265,7 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
265 ret = -EAGAIN; 265 ret = -EAGAIN;
266 if (file->f_flags & O_NONBLOCK) 266 if (file->f_flags & O_NONBLOCK)
267 break; 267 break;
268 ret = -EINTR; 268 ret = -ERESTARTSYS;
269 if (signal_pending(current)) 269 if (signal_pending(current))
270 break; 270 break;
271 271
@@ -281,23 +281,17 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
281 return ret; 281 return ret;
282} 282}
283 283
284static int inotify_fasync(int fd, struct file *file, int on)
285{
286 struct fsnotify_group *group = file->private_data;
287
288 return fasync_helper(fd, file, on, &group->inotify_data.fa) >= 0 ? 0 : -EIO;
289}
290
291static int inotify_release(struct inode *ignored, struct file *file) 284static int inotify_release(struct inode *ignored, struct file *file)
292{ 285{
293 struct fsnotify_group *group = file->private_data; 286 struct fsnotify_group *group = file->private_data;
294 287
295 pr_debug("%s: group=%p\n", __func__, group); 288 pr_debug("%s: group=%p\n", __func__, group);
296 289
297 fsnotify_clear_marks_by_group(group); 290 if (file->f_flags & FASYNC)
291 fsnotify_fasync(-1, file, 0);
298 292
299 /* free this group, matching get was inotify_init->fsnotify_obtain_group */ 293 /* free this group, matching get was inotify_init->fsnotify_obtain_group */
300 fsnotify_put_group(group); 294 fsnotify_destroy_group(group);
301 295
302 return 0; 296 return 0;
303} 297}
@@ -339,7 +333,7 @@ static const struct file_operations inotify_fops = {
339 .show_fdinfo = inotify_show_fdinfo, 333 .show_fdinfo = inotify_show_fdinfo,
340 .poll = inotify_poll, 334 .poll = inotify_poll,
341 .read = inotify_read, 335 .read = inotify_read,
342 .fasync = inotify_fasync, 336 .fasync = fsnotify_fasync,
343 .release = inotify_release, 337 .release = inotify_release,
344 .unlocked_ioctl = inotify_ioctl, 338 .unlocked_ioctl = inotify_ioctl,
345 .compat_ioctl = inotify_ioctl, 339 .compat_ioctl = inotify_ioctl,
@@ -521,13 +515,13 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
521 struct fsnotify_event_private_data *fsn_event_priv; 515 struct fsnotify_event_private_data *fsn_event_priv;
522 int ret; 516 int ret;
523 517
518 i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
519
524 ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL, 520 ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL,
525 FSNOTIFY_EVENT_NONE, NULL, 0, 521 FSNOTIFY_EVENT_NONE, NULL, 0,
526 GFP_NOFS); 522 GFP_NOFS);
527 if (!ignored_event) 523 if (!ignored_event)
528 return; 524 goto skip_send_ignore;
529
530 i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
531 525
532 event_priv = kmem_cache_alloc(event_priv_cachep, GFP_NOFS); 526 event_priv = kmem_cache_alloc(event_priv_cachep, GFP_NOFS);
533 if (unlikely(!event_priv)) 527 if (unlikely(!event_priv))
@@ -535,6 +529,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
535 529
536 fsn_event_priv = &event_priv->fsnotify_event_priv_data; 530 fsn_event_priv = &event_priv->fsnotify_event_priv_data;
537 531
532 fsnotify_get_group(group);
538 fsn_event_priv->group = group; 533 fsn_event_priv->group = group;
539 event_priv->wd = i_mark->wd; 534 event_priv->wd = i_mark->wd;
540 535
@@ -548,9 +543,9 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark,
548 } 543 }
549 544
550skip_send_ignore: 545skip_send_ignore:
551
552 /* matches the reference taken when the event was created */ 546 /* matches the reference taken when the event was created */
553 fsnotify_put_event(ignored_event); 547 if (ignored_event)
548 fsnotify_put_event(ignored_event);
554 549
555 /* remove this mark from the idr */ 550 /* remove this mark from the idr */
556 inotify_remove_from_idr(group, i_mark); 551 inotify_remove_from_idr(group, i_mark);
@@ -709,12 +704,11 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)
709 spin_lock_init(&group->inotify_data.idr_lock); 704 spin_lock_init(&group->inotify_data.idr_lock);
710 idr_init(&group->inotify_data.idr); 705 idr_init(&group->inotify_data.idr);
711 group->inotify_data.last_wd = 0; 706 group->inotify_data.last_wd = 0;
712 group->inotify_data.fa = NULL;
713 group->inotify_data.user = get_current_user(); 707 group->inotify_data.user = get_current_user();
714 708
715 if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > 709 if (atomic_inc_return(&group->inotify_data.user->inotify_devs) >
716 inotify_max_user_instances) { 710 inotify_max_user_instances) {
717 fsnotify_put_group(group); 711 fsnotify_destroy_group(group);
718 return ERR_PTR(-EMFILE); 712 return ERR_PTR(-EMFILE);
719 } 713 }
720 714
@@ -743,7 +737,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
743 ret = anon_inode_getfd("inotify", &inotify_fops, group, 737 ret = anon_inode_getfd("inotify", &inotify_fops, group,
744 O_RDONLY | flags); 738 O_RDONLY | flags);
745 if (ret < 0) 739 if (ret < 0)
746 fsnotify_put_group(group); 740 fsnotify_destroy_group(group);
747 741
748 return ret; 742 return ret;
749} 743}
@@ -819,7 +813,7 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)
819 813
820 ret = 0; 814 ret = 0;
821 815
822 fsnotify_destroy_mark(&i_mark->fsn_mark); 816 fsnotify_destroy_mark(&i_mark->fsn_mark, group);
823 817
824 /* match ref taken by inotify_idr_find */ 818 /* match ref taken by inotify_idr_find */
825 fsnotify_put_mark(&i_mark->fsn_mark); 819 fsnotify_put_mark(&i_mark->fsn_mark);
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index f104d565b682..fc6b49bf7360 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -109,8 +109,11 @@ void fsnotify_get_mark(struct fsnotify_mark *mark)
109 109
110void fsnotify_put_mark(struct fsnotify_mark *mark) 110void fsnotify_put_mark(struct fsnotify_mark *mark)
111{ 111{
112 if (atomic_dec_and_test(&mark->refcnt)) 112 if (atomic_dec_and_test(&mark->refcnt)) {
113 if (mark->group)
114 fsnotify_put_group(mark->group);
113 mark->free_mark(mark); 115 mark->free_mark(mark);
116 }
114} 117}
115 118
116/* 119/*
@@ -118,14 +121,14 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
118 * The caller had better be holding a reference to this mark so we don't actually 121 * The caller had better be holding a reference to this mark so we don't actually
119 * do the final put under the mark->lock 122 * do the final put under the mark->lock
120 */ 123 */
121void fsnotify_destroy_mark(struct fsnotify_mark *mark) 124void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
125 struct fsnotify_group *group)
122{ 126{
123 struct fsnotify_group *group;
124 struct inode *inode = NULL; 127 struct inode *inode = NULL;
125 128
126 spin_lock(&mark->lock); 129 BUG_ON(!mutex_is_locked(&group->mark_mutex));
127 130
128 group = mark->group; 131 spin_lock(&mark->lock);
129 132
130 /* something else already called this function on this mark */ 133 /* something else already called this function on this mark */
131 if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { 134 if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) {
@@ -135,8 +138,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
135 138
136 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; 139 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
137 140
138 spin_lock(&group->mark_lock);
139
140 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { 141 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
141 inode = mark->i.inode; 142 inode = mark->i.inode;
142 fsnotify_destroy_inode_mark(mark); 143 fsnotify_destroy_inode_mark(mark);
@@ -147,13 +148,22 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
147 148
148 list_del_init(&mark->g_list); 149 list_del_init(&mark->g_list);
149 150
150 spin_unlock(&group->mark_lock);
151 spin_unlock(&mark->lock); 151 spin_unlock(&mark->lock);
152 152
153 if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED))
154 iput(inode);
155 /* release lock temporarily */
156 mutex_unlock(&group->mark_mutex);
157
153 spin_lock(&destroy_lock); 158 spin_lock(&destroy_lock);
154 list_add(&mark->destroy_list, &destroy_list); 159 list_add(&mark->destroy_list, &destroy_list);
155 spin_unlock(&destroy_lock); 160 spin_unlock(&destroy_lock);
156 wake_up(&destroy_waitq); 161 wake_up(&destroy_waitq);
162 /*
163 * We don't necessarily have a ref on mark from caller so the above destroy
164 * may have actually freed it, unless this group provides a 'freeing_mark'
165 * function which must be holding a reference.
166 */
157 167
158 /* 168 /*
159 * Some groups like to know that marks are being freed. This is a 169 * Some groups like to know that marks are being freed. This is a
@@ -175,21 +185,17 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
175 * is just a lazy update (and could be a perf win...) 185 * is just a lazy update (and could be a perf win...)
176 */ 186 */
177 187
178 if (inode && (mark->flags & FSNOTIFY_MARK_FLAG_OBJECT_PINNED)) 188 atomic_dec(&group->num_marks);
179 iput(inode);
180 189
181 /* 190 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
182 * We don't necessarily have a ref on mark from caller so the above iput 191}
183 * may have already destroyed it. Don't touch from now on.
184 */
185 192
186 /* 193void fsnotify_destroy_mark(struct fsnotify_mark *mark,
187 * it's possible that this group tried to destroy itself, but this 194 struct fsnotify_group *group)
188 * this mark was simultaneously being freed by inode. If that's the 195{
189 * case, we finish freeing the group here. 196 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
190 */ 197 fsnotify_destroy_mark_locked(mark, group);
191 if (unlikely(atomic_dec_and_test(&group->num_marks))) 198 mutex_unlock(&group->mark_mutex);
192 fsnotify_final_destroy_group(group);
193} 199}
194 200
195void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) 201void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask)
@@ -214,26 +220,26 @@ void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mas
214 * These marks may be used for the fsnotify backend to determine which 220 * These marks may be used for the fsnotify backend to determine which
215 * event types should be delivered to which group. 221 * event types should be delivered to which group.
216 */ 222 */
217int fsnotify_add_mark(struct fsnotify_mark *mark, 223int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
218 struct fsnotify_group *group, struct inode *inode, 224 struct fsnotify_group *group, struct inode *inode,
219 struct vfsmount *mnt, int allow_dups) 225 struct vfsmount *mnt, int allow_dups)
220{ 226{
221 int ret = 0; 227 int ret = 0;
222 228
223 BUG_ON(inode && mnt); 229 BUG_ON(inode && mnt);
224 BUG_ON(!inode && !mnt); 230 BUG_ON(!inode && !mnt);
231 BUG_ON(!mutex_is_locked(&group->mark_mutex));
225 232
226 /* 233 /*
227 * LOCKING ORDER!!!! 234 * LOCKING ORDER!!!!
235 * group->mark_mutex
228 * mark->lock 236 * mark->lock
229 * group->mark_lock
230 * inode->i_lock 237 * inode->i_lock
231 */ 238 */
232 spin_lock(&mark->lock); 239 spin_lock(&mark->lock);
233 spin_lock(&group->mark_lock);
234
235 mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE; 240 mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE;
236 241
242 fsnotify_get_group(group);
237 mark->group = group; 243 mark->group = group;
238 list_add(&mark->g_list, &group->marks_list); 244 list_add(&mark->g_list, &group->marks_list);
239 atomic_inc(&group->num_marks); 245 atomic_inc(&group->num_marks);
@@ -251,11 +257,8 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
251 BUG(); 257 BUG();
252 } 258 }
253 259
254 spin_unlock(&group->mark_lock);
255
256 /* this will pin the object if appropriate */ 260 /* this will pin the object if appropriate */
257 fsnotify_set_mark_mask_locked(mark, mark->mask); 261 fsnotify_set_mark_mask_locked(mark, mark->mask);
258
259 spin_unlock(&mark->lock); 262 spin_unlock(&mark->lock);
260 263
261 if (inode) 264 if (inode)
@@ -265,10 +268,10 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
265err: 268err:
266 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; 269 mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
267 list_del_init(&mark->g_list); 270 list_del_init(&mark->g_list);
271 fsnotify_put_group(group);
268 mark->group = NULL; 272 mark->group = NULL;
269 atomic_dec(&group->num_marks); 273 atomic_dec(&group->num_marks);
270 274
271 spin_unlock(&group->mark_lock);
272 spin_unlock(&mark->lock); 275 spin_unlock(&mark->lock);
273 276
274 spin_lock(&destroy_lock); 277 spin_lock(&destroy_lock);
@@ -279,6 +282,16 @@ err:
279 return ret; 282 return ret;
280} 283}
281 284
285int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
286 struct inode *inode, struct vfsmount *mnt, int allow_dups)
287{
288 int ret;
289 mutex_lock(&group->mark_mutex);
290 ret = fsnotify_add_mark_locked(mark, group, inode, mnt, allow_dups);
291 mutex_unlock(&group->mark_mutex);
292 return ret;
293}
294
282/* 295/*
283 * clear any marks in a group in which mark->flags & flags is true 296 * clear any marks in a group in which mark->flags & flags is true
284 */ 297 */
@@ -286,22 +299,16 @@ void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group,
286 unsigned int flags) 299 unsigned int flags)
287{ 300{
288 struct fsnotify_mark *lmark, *mark; 301 struct fsnotify_mark *lmark, *mark;
289 LIST_HEAD(free_list);
290 302
291 spin_lock(&group->mark_lock); 303 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
292 list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { 304 list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
293 if (mark->flags & flags) { 305 if (mark->flags & flags) {
294 list_add(&mark->free_g_list, &free_list);
295 list_del_init(&mark->g_list);
296 fsnotify_get_mark(mark); 306 fsnotify_get_mark(mark);
307 fsnotify_destroy_mark_locked(mark, group);
308 fsnotify_put_mark(mark);
297 } 309 }
298 } 310 }
299 spin_unlock(&group->mark_lock); 311 mutex_unlock(&group->mark_mutex);
300
301 list_for_each_entry_safe(mark, lmark, &free_list, free_g_list) {
302 fsnotify_destroy_mark(mark);
303 fsnotify_put_mark(mark);
304 }
305} 312}
306 313
307/* 314/*
@@ -317,6 +324,8 @@ void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *ol
317 assert_spin_locked(&old->lock); 324 assert_spin_locked(&old->lock);
318 new->i.inode = old->i.inode; 325 new->i.inode = old->i.inode;
319 new->m.mnt = old->m.mnt; 326 new->m.mnt = old->m.mnt;
327 if (old->group)
328 fsnotify_get_group(old->group);
320 new->group = old->group; 329 new->group = old->group;
321 new->mask = old->mask; 330 new->mask = old->mask;
322 new->free_mark = old->free_mark; 331 new->free_mark = old->free_mark;
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 48cb994e4922..7b51b05f160c 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -225,6 +225,7 @@ alloc_holder:
225 mutex_unlock(&group->notification_mutex); 225 mutex_unlock(&group->notification_mutex);
226 226
227 wake_up(&group->notification_waitq); 227 wake_up(&group->notification_waitq);
228 kill_fasync(&group->fsn_fa, SIGIO, POLL_IN);
228 return return_event; 229 return return_event;
229} 230}
230 231
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c
index b7b4b0e8554f..4df58b8ea64a 100644
--- a/fs/notify/vfsmount_mark.c
+++ b/fs/notify/vfsmount_mark.c
@@ -46,8 +46,16 @@ void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
46 spin_unlock(&mnt->mnt_root->d_lock); 46 spin_unlock(&mnt->mnt_root->d_lock);
47 47
48 list_for_each_entry_safe(mark, lmark, &free_list, m.free_m_list) { 48 list_for_each_entry_safe(mark, lmark, &free_list, m.free_m_list) {
49 fsnotify_destroy_mark(mark); 49 struct fsnotify_group *group;
50
51 spin_lock(&mark->lock);
52 fsnotify_get_group(mark->group);
53 group = mark->group;
54 spin_unlock(&mark->lock);
55
56 fsnotify_destroy_mark(mark, group);
50 fsnotify_put_mark(mark); 57 fsnotify_put_mark(mark);
58 fsnotify_put_group(group);
51 } 59 }
52} 60}
53 61
@@ -88,8 +96,8 @@ void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark)
88{ 96{
89 struct vfsmount *mnt = mark->m.mnt; 97 struct vfsmount *mnt = mark->m.mnt;
90 98
99 BUG_ON(!mutex_is_locked(&mark->group->mark_mutex));
91 assert_spin_locked(&mark->lock); 100 assert_spin_locked(&mark->lock);
92 assert_spin_locked(&mark->group->mark_lock);
93 101
94 spin_lock(&mnt->mnt_root->d_lock); 102 spin_lock(&mnt->mnt_root->d_lock);
95 103
@@ -151,8 +159,8 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
151 159
152 mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; 160 mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
153 161
162 BUG_ON(!mutex_is_locked(&group->mark_mutex));
154 assert_spin_locked(&mark->lock); 163 assert_spin_locked(&mark->lock);
155 assert_spin_locked(&group->mark_lock);
156 164
157 spin_lock(&mnt->mnt_root->d_lock); 165 spin_lock(&mnt->mnt_root->d_lock);
158 166
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 63d966d5c2ea..d5b0910d4961 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -88,9 +88,10 @@ struct fsnotify_event_private_data;
88 * if the group is interested in this event. 88 * if the group is interested in this event.
89 * handle_event - main call for a group to handle an fs event 89 * handle_event - main call for a group to handle an fs event
90 * free_group_priv - called when a group refcnt hits 0 to clean up the private union 90 * free_group_priv - called when a group refcnt hits 0 to clean up the private union
91 * freeing-mark - this means that a mark has been flagged to die when everything 91 * freeing_mark - called when a mark is being destroyed for some reason. The group
92 * finishes using it. The function is supplied with what must be a 92 * MUST be holding a reference on each mark and that reference must be
93 * valid group and inode to use to clean up. 93 * dropped in this function. inotify uses this function to send
94 * userspace messages that marks have been removed.
94 */ 95 */
95struct fsnotify_ops { 96struct fsnotify_ops {
96 bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode, 97 bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode,
@@ -141,12 +142,14 @@ struct fsnotify_group {
141 unsigned int priority; 142 unsigned int priority;
142 143
143 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ 144 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
144 spinlock_t mark_lock; /* protect marks_list */ 145 struct mutex mark_mutex; /* protect marks_list */
145 atomic_t num_marks; /* 1 for each mark and 1 for not being 146 atomic_t num_marks; /* 1 for each mark and 1 for not being
146 * past the point of no return when freeing 147 * past the point of no return when freeing
147 * a group */ 148 * a group */
148 struct list_head marks_list; /* all inode marks for this group */ 149 struct list_head marks_list; /* all inode marks for this group */
149 150
151 struct fasync_struct *fsn_fa; /* async notification */
152
150 /* groups can define private fields here or use the void *private */ 153 /* groups can define private fields here or use the void *private */
151 union { 154 union {
152 void *private; 155 void *private;
@@ -155,7 +158,6 @@ struct fsnotify_group {
155 spinlock_t idr_lock; 158 spinlock_t idr_lock;
156 struct idr idr; 159 struct idr idr;
157 u32 last_wd; 160 u32 last_wd;
158 struct fasync_struct *fa; /* async notification */
159 struct user_struct *user; 161 struct user_struct *user;
160 } inotify_data; 162 } inotify_data;
161#endif 163#endif
@@ -287,7 +289,6 @@ struct fsnotify_mark {
287 struct fsnotify_inode_mark i; 289 struct fsnotify_inode_mark i;
288 struct fsnotify_vfsmount_mark m; 290 struct fsnotify_vfsmount_mark m;
289 }; 291 };
290 struct list_head free_g_list; /* tmp list used when freeing this mark */
291 __u32 ignored_mask; /* events types to ignore */ 292 __u32 ignored_mask; /* events types to ignore */
292#define FSNOTIFY_MARK_FLAG_INODE 0x01 293#define FSNOTIFY_MARK_FLAG_INODE 0x01
293#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02 294#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
@@ -360,11 +361,16 @@ static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode
360 361
361/* called from fsnotify listeners, such as fanotify or dnotify */ 362/* called from fsnotify listeners, such as fanotify or dnotify */
362 363
363/* get a reference to an existing or create a new group */ 364/* create a new group */
364extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops); 365extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops);
366/* get reference to a group */
367extern void fsnotify_get_group(struct fsnotify_group *group);
365/* drop reference on a group from fsnotify_alloc_group */ 368/* drop reference on a group from fsnotify_alloc_group */
366extern void fsnotify_put_group(struct fsnotify_group *group); 369extern void fsnotify_put_group(struct fsnotify_group *group);
367 370/* destroy group */
371extern void fsnotify_destroy_group(struct fsnotify_group *group);
372/* fasync handler function */
373extern int fsnotify_fasync(int fd, struct file *file, int on);
368/* take a reference to an event */ 374/* take a reference to an event */
369extern void fsnotify_get_event(struct fsnotify_event *event); 375extern void fsnotify_get_event(struct fsnotify_event *event);
370extern void fsnotify_put_event(struct fsnotify_event *event); 376extern void fsnotify_put_event(struct fsnotify_event *event);
@@ -405,8 +411,13 @@ extern void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask
405/* attach the mark to both the group and the inode */ 411/* attach the mark to both the group and the inode */
406extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, 412extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
407 struct inode *inode, struct vfsmount *mnt, int allow_dups); 413 struct inode *inode, struct vfsmount *mnt, int allow_dups);
408/* given a mark, flag it to be freed when all references are dropped */ 414extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, struct fsnotify_group *group,
409extern void fsnotify_destroy_mark(struct fsnotify_mark *mark); 415 struct inode *inode, struct vfsmount *mnt, int allow_dups);
416/* given a group and a mark, flag mark to be freed when all references are dropped */
417extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
418 struct fsnotify_group *group);
419extern void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
420 struct fsnotify_group *group);
410/* run all the marks in a group, and clear all of the vfsmount marks */ 421/* run all the marks in a group, and clear all of the vfsmount marks */
411extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group); 422extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group);
412/* run all the marks in a group, and clear all of the inode marks */ 423/* run all the marks in a group, and clear all of the inode marks */
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index ed206fd88cca..e81175ef25f8 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -249,7 +249,7 @@ static void untag_chunk(struct node *p)
249 list_del_rcu(&chunk->hash); 249 list_del_rcu(&chunk->hash);
250 spin_unlock(&hash_lock); 250 spin_unlock(&hash_lock);
251 spin_unlock(&entry->lock); 251 spin_unlock(&entry->lock);
252 fsnotify_destroy_mark(entry); 252 fsnotify_destroy_mark(entry, audit_tree_group);
253 goto out; 253 goto out;
254 } 254 }
255 255
@@ -291,7 +291,7 @@ static void untag_chunk(struct node *p)
291 owner->root = new; 291 owner->root = new;
292 spin_unlock(&hash_lock); 292 spin_unlock(&hash_lock);
293 spin_unlock(&entry->lock); 293 spin_unlock(&entry->lock);
294 fsnotify_destroy_mark(entry); 294 fsnotify_destroy_mark(entry, audit_tree_group);
295 fsnotify_put_mark(&new->mark); /* drop initial reference */ 295 fsnotify_put_mark(&new->mark); /* drop initial reference */
296 goto out; 296 goto out;
297 297
@@ -331,7 +331,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
331 spin_unlock(&hash_lock); 331 spin_unlock(&hash_lock);
332 chunk->dead = 1; 332 chunk->dead = 1;
333 spin_unlock(&entry->lock); 333 spin_unlock(&entry->lock);
334 fsnotify_destroy_mark(entry); 334 fsnotify_destroy_mark(entry, audit_tree_group);
335 fsnotify_put_mark(entry); 335 fsnotify_put_mark(entry);
336 return 0; 336 return 0;
337 } 337 }
@@ -412,7 +412,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
412 spin_unlock(&chunk_entry->lock); 412 spin_unlock(&chunk_entry->lock);
413 spin_unlock(&old_entry->lock); 413 spin_unlock(&old_entry->lock);
414 414
415 fsnotify_destroy_mark(chunk_entry); 415 fsnotify_destroy_mark(chunk_entry, audit_tree_group);
416 416
417 fsnotify_put_mark(chunk_entry); 417 fsnotify_put_mark(chunk_entry);
418 fsnotify_put_mark(old_entry); 418 fsnotify_put_mark(old_entry);
@@ -443,7 +443,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
443 spin_unlock(&hash_lock); 443 spin_unlock(&hash_lock);
444 spin_unlock(&chunk_entry->lock); 444 spin_unlock(&chunk_entry->lock);
445 spin_unlock(&old_entry->lock); 445 spin_unlock(&old_entry->lock);
446 fsnotify_destroy_mark(old_entry); 446 fsnotify_destroy_mark(old_entry, audit_tree_group);
447 fsnotify_put_mark(chunk_entry); /* drop initial reference */ 447 fsnotify_put_mark(chunk_entry); /* drop initial reference */
448 fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ 448 fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
449 return 0; 449 return 0;
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 9a9ae6e3d290..4a599f699adc 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -350,7 +350,7 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
350 } 350 }
351 mutex_unlock(&audit_filter_mutex); 351 mutex_unlock(&audit_filter_mutex);
352 352
353 fsnotify_destroy_mark(&parent->mark); 353 fsnotify_destroy_mark(&parent->mark, audit_watch_group);
354} 354}
355 355
356/* Get path information necessary for adding watches. */ 356/* Get path information necessary for adding watches. */
@@ -457,7 +457,7 @@ void audit_remove_watch_rule(struct audit_krule *krule)
457 457
458 if (list_empty(&parent->watches)) { 458 if (list_empty(&parent->watches)) {
459 audit_get_parent(parent); 459 audit_get_parent(parent);
460 fsnotify_destroy_mark(&parent->mark); 460 fsnotify_destroy_mark(&parent->mark, audit_watch_group);
461 audit_put_parent(parent); 461 audit_put_parent(parent);
462 } 462 }
463 } 463 }