diff options
author | Lino Sanfilippo <LinoSanfilippo@gmx.de> | 2011-06-14 11:29:52 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2012-12-11 13:44:36 -0500 |
commit | d5a335b845792d2a69ed1e244c0b233117b7db3c (patch) | |
tree | 7a340810ee8cba71ba90ab61f2a9bcef7c63a158 /fs/notify/mark.c | |
parent | e2a29943e9a2ee2aa737a77f550f46ba72269db4 (diff) |
fsnotify: introduce locked versions of fsnotify_add_mark() and fsnotify_remove_mark()
This patch introduces fsnotify_add_mark_locked() and fsnotify_remove_mark_locked()
which are essentially the same as fsnotify_add_mark() and fsnotify_remove_mark() but
assume that the caller has already taken the groups mark mutex.
Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs/notify/mark.c')
-rw-r--r-- | fs/notify/mark.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index b77c833c8d0a..f9dda0304a10 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
@@ -121,18 +121,18 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) | |||
121 | * 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 |
122 | * do the final put under the mark->lock | 122 | * do the final put under the mark->lock |
123 | */ | 123 | */ |
124 | void fsnotify_destroy_mark(struct fsnotify_mark *mark, | 124 | void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark, |
125 | struct fsnotify_group *group) | 125 | struct fsnotify_group *group) |
126 | { | 126 | { |
127 | struct inode *inode = NULL; | 127 | struct inode *inode = NULL; |
128 | 128 | ||
129 | mutex_lock(&group->mark_mutex); | 129 | BUG_ON(!mutex_is_locked(&group->mark_mutex)); |
130 | |||
130 | spin_lock(&mark->lock); | 131 | spin_lock(&mark->lock); |
131 | 132 | ||
132 | /* something else already called this function on this mark */ | 133 | /* something else already called this function on this mark */ |
133 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { | 134 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { |
134 | spin_unlock(&mark->lock); | 135 | spin_unlock(&mark->lock); |
135 | mutex_unlock(&group->mark_mutex); | ||
136 | return; | 136 | return; |
137 | } | 137 | } |
138 | 138 | ||
@@ -149,6 +149,8 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, | |||
149 | list_del_init(&mark->g_list); | 149 | list_del_init(&mark->g_list); |
150 | 150 | ||
151 | spin_unlock(&mark->lock); | 151 | spin_unlock(&mark->lock); |
152 | |||
153 | /* release lock temporarily */ | ||
152 | mutex_unlock(&group->mark_mutex); | 154 | mutex_unlock(&group->mark_mutex); |
153 | 155 | ||
154 | spin_lock(&destroy_lock); | 156 | spin_lock(&destroy_lock); |
@@ -184,6 +186,16 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, | |||
184 | */ | 186 | */ |
185 | 187 | ||
186 | atomic_dec(&group->num_marks); | 188 | atomic_dec(&group->num_marks); |
189 | |||
190 | mutex_lock(&group->mark_mutex); | ||
191 | } | ||
192 | |||
193 | void fsnotify_destroy_mark(struct fsnotify_mark *mark, | ||
194 | struct fsnotify_group *group) | ||
195 | { | ||
196 | mutex_lock(&group->mark_mutex); | ||
197 | fsnotify_destroy_mark_locked(mark, group); | ||
198 | mutex_unlock(&group->mark_mutex); | ||
187 | } | 199 | } |
188 | 200 | ||
189 | void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) | 201 | void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) |
@@ -208,14 +220,15 @@ void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mas | |||
208 | * 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 |
209 | * event types should be delivered to which group. | 221 | * event types should be delivered to which group. |
210 | */ | 222 | */ |
211 | int fsnotify_add_mark(struct fsnotify_mark *mark, | 223 | int fsnotify_add_mark_locked(struct fsnotify_mark *mark, |
212 | struct fsnotify_group *group, struct inode *inode, | 224 | struct fsnotify_group *group, struct inode *inode, |
213 | struct vfsmount *mnt, int allow_dups) | 225 | struct vfsmount *mnt, int allow_dups) |
214 | { | 226 | { |
215 | int ret = 0; | 227 | int ret = 0; |
216 | 228 | ||
217 | BUG_ON(inode && mnt); | 229 | BUG_ON(inode && mnt); |
218 | BUG_ON(!inode && !mnt); | 230 | BUG_ON(!inode && !mnt); |
231 | BUG_ON(!mutex_is_locked(&group->mark_mutex)); | ||
219 | 232 | ||
220 | /* | 233 | /* |
221 | * LOCKING ORDER!!!! | 234 | * LOCKING ORDER!!!! |
@@ -223,8 +236,6 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, | |||
223 | * mark->lock | 236 | * mark->lock |
224 | * inode->i_lock | 237 | * inode->i_lock |
225 | */ | 238 | */ |
226 | mutex_lock(&group->mark_mutex); | ||
227 | |||
228 | spin_lock(&mark->lock); | 239 | spin_lock(&mark->lock); |
229 | mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE; | 240 | mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE; |
230 | 241 | ||
@@ -250,8 +261,6 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, | |||
250 | fsnotify_set_mark_mask_locked(mark, mark->mask); | 261 | fsnotify_set_mark_mask_locked(mark, mark->mask); |
251 | spin_unlock(&mark->lock); | 262 | spin_unlock(&mark->lock); |
252 | 263 | ||
253 | mutex_unlock(&group->mark_mutex); | ||
254 | |||
255 | if (inode) | 264 | if (inode) |
256 | __fsnotify_update_child_dentry_flags(inode); | 265 | __fsnotify_update_child_dentry_flags(inode); |
257 | 266 | ||
@@ -264,7 +273,6 @@ err: | |||
264 | atomic_dec(&group->num_marks); | 273 | atomic_dec(&group->num_marks); |
265 | 274 | ||
266 | spin_unlock(&mark->lock); | 275 | spin_unlock(&mark->lock); |
267 | mutex_unlock(&group->mark_mutex); | ||
268 | 276 | ||
269 | spin_lock(&destroy_lock); | 277 | spin_lock(&destroy_lock); |
270 | list_add(&mark->destroy_list, &destroy_list); | 278 | list_add(&mark->destroy_list, &destroy_list); |
@@ -274,6 +282,16 @@ err: | |||
274 | return ret; | 282 | return ret; |
275 | } | 283 | } |
276 | 284 | ||
285 | int 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 | |||
277 | /* | 295 | /* |
278 | * 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 |
279 | */ | 297 | */ |