diff options
author | Andreas Gruenbacher <agruen@suse.de> | 2009-12-17 21:24:25 -0500 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2010-07-28 09:58:54 -0400 |
commit | 35566087099c3ff8901d65ee98af56347ee66e5a (patch) | |
tree | e4e56bcf787e5f100fa1ea0138c417e1203b10ae | |
parent | ef5e2b785fb3216269e6d0656d38ec286b98dbe5 (diff) |
fsnotify: take inode->i_lock inside fsnotify_find_mark_entry()
All callers to fsnotify_find_mark_entry() except one take and
release inode->i_lock around the call. Take the lock inside
fsnotify_find_mark_entry() instead.
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Signed-off-by: Eric Paris <eparis@redhat.com>
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 12 | ||||
-rw-r--r-- | fs/notify/inode_mark.c | 26 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 4 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 2 | ||||
-rw-r--r-- | kernel/audit_tree.c | 2 | ||||
-rw-r--r-- | kernel/audit_watch.c | 5 |
6 files changed, 19 insertions, 32 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 3efb8b9a572d..cac2eb896639 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -95,11 +95,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, | |||
95 | 95 | ||
96 | to_tell = event->to_tell; | 96 | to_tell = event->to_tell; |
97 | 97 | ||
98 | spin_lock(&to_tell->i_lock); | ||
99 | fsn_mark = fsnotify_find_mark(group, to_tell); | 98 | fsn_mark = fsnotify_find_mark(group, to_tell); |
100 | spin_unlock(&to_tell->i_lock); | ||
101 | |||
102 | /* unlikely since we alreay passed dnotify_should_send_event() */ | ||
103 | if (unlikely(!fsn_mark)) | 99 | if (unlikely(!fsn_mark)) |
104 | return 0; | 100 | return 0; |
105 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); | 101 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); |
@@ -147,11 +143,7 @@ static bool dnotify_should_send_event(struct fsnotify_group *group, | |||
147 | if (!S_ISDIR(inode->i_mode)) | 143 | if (!S_ISDIR(inode->i_mode)) |
148 | return false; | 144 | return false; |
149 | 145 | ||
150 | spin_lock(&inode->i_lock); | ||
151 | fsn_mark = fsnotify_find_mark(group, inode); | 146 | fsn_mark = fsnotify_find_mark(group, inode); |
152 | spin_unlock(&inode->i_lock); | ||
153 | |||
154 | /* no mark means no dnotify watch */ | ||
155 | if (!fsn_mark) | 147 | if (!fsn_mark) |
156 | return false; | 148 | return false; |
157 | 149 | ||
@@ -201,9 +193,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) | |||
201 | if (!S_ISDIR(inode->i_mode)) | 193 | if (!S_ISDIR(inode->i_mode)) |
202 | return; | 194 | return; |
203 | 195 | ||
204 | spin_lock(&inode->i_lock); | ||
205 | fsn_mark = fsnotify_find_mark(dnotify_group, inode); | 196 | fsn_mark = fsnotify_find_mark(dnotify_group, inode); |
206 | spin_unlock(&inode->i_lock); | ||
207 | if (!fsn_mark) | 197 | if (!fsn_mark) |
208 | return; | 198 | return; |
209 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); | 199 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); |
@@ -356,9 +346,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
356 | mutex_lock(&dnotify_mark_mutex); | 346 | mutex_lock(&dnotify_mark_mutex); |
357 | 347 | ||
358 | /* add the new_fsn_mark or find an old one. */ | 348 | /* add the new_fsn_mark or find an old one. */ |
359 | spin_lock(&inode->i_lock); | ||
360 | fsn_mark = fsnotify_find_mark(dnotify_group, inode); | 349 | fsn_mark = fsnotify_find_mark(dnotify_group, inode); |
361 | spin_unlock(&inode->i_lock); | ||
362 | if (fsn_mark) { | 350 | if (fsn_mark) { |
363 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); | 351 | dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark); |
364 | spin_lock(&fsn_mark->lock); | 352 | spin_lock(&fsn_mark->lock); |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index 27c1b43ad739..ba6f9833561b 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
@@ -261,12 +261,8 @@ void fsnotify_clear_marks_by_inode(struct inode *inode) | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | /* | 264 | static struct fsnotify_mark *fsnotify_find_mark_locked(struct fsnotify_group *group, |
265 | * given a group and inode, find the mark associated with that combination. | 265 | struct inode *inode) |
266 | * if found take a reference to that mark and return it, else return NULL | ||
267 | */ | ||
268 | struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_group *group, | ||
269 | struct inode *inode) | ||
270 | { | 266 | { |
271 | struct fsnotify_mark *mark; | 267 | struct fsnotify_mark *mark; |
272 | struct hlist_node *pos; | 268 | struct hlist_node *pos; |
@@ -282,6 +278,22 @@ struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_group *group, | |||
282 | return NULL; | 278 | return NULL; |
283 | } | 279 | } |
284 | 280 | ||
281 | /* | ||
282 | * given a group and inode, find the mark associated with that combination. | ||
283 | * if found take a reference to that mark and return it, else return NULL | ||
284 | */ | ||
285 | struct fsnotify_mark *fsnotify_find_mark(struct fsnotify_group *group, | ||
286 | struct inode *inode) | ||
287 | { | ||
288 | struct fsnotify_mark *mark; | ||
289 | |||
290 | spin_lock(&inode->i_lock); | ||
291 | mark = fsnotify_find_mark_locked(group, inode); | ||
292 | spin_unlock(&inode->i_lock); | ||
293 | |||
294 | return mark; | ||
295 | } | ||
296 | |||
285 | void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) | 297 | void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old) |
286 | { | 298 | { |
287 | assert_spin_locked(&old->lock); | 299 | assert_spin_locked(&old->lock); |
@@ -349,7 +361,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, | |||
349 | spin_lock(&inode->i_lock); | 361 | spin_lock(&inode->i_lock); |
350 | 362 | ||
351 | if (!allow_dups) | 363 | if (!allow_dups) |
352 | lmark = fsnotify_find_mark(group, inode); | 364 | lmark = fsnotify_find_mark_locked(group, inode); |
353 | if (!lmark) { | 365 | if (!lmark) { |
354 | mark->group = group; | 366 | mark->group = group; |
355 | mark->i.inode = inode; | 367 | mark->i.inode = inode; |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 12dc72be992e..cc8f6bcbb4a3 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -97,9 +97,7 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev | |||
97 | 97 | ||
98 | to_tell = event->to_tell; | 98 | to_tell = event->to_tell; |
99 | 99 | ||
100 | spin_lock(&to_tell->i_lock); | ||
101 | fsn_mark = fsnotify_find_mark(group, to_tell); | 100 | fsn_mark = fsnotify_find_mark(group, to_tell); |
102 | spin_unlock(&to_tell->i_lock); | ||
103 | /* race with watch removal? We already passes should_send */ | 101 | /* race with watch removal? We already passes should_send */ |
104 | if (unlikely(!fsn_mark)) | 102 | if (unlikely(!fsn_mark)) |
105 | return 0; | 103 | return 0; |
@@ -147,9 +145,7 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode | |||
147 | struct fsnotify_mark *fsn_mark; | 145 | struct fsnotify_mark *fsn_mark; |
148 | bool send; | 146 | bool send; |
149 | 147 | ||
150 | spin_lock(&inode->i_lock); | ||
151 | fsn_mark = fsnotify_find_mark(group, inode); | 148 | fsn_mark = fsnotify_find_mark(group, inode); |
152 | spin_unlock(&inode->i_lock); | ||
153 | if (!fsn_mark) | 149 | if (!fsn_mark) |
154 | return false; | 150 | return false; |
155 | 151 | ||
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 80d102acb86b..ad5a1ea7827e 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -566,9 +566,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, | |||
566 | if (unlikely(!mask)) | 566 | if (unlikely(!mask)) |
567 | return -EINVAL; | 567 | return -EINVAL; |
568 | 568 | ||
569 | spin_lock(&inode->i_lock); | ||
570 | fsn_mark = fsnotify_find_mark(group, inode); | 569 | fsn_mark = fsnotify_find_mark(group, inode); |
571 | spin_unlock(&inode->i_lock); | ||
572 | if (!fsn_mark) | 570 | if (!fsn_mark) |
573 | return -ENOENT; | 571 | return -ENOENT; |
574 | 572 | ||
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index b20fb055d712..80f8ac328aad 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -360,9 +360,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
360 | struct node *p; | 360 | struct node *p; |
361 | int n; | 361 | int n; |
362 | 362 | ||
363 | spin_lock(&inode->i_lock); | ||
364 | old_entry = fsnotify_find_mark(audit_tree_group, inode); | 363 | old_entry = fsnotify_find_mark(audit_tree_group, inode); |
365 | spin_unlock(&inode->i_lock); | ||
366 | if (!old_entry) | 364 | if (!old_entry) |
367 | return create_chunk(inode, tree); | 365 | return create_chunk(inode, tree); |
368 | 366 | ||
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 24ecbebf4354..d85fa538a722 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -101,10 +101,7 @@ static inline struct audit_parent *audit_find_parent(struct inode *inode) | |||
101 | struct audit_parent *parent = NULL; | 101 | struct audit_parent *parent = NULL; |
102 | struct fsnotify_mark *entry; | 102 | struct fsnotify_mark *entry; |
103 | 103 | ||
104 | spin_lock(&inode->i_lock); | ||
105 | entry = fsnotify_find_mark(audit_watch_group, inode); | 104 | entry = fsnotify_find_mark(audit_watch_group, inode); |
106 | spin_unlock(&inode->i_lock); | ||
107 | |||
108 | if (entry) | 105 | if (entry) |
109 | parent = container_of(entry, struct audit_parent, mark); | 106 | parent = container_of(entry, struct audit_parent, mark); |
110 | 107 | ||
@@ -520,9 +517,7 @@ static bool audit_watch_should_send_event(struct fsnotify_group *group, struct i | |||
520 | struct fsnotify_mark *entry; | 517 | struct fsnotify_mark *entry; |
521 | bool send; | 518 | bool send; |
522 | 519 | ||
523 | spin_lock(&inode->i_lock); | ||
524 | entry = fsnotify_find_mark(group, inode); | 520 | entry = fsnotify_find_mark(group, inode); |
525 | spin_unlock(&inode->i_lock); | ||
526 | if (!entry) | 521 | if (!entry) |
527 | return false; | 522 | return false; |
528 | 523 | ||