aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/fsnotify.h2
-rw-r--r--fs/notify/group.c18
-rw-r--r--fs/notify/inode_mark.c7
3 files changed, 17 insertions, 10 deletions
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index ec5aee43bdc5..5bd22412017f 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -16,6 +16,8 @@ extern __u32 fsnotify_inode_mask;
16/* destroy all events sitting in this groups notification queue */ 16/* destroy all events sitting in this groups notification queue */
17extern void fsnotify_flush_notify(struct fsnotify_group *group); 17extern void fsnotify_flush_notify(struct fsnotify_group *group);
18 18
19/* add a group to the inode group list */
20extern void fsnotify_add_inode_group(struct fsnotify_group *group);
19/* final kfree of a group */ 21/* final kfree of a group */
20extern void fsnotify_final_destroy_group(struct fsnotify_group *group); 22extern void fsnotify_final_destroy_group(struct fsnotify_group *group);
21 23
diff --git a/fs/notify/group.c b/fs/notify/group.c
index 656c534ffb66..34fccbd2809c 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -77,12 +77,15 @@ void fsnotify_recalc_group_mask(struct fsnotify_group *group)
77 fsnotify_recalc_global_mask(); 77 fsnotify_recalc_global_mask();
78} 78}
79 79
80static void fsnotify_add_group(struct fsnotify_group *group) 80void fsnotify_add_inode_group(struct fsnotify_group *group)
81{ 81{
82 BUG_ON(!mutex_is_locked(&fsnotify_grp_mutex)); 82 mutex_lock(&fsnotify_grp_mutex);
83 83
84 if (!group->on_inode_group_list)
85 list_add_tail_rcu(&group->inode_group_list, &fsnotify_inode_groups);
84 group->on_inode_group_list = 1; 86 group->on_inode_group_list = 1;
85 list_add_tail_rcu(&group->inode_group_list, &fsnotify_inode_groups); 87
88 mutex_unlock(&fsnotify_grp_mutex);
86} 89}
87 90
88/* 91/*
@@ -188,22 +191,17 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
188 */ 191 */
189 atomic_set(&group->num_marks, 1); 192 atomic_set(&group->num_marks, 1);
190 193
191
192 mutex_init(&group->notification_mutex); 194 mutex_init(&group->notification_mutex);
193 INIT_LIST_HEAD(&group->notification_list); 195 INIT_LIST_HEAD(&group->notification_list);
194 init_waitqueue_head(&group->notification_waitq); 196 init_waitqueue_head(&group->notification_waitq);
195 group->max_events = UINT_MAX; 197 group->max_events = UINT_MAX;
196 198
199 INIT_LIST_HEAD(&group->inode_group_list);
200
197 spin_lock_init(&group->mark_lock); 201 spin_lock_init(&group->mark_lock);
198 INIT_LIST_HEAD(&group->mark_entries); 202 INIT_LIST_HEAD(&group->mark_entries);
199 203
200 group->ops = ops; 204 group->ops = ops;
201 205
202 mutex_lock(&fsnotify_grp_mutex);
203
204 fsnotify_add_group(group);
205
206 mutex_unlock(&fsnotify_grp_mutex);
207
208 return group; 206 return group;
209} 207}
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 7d2962e5328e..a3230c485531 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -323,6 +323,13 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry,
323 return -EINVAL; 323 return -EINVAL;
324 324
325 /* 325 /*
326 * if this group isn't being testing for inode type events we need
327 * to start testing
328 */
329 if (unlikely(list_empty(&group->inode_group_list)))
330 fsnotify_add_inode_group(group);
331
332 /*
326 * LOCKING ORDER!!!! 333 * LOCKING ORDER!!!!
327 * entry->lock 334 * entry->lock
328 * group->mark_lock 335 * group->mark_lock