diff options
| -rw-r--r-- | fs/notify/dnotify/dnotify.c | 4 | ||||
| -rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 4 | ||||
| -rw-r--r-- | fs/notify/inode_mark.c | 10 | ||||
| -rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 2 | ||||
| -rw-r--r-- | fs/notify/inotify/inotify_user.c | 2 | ||||
| -rw-r--r-- | fs/notify/mark.c | 21 | ||||
| -rw-r--r-- | fs/notify/vfsmount_mark.c | 10 | ||||
| -rw-r--r-- | include/linux/fsnotify_backend.h | 5 | ||||
| -rw-r--r-- | kernel/audit_tree.c | 10 | ||||
| -rw-r--r-- | kernel/audit_watch.c | 4 |
10 files changed, 38 insertions, 34 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 3344bdd5506e..08b886f119ce 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
| @@ -201,7 +201,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) | |||
| 201 | 201 | ||
| 202 | /* nothing else could have found us thanks to the dnotify_mark_mutex */ | 202 | /* nothing else could have found us thanks to the dnotify_mark_mutex */ |
| 203 | if (dn_mark->dn == NULL) | 203 | if (dn_mark->dn == NULL) |
| 204 | fsnotify_destroy_mark(fsn_mark); | 204 | fsnotify_destroy_mark(fsn_mark, dnotify_group); |
| 205 | 205 | ||
| 206 | mutex_unlock(&dnotify_mark_mutex); | 206 | mutex_unlock(&dnotify_mark_mutex); |
| 207 | 207 | ||
| @@ -385,7 +385,7 @@ out: | |||
| 385 | spin_unlock(&fsn_mark->lock); | 385 | spin_unlock(&fsn_mark->lock); |
| 386 | 386 | ||
| 387 | if (destroy) | 387 | if (destroy) |
| 388 | fsnotify_destroy_mark(fsn_mark); | 388 | fsnotify_destroy_mark(fsn_mark, dnotify_group); |
| 389 | 389 | ||
| 390 | mutex_unlock(&dnotify_mark_mutex); | 390 | mutex_unlock(&dnotify_mark_mutex); |
| 391 | fsnotify_put_mark(fsn_mark); | 391 | fsnotify_put_mark(fsn_mark); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 599a01952c74..1218d10424d0 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
| @@ -546,7 +546,7 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, | |||
| 546 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, | 546 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, |
| 547 | &destroy_mark); | 547 | &destroy_mark); |
| 548 | if (destroy_mark) | 548 | if (destroy_mark) |
| 549 | fsnotify_destroy_mark(fsn_mark); | 549 | fsnotify_destroy_mark(fsn_mark, group); |
| 550 | 550 | ||
| 551 | fsnotify_put_mark(fsn_mark); | 551 | fsnotify_put_mark(fsn_mark); |
| 552 | if (removed & real_mount(mnt)->mnt_fsnotify_mask) | 552 | if (removed & real_mount(mnt)->mnt_fsnotify_mask) |
| @@ -570,7 +570,7 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group, | |||
| 570 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, | 570 | removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, |
| 571 | &destroy_mark); | 571 | &destroy_mark); |
| 572 | if (destroy_mark) | 572 | if (destroy_mark) |
| 573 | fsnotify_destroy_mark(fsn_mark); | 573 | fsnotify_destroy_mark(fsn_mark, group); |
| 574 | /* matches the fsnotify_find_inode_mark() */ | 574 | /* matches the fsnotify_find_inode_mark() */ |
| 575 | fsnotify_put_mark(fsn_mark); | 575 | fsnotify_put_mark(fsn_mark); |
| 576 | if (removed & inode->i_fsnotify_mask) | 576 | if (removed & inode->i_fsnotify_mask) |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index 4e9071e37d5d..21230209c957 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
| @@ -99,8 +99,16 @@ void fsnotify_clear_marks_by_inode(struct inode *inode) | |||
| 99 | spin_unlock(&inode->i_lock); | 99 | spin_unlock(&inode->i_lock); |
| 100 | 100 | ||
| 101 | list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) { | 101 | list_for_each_entry_safe(mark, lmark, &free_list, i.free_i_list) { |
| 102 | fsnotify_destroy_mark(mark); | 102 | struct fsnotify_group *group; |
| 103 | |||
| 104 | spin_lock(&mark->lock); | ||
| 105 | fsnotify_get_group(mark->group); | ||
| 106 | group = mark->group; | ||
| 107 | spin_unlock(&mark->lock); | ||
| 108 | |||
| 109 | fsnotify_destroy_mark(mark, group); | ||
| 103 | fsnotify_put_mark(mark); | 110 | fsnotify_put_mark(mark); |
| 111 | fsnotify_put_group(group); | ||
| 104 | } | 112 | } |
| 105 | } | 113 | } |
| 106 | 114 | ||
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 74977fbf5aae..871569c7d609 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
| @@ -132,7 +132,7 @@ static int inotify_handle_event(struct fsnotify_group *group, | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | if (inode_mark->mask & IN_ONESHOT) | 134 | if (inode_mark->mask & IN_ONESHOT) |
| 135 | fsnotify_destroy_mark(inode_mark); | 135 | fsnotify_destroy_mark(inode_mark, group); |
| 136 | 136 | ||
| 137 | return ret; | 137 | return ret; |
| 138 | } | 138 | } |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 246250f1db7a..00ff82ff7c9f 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
| @@ -816,7 +816,7 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd) | |||
| 816 | 816 | ||
| 817 | ret = 0; | 817 | ret = 0; |
| 818 | 818 | ||
| 819 | fsnotify_destroy_mark(&i_mark->fsn_mark); | 819 | fsnotify_destroy_mark(&i_mark->fsn_mark, group); |
| 820 | 820 | ||
| 821 | /* match ref taken by inotify_idr_find */ | 821 | /* match ref taken by inotify_idr_find */ |
| 822 | fsnotify_put_mark(&i_mark->fsn_mark); | 822 | fsnotify_put_mark(&i_mark->fsn_mark); |
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index ab25b810b146..b77c833c8d0a 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
| @@ -121,21 +121,11 @@ 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(struct fsnotify_mark *mark, |
| 125 | struct fsnotify_group *group) | ||
| 125 | { | 126 | { |
| 126 | struct fsnotify_group *group; | ||
| 127 | struct inode *inode = NULL; | 127 | struct inode *inode = NULL; |
| 128 | 128 | ||
| 129 | spin_lock(&mark->lock); | ||
| 130 | /* dont get the group from a mark that is not alive yet */ | ||
| 131 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { | ||
| 132 | spin_unlock(&mark->lock); | ||
| 133 | return; | ||
| 134 | } | ||
| 135 | fsnotify_get_group(mark->group); | ||
| 136 | group = mark->group; | ||
| 137 | spin_unlock(&mark->lock); | ||
| 138 | |||
| 139 | mutex_lock(&group->mark_mutex); | 129 | mutex_lock(&group->mark_mutex); |
| 140 | spin_lock(&mark->lock); | 130 | spin_lock(&mark->lock); |
| 141 | 131 | ||
| @@ -143,7 +133,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark) | |||
| 143 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { | 133 | if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE)) { |
| 144 | spin_unlock(&mark->lock); | 134 | spin_unlock(&mark->lock); |
| 145 | mutex_unlock(&group->mark_mutex); | 135 | mutex_unlock(&group->mark_mutex); |
| 146 | goto put_group; | 136 | return; |
| 147 | } | 137 | } |
| 148 | 138 | ||
| 149 | mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; | 139 | mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; |
| @@ -194,9 +184,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark) | |||
| 194 | */ | 184 | */ |
| 195 | 185 | ||
| 196 | atomic_dec(&group->num_marks); | 186 | atomic_dec(&group->num_marks); |
| 197 | |||
| 198 | put_group: | ||
| 199 | fsnotify_put_group(group); | ||
| 200 | } | 187 | } |
| 201 | 188 | ||
| 202 | void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) | 189 | void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask) |
| @@ -307,7 +294,7 @@ void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, | |||
| 307 | mutex_unlock(&group->mark_mutex); | 294 | mutex_unlock(&group->mark_mutex); |
| 308 | 295 | ||
| 309 | list_for_each_entry_safe(mark, lmark, &free_list, free_g_list) { | 296 | list_for_each_entry_safe(mark, lmark, &free_list, free_g_list) { |
| 310 | fsnotify_destroy_mark(mark); | 297 | fsnotify_destroy_mark(mark, group); |
| 311 | fsnotify_put_mark(mark); | 298 | fsnotify_put_mark(mark); |
| 312 | } | 299 | } |
| 313 | } | 300 | } |
diff --git a/fs/notify/vfsmount_mark.c b/fs/notify/vfsmount_mark.c index f26a348827f8..4df58b8ea64a 100644 --- a/fs/notify/vfsmount_mark.c +++ b/fs/notify/vfsmount_mark.c | |||
| @@ -46,8 +46,16 @@ void fsnotify_clear_marks_by_mount(struct vfsmount *mnt) | |||
| 46 | spin_unlock(&mnt->mnt_root->d_lock); | 46 | spin_unlock(&mnt->mnt_root->d_lock); |
| 47 | 47 | ||
| 48 | list_for_each_entry_safe(mark, lmark, &free_list, m.free_m_list) { | 48 | list_for_each_entry_safe(mark, lmark, &free_list, m.free_m_list) { |
| 49 | fsnotify_destroy_mark(mark); | 49 | struct fsnotify_group *group; |
| 50 | |||
| 51 | spin_lock(&mark->lock); | ||
| 52 | fsnotify_get_group(mark->group); | ||
| 53 | group = mark->group; | ||
| 54 | spin_unlock(&mark->lock); | ||
| 55 | |||
| 56 | fsnotify_destroy_mark(mark, group); | ||
| 50 | fsnotify_put_mark(mark); | 57 | fsnotify_put_mark(mark); |
| 58 | fsnotify_put_group(group); | ||
| 51 | } | 59 | } |
| 52 | } | 60 | } |
| 53 | 61 | ||
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index c5848346840d..140b4b8a100b 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -408,8 +408,9 @@ extern void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask | |||
| 408 | /* attach the mark to both the group and the inode */ | 408 | /* attach the mark to both the group and the inode */ |
| 409 | extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, | 409 | extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group, |
| 410 | struct inode *inode, struct vfsmount *mnt, int allow_dups); | 410 | struct inode *inode, struct vfsmount *mnt, int allow_dups); |
| 411 | /* given a mark, flag it to be freed when all references are dropped */ | 411 | /* given a group and a mark, flag mark to be freed when all references are dropped */ |
| 412 | extern void fsnotify_destroy_mark(struct fsnotify_mark *mark); | 412 | extern void fsnotify_destroy_mark(struct fsnotify_mark *mark, |
| 413 | struct fsnotify_group *group); | ||
| 413 | /* run all the marks in a group, and clear all of the vfsmount marks */ | 414 | /* run all the marks in a group, and clear all of the vfsmount marks */ |
| 414 | extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group); | 415 | extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group); |
| 415 | /* run all the marks in a group, and clear all of the inode marks */ | 416 | /* run all the marks in a group, and clear all of the inode marks */ |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index ed206fd88cca..e81175ef25f8 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
| @@ -249,7 +249,7 @@ static void untag_chunk(struct node *p) | |||
| 249 | list_del_rcu(&chunk->hash); | 249 | list_del_rcu(&chunk->hash); |
| 250 | spin_unlock(&hash_lock); | 250 | spin_unlock(&hash_lock); |
| 251 | spin_unlock(&entry->lock); | 251 | spin_unlock(&entry->lock); |
| 252 | fsnotify_destroy_mark(entry); | 252 | fsnotify_destroy_mark(entry, audit_tree_group); |
| 253 | goto out; | 253 | goto out; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| @@ -291,7 +291,7 @@ static void untag_chunk(struct node *p) | |||
| 291 | owner->root = new; | 291 | owner->root = new; |
| 292 | spin_unlock(&hash_lock); | 292 | spin_unlock(&hash_lock); |
| 293 | spin_unlock(&entry->lock); | 293 | spin_unlock(&entry->lock); |
| 294 | fsnotify_destroy_mark(entry); | 294 | fsnotify_destroy_mark(entry, audit_tree_group); |
| 295 | fsnotify_put_mark(&new->mark); /* drop initial reference */ | 295 | fsnotify_put_mark(&new->mark); /* drop initial reference */ |
| 296 | goto out; | 296 | goto out; |
| 297 | 297 | ||
| @@ -331,7 +331,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) | |||
| 331 | spin_unlock(&hash_lock); | 331 | spin_unlock(&hash_lock); |
| 332 | chunk->dead = 1; | 332 | chunk->dead = 1; |
| 333 | spin_unlock(&entry->lock); | 333 | spin_unlock(&entry->lock); |
| 334 | fsnotify_destroy_mark(entry); | 334 | fsnotify_destroy_mark(entry, audit_tree_group); |
| 335 | fsnotify_put_mark(entry); | 335 | fsnotify_put_mark(entry); |
| 336 | return 0; | 336 | return 0; |
| 337 | } | 337 | } |
| @@ -412,7 +412,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
| 412 | spin_unlock(&chunk_entry->lock); | 412 | spin_unlock(&chunk_entry->lock); |
| 413 | spin_unlock(&old_entry->lock); | 413 | spin_unlock(&old_entry->lock); |
| 414 | 414 | ||
| 415 | fsnotify_destroy_mark(chunk_entry); | 415 | fsnotify_destroy_mark(chunk_entry, audit_tree_group); |
| 416 | 416 | ||
| 417 | fsnotify_put_mark(chunk_entry); | 417 | fsnotify_put_mark(chunk_entry); |
| 418 | fsnotify_put_mark(old_entry); | 418 | fsnotify_put_mark(old_entry); |
| @@ -443,7 +443,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
| 443 | spin_unlock(&hash_lock); | 443 | spin_unlock(&hash_lock); |
| 444 | spin_unlock(&chunk_entry->lock); | 444 | spin_unlock(&chunk_entry->lock); |
| 445 | spin_unlock(&old_entry->lock); | 445 | spin_unlock(&old_entry->lock); |
| 446 | fsnotify_destroy_mark(old_entry); | 446 | fsnotify_destroy_mark(old_entry, audit_tree_group); |
| 447 | fsnotify_put_mark(chunk_entry); /* drop initial reference */ | 447 | fsnotify_put_mark(chunk_entry); /* drop initial reference */ |
| 448 | fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ | 448 | fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ |
| 449 | return 0; | 449 | return 0; |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 3823281401b5..a66affc1c12c 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
| @@ -349,7 +349,7 @@ static void audit_remove_parent_watches(struct audit_parent *parent) | |||
| 349 | } | 349 | } |
| 350 | mutex_unlock(&audit_filter_mutex); | 350 | mutex_unlock(&audit_filter_mutex); |
| 351 | 351 | ||
| 352 | fsnotify_destroy_mark(&parent->mark); | 352 | fsnotify_destroy_mark(&parent->mark, audit_watch_group); |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | /* Get path information necessary for adding watches. */ | 355 | /* Get path information necessary for adding watches. */ |
| @@ -456,7 +456,7 @@ void audit_remove_watch_rule(struct audit_krule *krule) | |||
| 456 | 456 | ||
| 457 | if (list_empty(&parent->watches)) { | 457 | if (list_empty(&parent->watches)) { |
| 458 | audit_get_parent(parent); | 458 | audit_get_parent(parent); |
| 459 | fsnotify_destroy_mark(&parent->mark); | 459 | fsnotify_destroy_mark(&parent->mark, audit_watch_group); |
| 460 | audit_put_parent(parent); | 460 | audit_put_parent(parent); |
| 461 | } | 461 | } |
| 462 | } | 462 | } |
