aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/mark.c
diff options
context:
space:
mode:
authorLino Sanfilippo <LinoSanfilippo@gmx.de>2011-06-14 11:29:52 -0400
committerEric Paris <eparis@redhat.com>2012-12-11 13:44:36 -0500
commitd5a335b845792d2a69ed1e244c0b233117b7db3c (patch)
tree7a340810ee8cba71ba90ab61f2a9bcef7c63a158 /fs/notify/mark.c
parente2a29943e9a2ee2aa737a77f550f46ba72269db4 (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.c42
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 */
124void fsnotify_destroy_mark(struct fsnotify_mark *mark, 124void 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
193void 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
189void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) 201void 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 */
211int fsnotify_add_mark(struct fsnotify_mark *mark, 223int 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
285int 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 */