diff options
author | Lino Sanfilippo <LinoSanfilippo@gmx.de> | 2013-07-08 18:59:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 13:33:20 -0400 |
commit | 52f85729805b7a0ec5a7a70e2c814193929de2f0 (patch) | |
tree | cea36db4bfc807c0dfa357da02f5bb899df863a1 /fs/notify | |
parent | 5e9c070ca085439fbec9e9629dd6171ae325d4d8 (diff) |
dnotify: replace dnotify_mark_mutex with mark mutex of dnotify_group
There is no need to use a special mutex to protect against the
fcntl/close race (see dnotify.c for a description of this race).
Instead the dnotify_groups mark mutex can be used.
Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Cc: Eric Paris <eparis@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 2bfe6dc413a0..1fedd5f7ccc4 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -31,7 +31,6 @@ int dir_notify_enable __read_mostly = 1; | |||
31 | static struct kmem_cache *dnotify_struct_cache __read_mostly; | 31 | static struct kmem_cache *dnotify_struct_cache __read_mostly; |
32 | static struct kmem_cache *dnotify_mark_cache __read_mostly; | 32 | static struct kmem_cache *dnotify_mark_cache __read_mostly; |
33 | static struct fsnotify_group *dnotify_group __read_mostly; | 33 | static struct fsnotify_group *dnotify_group __read_mostly; |
34 | static DEFINE_MUTEX(dnotify_mark_mutex); | ||
35 | 34 | ||
36 | /* | 35 | /* |
37 | * dnotify will attach one of these to each inode (i_fsnotify_marks) which | 36 | * dnotify will attach one of these to each inode (i_fsnotify_marks) which |
@@ -183,7 +182,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) | |||
183 | return; | 182 | return; |
184 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); | 183 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); |
185 | 184 | ||
186 | mutex_lock(&dnotify_mark_mutex); | 185 | mutex_lock(&dnotify_group->mark_mutex); |
187 | 186 | ||
188 | spin_lock(&fsn_mark->lock); | 187 | spin_lock(&fsn_mark->lock); |
189 | prev = &dn_mark->dn; | 188 | prev = &dn_mark->dn; |
@@ -199,11 +198,12 @@ void dnotify_flush(struct file *filp, fl_owner_t id) | |||
199 | 198 | ||
200 | spin_unlock(&fsn_mark->lock); | 199 | spin_unlock(&fsn_mark->lock); |
201 | 200 | ||
202 | /* nothing else could have found us thanks to the dnotify_mark_mutex */ | 201 | /* nothing else could have found us thanks to the dnotify_groups |
202 | mark_mutex */ | ||
203 | if (dn_mark->dn == NULL) | 203 | if (dn_mark->dn == NULL) |
204 | fsnotify_destroy_mark(fsn_mark, dnotify_group); | 204 | fsnotify_destroy_mark_locked(fsn_mark, dnotify_group); |
205 | 205 | ||
206 | mutex_unlock(&dnotify_mark_mutex); | 206 | mutex_unlock(&dnotify_group->mark_mutex); |
207 | 207 | ||
208 | fsnotify_put_mark(fsn_mark); | 208 | fsnotify_put_mark(fsn_mark); |
209 | } | 209 | } |
@@ -326,7 +326,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
326 | new_dn_mark->dn = NULL; | 326 | new_dn_mark->dn = NULL; |
327 | 327 | ||
328 | /* this is needed to prevent the fcntl/close race described below */ | 328 | /* this is needed to prevent the fcntl/close race described below */ |
329 | mutex_lock(&dnotify_mark_mutex); | 329 | mutex_lock(&dnotify_group->mark_mutex); |
330 | 330 | ||
331 | /* add the new_fsn_mark or find an old one. */ | 331 | /* add the new_fsn_mark or find an old one. */ |
332 | fsn_mark = fsnotify_find_inode_mark(dnotify_group, inode); | 332 | fsn_mark = fsnotify_find_inode_mark(dnotify_group, inode); |
@@ -334,7 +334,8 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
334 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); | 334 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); |
335 | spin_lock(&fsn_mark->lock); | 335 | spin_lock(&fsn_mark->lock); |
336 | } else { | 336 | } else { |
337 | fsnotify_add_mark(new_fsn_mark, dnotify_group, inode, NULL, 0); | 337 | fsnotify_add_mark_locked(new_fsn_mark, dnotify_group, inode, |
338 | NULL, 0); | ||
338 | spin_lock(&new_fsn_mark->lock); | 339 | spin_lock(&new_fsn_mark->lock); |
339 | fsn_mark = new_fsn_mark; | 340 | fsn_mark = new_fsn_mark; |
340 | dn_mark = new_dn_mark; | 341 | dn_mark = new_dn_mark; |
@@ -348,9 +349,9 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
348 | 349 | ||
349 | /* if (f != filp) means that we lost a race and another task/thread | 350 | /* if (f != filp) means that we lost a race and another task/thread |
350 | * actually closed the fd we are still playing with before we grabbed | 351 | * actually closed the fd we are still playing with before we grabbed |
351 | * the dnotify_mark_mutex and fsn_mark->lock. Since closing the fd is the | 352 | * the dnotify_groups mark_mutex and fsn_mark->lock. Since closing the |
352 | * only time we clean up the marks we need to get our mark off | 353 | * fd is the only time we clean up the marks we need to get our mark |
353 | * the list. */ | 354 | * off the list. */ |
354 | if (f != filp) { | 355 | if (f != filp) { |
355 | /* if we added ourselves, shoot ourselves, it's possible that | 356 | /* if we added ourselves, shoot ourselves, it's possible that |
356 | * the flush actually did shoot this fsn_mark. That's fine too | 357 | * the flush actually did shoot this fsn_mark. That's fine too |
@@ -385,9 +386,9 @@ out: | |||
385 | spin_unlock(&fsn_mark->lock); | 386 | spin_unlock(&fsn_mark->lock); |
386 | 387 | ||
387 | if (destroy) | 388 | if (destroy) |
388 | fsnotify_destroy_mark(fsn_mark, dnotify_group); | 389 | fsnotify_destroy_mark_locked(fsn_mark, dnotify_group); |
389 | 390 | ||
390 | mutex_unlock(&dnotify_mark_mutex); | 391 | mutex_unlock(&dnotify_group->mark_mutex); |
391 | fsnotify_put_mark(fsn_mark); | 392 | fsnotify_put_mark(fsn_mark); |
392 | out_err: | 393 | out_err: |
393 | if (new_fsn_mark) | 394 | if (new_fsn_mark) |