diff options
| author | Lino Sanfilippo <LinoSanfilippo@gmx.de> | 2011-06-14 11:29:50 -0400 |
|---|---|---|
| committer | Eric Paris <eparis@redhat.com> | 2012-12-11 13:29:46 -0500 |
| commit | 986ab09807ca9454c3f54aae4db7e1bb00daeed3 (patch) | |
| tree | d6b76b03624a2d95a73ba88d990cd5210ab9eb20 | |
| parent | 6dfbd149946c22c2e2886d6b560def78630c8387 (diff) | |
fsnotify: use a mutex instead of a spinlock to protect a groups mark list
Replaces the groups mark_lock spinlock with a mutex. Using a mutex instead
of a spinlock results in more flexibility (i.e it allows to sleep while the
lock is held).
Signed-off-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Signed-off-by: Eric Paris <eparis@redhat.com>
| -rw-r--r-- | fs/notify/group.c | 2 | ||||
| -rw-r--r-- | fs/notify/inode_mark.c | 4 | ||||
| -rw-r--r-- | fs/notify/mark.c | 18 | ||||
| -rw-r--r-- | fs/notify/vfsmount_mark.c | 4 | ||||
| -rw-r--r-- | include/linux/fsnotify_backend.h | 2 |
5 files changed, 15 insertions, 15 deletions
diff --git a/fs/notify/group.c b/fs/notify/group.c index 354044c47e23..1f7305711fc9 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c | |||
| @@ -95,7 +95,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) | |||
| 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; |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index b13c00ac48eb..4e9071e37d5d 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 | ||
| @@ -191,8 +191,8 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark, | |||
| 191 | 191 | ||
| 192 | mark->flags |= FSNOTIFY_MARK_FLAG_INODE; | 192 | mark->flags |= FSNOTIFY_MARK_FLAG_INODE; |
| 193 | 193 | ||
| 194 | BUG_ON(!mutex_is_locked(&group->mark_mutex)); | ||
| 194 | assert_spin_locked(&mark->lock); | 195 | assert_spin_locked(&mark->lock); |
| 195 | assert_spin_locked(&group->mark_lock); | ||
| 196 | 196 | ||
| 197 | spin_lock(&inode->i_lock); | 197 | spin_lock(&inode->i_lock); |
| 198 | 198 | ||
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 32447dc06c07..ab25b810b146 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
| @@ -136,13 +136,13 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark) | |||
| 136 | group = mark->group; | 136 | group = mark->group; |
| 137 | spin_unlock(&mark->lock); | 137 | spin_unlock(&mark->lock); |
| 138 | 138 | ||
| 139 | spin_lock(&group->mark_lock); | 139 | mutex_lock(&group->mark_mutex); |
| 140 | spin_lock(&mark->lock); | 140 | spin_lock(&mark->lock); |
| 141 | 141 | ||
| 142 | /* something else already called this function on this mark */ | 142 | /* something else already called this function on this mark */ |
| 143 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { | 143 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { |
| 144 | spin_unlock(&mark->lock); | 144 | spin_unlock(&mark->lock); |
| 145 | spin_unlock(&group->mark_lock); | 145 | mutex_unlock(&group->mark_mutex); |
| 146 | goto put_group; | 146 | goto put_group; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| @@ -159,7 +159,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark) | |||
| 159 | list_del_init(&mark->g_list); | 159 | list_del_init(&mark->g_list); |
| 160 | 160 | ||
| 161 | spin_unlock(&mark->lock); | 161 | spin_unlock(&mark->lock); |
| 162 | spin_unlock(&group->mark_lock); | 162 | mutex_unlock(&group->mark_mutex); |
| 163 | 163 | ||
| 164 | spin_lock(&destroy_lock); | 164 | spin_lock(&destroy_lock); |
| 165 | list_add(&mark->destroy_list, &destroy_list); | 165 | list_add(&mark->destroy_list, &destroy_list); |
| @@ -232,11 +232,11 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, | |||
| 232 | 232 | ||
| 233 | /* | 233 | /* |
| 234 | * LOCKING ORDER!!!! | 234 | * LOCKING ORDER!!!! |
| 235 | * group->mark_lock | 235 | * group->mark_mutex |
| 236 | * mark->lock | 236 | * mark->lock |
| 237 | * inode->i_lock | 237 | * inode->i_lock |
| 238 | */ | 238 | */ |
| 239 | spin_lock(&group->mark_lock); | 239 | mutex_lock(&group->mark_mutex); |
| 240 | 240 | ||
| 241 | spin_lock(&mark->lock); | 241 | spin_lock(&mark->lock); |
| 242 | mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE; | 242 | mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE; |
| @@ -263,7 +263,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, | |||
| 263 | fsnotify_set_mark_mask_locked(mark, mark->mask); | 263 | fsnotify_set_mark_mask_locked(mark, mark->mask); |
| 264 | spin_unlock(&mark->lock); | 264 | spin_unlock(&mark->lock); |
| 265 | 265 | ||
| 266 | spin_unlock(&group->mark_lock); | 266 | mutex_unlock(&group->mark_mutex); |
| 267 | 267 | ||
| 268 | if (inode) | 268 | if (inode) |
| 269 | __fsnotify_update_child_dentry_flags(inode); | 269 | __fsnotify_update_child_dentry_flags(inode); |
| @@ -277,7 +277,7 @@ err: | |||
| 277 | atomic_dec(&group->num_marks); | 277 | atomic_dec(&group->num_marks); |
| 278 | 278 | ||
| 279 | spin_unlock(&mark->lock); | 279 | spin_unlock(&mark->lock); |
| 280 | spin_unlock(&group->mark_lock); | 280 | mutex_unlock(&group->mark_mutex); |
| 281 | 281 | ||
| 282 | spin_lock(&destroy_lock); | 282 | spin_lock(&destroy_lock); |
| 283 | list_add(&mark->destroy_list, &destroy_list); | 283 | list_add(&mark->destroy_list, &destroy_list); |
| @@ -296,7 +296,7 @@ void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, | |||
| 296 | struct fsnotify_mark *lmark, *mark; | 296 | struct fsnotify_mark *lmark, *mark; |
| 297 | LIST_HEAD(free_list); | 297 | LIST_HEAD(free_list); |
| 298 | 298 | ||
| 299 | spin_lock(&group->mark_lock); | 299 | mutex_lock(&group->mark_mutex); |
| 300 | list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { | 300 | list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { |
| 301 | if (mark->flags & flags) { | 301 | if (mark->flags & flags) { |
| 302 | list_add(&mark->free_g_list, &free_list); | 302 | list_add(&mark->free_g_list, &free_list); |
| @@ -304,7 +304,7 @@ void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, | |||
| 304 | fsnotify_get_mark(mark); | 304 | fsnotify_get_mark(mark); |
| 305 | } | 305 | } |
| 306 | } | 306 | } |
| 307 | spin_unlock(&group->mark_lock); | 307 | mutex_unlock(&group->mark_mutex); |
| 308 | 308 | ||
| 309 | list_for_each_entry_safe(mark, lmark, &free_list, free_g_list) { | 309 | list_for_each_entry_safe(mark, lmark, &free_list, free_g_list) { |
| 310 | fsnotify_destroy_mark(mark); | 310 | fsnotify_destroy_mark(mark); |
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c index b7b4b0e8554f..f26a348827f8 100644 --- a/fs/notify/vfsmount_mark.c +++ b/fs/notify/vfsmount_mark.c | |||
| @@ -88,8 +88,8 @@ void fsnotify_destroy_vfsmount_mark(struct fsnotify_mark *mark) | |||
| 88 | { | 88 | { |
| 89 | struct vfsmount *mnt = mark->m.mnt; | 89 | struct vfsmount *mnt = mark->m.mnt; |
| 90 | 90 | ||
| 91 | BUG_ON(!mutex_is_locked(&mark->group->mark_mutex)); | ||
| 91 | assert_spin_locked(&mark->lock); | 92 | assert_spin_locked(&mark->lock); |
| 92 | assert_spin_locked(&mark->group->mark_lock); | ||
| 93 | 93 | ||
| 94 | spin_lock(&mnt->mnt_root->d_lock); | 94 | spin_lock(&mnt->mnt_root->d_lock); |
| 95 | 95 | ||
| @@ -151,8 +151,8 @@ int fsnotify_add_vfsmount_mark(struct fsnotify_mark *mark, | |||
| 151 | 151 | ||
| 152 | mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; | 152 | mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT; |
| 153 | 153 | ||
| 154 | BUG_ON(!mutex_is_locked(&group->mark_mutex)); | ||
| 154 | assert_spin_locked(&mark->lock); | 155 | assert_spin_locked(&mark->lock); |
| 155 | assert_spin_locked(&group->mark_lock); | ||
| 156 | 156 | ||
| 157 | spin_lock(&mnt->mnt_root->d_lock); | 157 | spin_lock(&mnt->mnt_root->d_lock); |
| 158 | 158 | ||
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index e76cef75295d..c5848346840d 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -141,7 +141,7 @@ struct fsnotify_group { | |||
| 141 | unsigned int priority; | 141 | unsigned int priority; |
| 142 | 142 | ||
| 143 | /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ | 143 | /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ |
| 144 | spinlock_t mark_lock; /* protect marks_list */ | 144 | struct mutex mark_mutex; /* protect marks_list */ |
| 145 | atomic_t num_marks; /* 1 for each mark and 1 for not being | 145 | atomic_t num_marks; /* 1 for each mark and 1 for not being |
| 146 | * past the point of no return when freeing | 146 | * past the point of no return when freeing |
| 147 | * a group */ | 147 | * a group */ |
