aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-07-28 10:18:39 -0400
committerEric Paris <eparis@redhat.com>2010-07-28 10:18:54 -0400
commit02436668d98385f5b5d9ffb695a37dadf98ed8a8 (patch)
treee0e37328a9ba5c0af49903114fffd82f2141180d /fs
parent43709a288ed03aa0e2979ab63dd089b3889645c4 (diff)
fsnotify: remove global fsnotify groups lists
The global fsnotify groups lists were invented as a way to increase the performance of fsnotify by shortcutting events which were not interesting. With the changes to walk the object lists rather than global groups lists these shortcuts are not useful. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/notify/fsnotify.c5
-rw-r--r--fs/notify/fsnotify.h9
-rw-r--r--fs/notify/group.c107
-rw-r--r--fs/notify/mark.c9
4 files changed, 2 insertions, 128 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 9ba29ee747cf..1dd1fde1da08 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -219,11 +219,6 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
219 /* global tests shouldn't care about events on child only the specific event */ 219 /* global tests shouldn't care about events on child only the specific event */
220 __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); 220 __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
221 221
222 /* if no fsnotify listeners, nothing to do */
223 if (list_empty(&fsnotify_inode_groups) &&
224 list_empty(&fsnotify_vfsmount_groups))
225 return 0;
226
227 if (mask & FS_MODIFY) 222 if (mask & FS_MODIFY)
228 __fsnotify_flush_ignored_mask(to_tell, data, data_is); 223 __fsnotify_flush_ignored_mask(to_tell, data, data_is);
229 224
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index b41dbf5a125c..85e7d2b431d9 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -6,11 +6,6 @@
6#include <linux/srcu.h> 6#include <linux/srcu.h>
7#include <linux/types.h> 7#include <linux/types.h>
8 8
9/* all groups which receive inode fsnotify events */
10extern struct list_head fsnotify_inode_groups;
11/* all groups which receive vfsmount fsnotify events */
12extern struct list_head fsnotify_vfsmount_groups;
13
14/* destroy all events sitting in this groups notification queue */ 9/* destroy all events sitting in this groups notification queue */
15extern void fsnotify_flush_notify(struct fsnotify_group *group); 10extern void fsnotify_flush_notify(struct fsnotify_group *group);
16 11
@@ -28,10 +23,6 @@ extern int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark,
28 struct fsnotify_group *group, struct vfsmount *mnt, 23 struct fsnotify_group *group, struct vfsmount *mnt,
29 int allow_dups); 24 int allow_dups);
30 25
31/* add a group to the inode group list */
32extern void fsnotify_add_inode_group(struct fsnotify_group *group);
33/* add a group to the vfsmount group list */
34extern void fsnotify_add_vfsmount_group(struct fsnotify_group *group);
35/* final kfree of a group */ 26/* final kfree of a group */
36extern void fsnotify_final_destroy_group(struct fsnotify_group *group); 27extern void fsnotify_final_destroy_group(struct fsnotify_group *group);
37 28
diff --git a/fs/notify/group.c b/fs/notify/group.c
index fc0d966b270f..d309f38449cb 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -28,67 +28,6 @@
28 28
29#include <asm/atomic.h> 29#include <asm/atomic.h>
30 30
31/* protects writes to fsnotify_groups and fsnotify_mask */
32static DEFINE_MUTEX(fsnotify_grp_mutex);
33/* all groups registered to receive inode filesystem notifications */
34LIST_HEAD(fsnotify_inode_groups);
35/* all groups registered to receive mount point filesystem notifications */
36LIST_HEAD(fsnotify_vfsmount_groups);
37
38void fsnotify_add_vfsmount_group(struct fsnotify_group *group)
39{
40 struct fsnotify_group *group_iter;
41
42 mutex_lock(&fsnotify_grp_mutex);
43
44 if (!group->on_vfsmount_group_list) {
45 list_for_each_entry(group_iter, &fsnotify_vfsmount_groups,
46 vfsmount_group_list) {
47 /* insert in front of this one? */
48 if (group < group_iter) {
49 /* list_add_tail() insert in front of group_iter */
50 list_add_tail_rcu(&group->inode_group_list,
51 &group_iter->inode_group_list);
52 goto out;
53 }
54 }
55
56 /* apparently we need to be the last entry */
57 list_add_tail_rcu(&group->vfsmount_group_list, &fsnotify_vfsmount_groups);
58 }
59out:
60 group->on_vfsmount_group_list = 1;
61
62 mutex_unlock(&fsnotify_grp_mutex);
63}
64
65void fsnotify_add_inode_group(struct fsnotify_group *group)
66{
67 struct fsnotify_group *group_iter;
68
69 mutex_lock(&fsnotify_grp_mutex);
70
71 /* add to global group list */
72 if (!group->on_inode_group_list) {
73 list_for_each_entry(group_iter, &fsnotify_inode_groups,
74 inode_group_list) {
75 if (group < group_iter) {
76 /* list_add_tail() insert in front of group_iter */
77 list_add_tail_rcu(&group->inode_group_list,
78 &group_iter->inode_group_list);
79 goto out;
80 }
81 }
82
83 /* apparently we need to be the last entry */
84 list_add_tail_rcu(&group->inode_group_list, &fsnotify_inode_groups);
85 }
86out:
87 group->on_inode_group_list = 1;
88
89 mutex_unlock(&fsnotify_grp_mutex);
90}
91
92/* 31/*
93 * Final freeing of a group 32 * Final freeing of a group
94 */ 33 */
@@ -124,51 +63,12 @@ static void fsnotify_destroy_group(struct fsnotify_group *group)
124} 63}
125 64
126/* 65/*
127 * Remove this group from the global list of groups that will get events
128 * this can be done even if there are still references and things still using
129 * this group. This just stops the group from getting new events.
130 */
131static void __fsnotify_evict_group(struct fsnotify_group *group)
132{
133 BUG_ON(!mutex_is_locked(&fsnotify_grp_mutex));
134
135 if (group->on_inode_group_list)
136 list_del_rcu(&group->inode_group_list);
137 group->on_inode_group_list = 0;
138 if (group->on_vfsmount_group_list)
139 list_del_rcu(&group->vfsmount_group_list);
140 group->on_vfsmount_group_list = 0;
141}
142
143/*
144 * Called when a group is no longer interested in getting events. This can be
145 * used if a group is misbehaving or if for some reason a group should no longer
146 * get any filesystem events.
147 */
148void fsnotify_evict_group(struct fsnotify_group *group)
149{
150 mutex_lock(&fsnotify_grp_mutex);
151 __fsnotify_evict_group(group);
152 mutex_unlock(&fsnotify_grp_mutex);
153}
154
155/*
156 * Drop a reference to a group. Free it if it's through. 66 * Drop a reference to a group. Free it if it's through.
157 */ 67 */
158void fsnotify_put_group(struct fsnotify_group *group) 68void fsnotify_put_group(struct fsnotify_group *group)
159{ 69{
160 if (!atomic_dec_and_mutex_lock(&group->refcnt, &fsnotify_grp_mutex)) 70 if (atomic_dec_and_test(&group->refcnt))
161 return; 71 fsnotify_destroy_group(group);
162
163 /*
164 * OK, now we know that there's no other users *and* we hold mutex,
165 * so no new references will appear
166 */
167 __fsnotify_evict_group(group);
168
169 mutex_unlock(&fsnotify_grp_mutex);
170
171 fsnotify_destroy_group(group);
172} 72}
173 73
174/* 74/*
@@ -195,9 +95,6 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
195 init_waitqueue_head(&group->notification_waitq); 95 init_waitqueue_head(&group->notification_waitq);
196 group->max_events = UINT_MAX; 96 group->max_events = UINT_MAX;
197 97
198 INIT_LIST_HEAD(&group->inode_group_list);
199 INIT_LIST_HEAD(&group->vfsmount_group_list);
200
201 spin_lock_init(&group->mark_lock); 98 spin_lock_init(&group->mark_lock);
202 INIT_LIST_HEAD(&group->marks_list); 99 INIT_LIST_HEAD(&group->marks_list);
203 100
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 236f29b066ed..325185e514bb 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -223,15 +223,6 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
223 BUG_ON(!inode && !mnt); 223 BUG_ON(!inode && !mnt);
224 224
225 /* 225 /*
226 * if this group isn't being testing for inode type events we need
227 * to start testing
228 */
229 if (inode && unlikely(list_empty(&group->inode_group_list)))
230 fsnotify_add_inode_group(group);
231 else if (mnt && unlikely(list_empty(&group->vfsmount_group_list)))
232 fsnotify_add_vfsmount_group(group);
233
234 /*
235 * LOCKING ORDER!!!! 226 * LOCKING ORDER!!!!
236 * mark->lock 227 * mark->lock
237 * group->mark_lock 228 * group->mark_lock