diff options
author | Jan Kara <jack@suse.cz> | 2016-12-21 12:06:12 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2017-04-10 11:37:36 -0400 |
commit | 054c636e5c8054884ede889be82ce059879945e6 (patch) | |
tree | 0559d887ce9f1bd9ba0e594b0fc876d597327bc1 | |
parent | 7b1293234084ddb6469c4e9a5ef818f399b5786b (diff) |
fsnotify: Move ->free_mark callback to fsnotify_ops
Pointer to ->free_mark callback unnecessarily occupies one long in each
fsnotify_mark although they are the same for all marks from one
notification group. Move the callback pointer to fsnotify_ops.
Reviewed-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | fs/notify/dnotify/dnotify.c | 3 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 6 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify.h | 1 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 9 | ||||
-rw-r--r-- | fs/notify/inotify/inotify.h | 1 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 11 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 14 | ||||
-rw-r--r-- | fs/notify/mark.c | 13 | ||||
-rw-r--r-- | include/linux/fsnotify_backend.h | 6 | ||||
-rw-r--r-- | kernel/audit_fsnotify.c | 4 | ||||
-rw-r--r-- | kernel/audit_tree.c | 4 | ||||
-rw-r--r-- | kernel/audit_watch.c | 4 |
12 files changed, 41 insertions, 35 deletions
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index f9d500fd7b9a..2430a0415995 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
@@ -135,6 +135,7 @@ static void dnotify_free_mark(struct fsnotify_mark *fsn_mark) | |||
135 | 135 | ||
136 | static struct fsnotify_ops dnotify_fsnotify_ops = { | 136 | static struct fsnotify_ops dnotify_fsnotify_ops = { |
137 | .handle_event = dnotify_handle_event, | 137 | .handle_event = dnotify_handle_event, |
138 | .free_mark = dnotify_free_mark, | ||
138 | }; | 139 | }; |
139 | 140 | ||
140 | /* | 141 | /* |
@@ -305,7 +306,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
305 | 306 | ||
306 | /* set up the new_fsn_mark and new_dn_mark */ | 307 | /* set up the new_fsn_mark and new_dn_mark */ |
307 | new_fsn_mark = &new_dn_mark->fsn_mark; | 308 | new_fsn_mark = &new_dn_mark->fsn_mark; |
308 | fsnotify_init_mark(new_fsn_mark, dnotify_group, dnotify_free_mark); | 309 | fsnotify_init_mark(new_fsn_mark, dnotify_group); |
309 | new_fsn_mark->mask = mask; | 310 | new_fsn_mark->mask = mask; |
310 | new_dn_mark->dn = NULL; | 311 | new_dn_mark->dn = NULL; |
311 | 312 | ||
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 461c21ebebeb..2fa99aeaa095 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -262,8 +262,14 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event) | |||
262 | kmem_cache_free(fanotify_event_cachep, event); | 262 | kmem_cache_free(fanotify_event_cachep, event); |
263 | } | 263 | } |
264 | 264 | ||
265 | static void fanotify_free_mark(struct fsnotify_mark *fsn_mark) | ||
266 | { | ||
267 | kmem_cache_free(fanotify_mark_cache, fsn_mark); | ||
268 | } | ||
269 | |||
265 | const struct fsnotify_ops fanotify_fsnotify_ops = { | 270 | const struct fsnotify_ops fanotify_fsnotify_ops = { |
266 | .handle_event = fanotify_handle_event, | 271 | .handle_event = fanotify_handle_event, |
267 | .free_group_priv = fanotify_free_group_priv, | 272 | .free_group_priv = fanotify_free_group_priv, |
268 | .free_event = fanotify_free_event, | 273 | .free_event = fanotify_free_event, |
274 | .free_mark = fanotify_free_mark, | ||
269 | }; | 275 | }; |
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 4500a74f8d38..4eb6f5efa282 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/path.h> | 2 | #include <linux/path.h> |
3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
4 | 4 | ||
5 | extern struct kmem_cache *fanotify_mark_cache; | ||
5 | extern struct kmem_cache *fanotify_event_cachep; | 6 | extern struct kmem_cache *fanotify_event_cachep; |
6 | extern struct kmem_cache *fanotify_perm_event_cachep; | 7 | extern struct kmem_cache *fanotify_perm_event_cachep; |
7 | 8 | ||
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index d5775f054be7..bf306d4f72f7 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | extern const struct fsnotify_ops fanotify_fsnotify_ops; | 42 | extern const struct fsnotify_ops fanotify_fsnotify_ops; |
43 | 43 | ||
44 | static struct kmem_cache *fanotify_mark_cache __read_mostly; | 44 | struct kmem_cache *fanotify_mark_cache __read_mostly; |
45 | struct kmem_cache *fanotify_event_cachep __read_mostly; | 45 | struct kmem_cache *fanotify_event_cachep __read_mostly; |
46 | struct kmem_cache *fanotify_perm_event_cachep __read_mostly; | 46 | struct kmem_cache *fanotify_perm_event_cachep __read_mostly; |
47 | 47 | ||
@@ -445,11 +445,6 @@ static const struct file_operations fanotify_fops = { | |||
445 | .llseek = noop_llseek, | 445 | .llseek = noop_llseek, |
446 | }; | 446 | }; |
447 | 447 | ||
448 | static void fanotify_free_mark(struct fsnotify_mark *fsn_mark) | ||
449 | { | ||
450 | kmem_cache_free(fanotify_mark_cache, fsn_mark); | ||
451 | } | ||
452 | |||
453 | static int fanotify_find_path(int dfd, const char __user *filename, | 448 | static int fanotify_find_path(int dfd, const char __user *filename, |
454 | struct path *path, unsigned int flags) | 449 | struct path *path, unsigned int flags) |
455 | { | 450 | { |
@@ -628,7 +623,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group, | |||
628 | if (!mark) | 623 | if (!mark) |
629 | return ERR_PTR(-ENOMEM); | 624 | return ERR_PTR(-ENOMEM); |
630 | 625 | ||
631 | fsnotify_init_mark(mark, group, fanotify_free_mark); | 626 | fsnotify_init_mark(mark, group); |
632 | ret = fsnotify_add_mark_locked(mark, inode, mnt, 0); | 627 | ret = fsnotify_add_mark_locked(mark, inode, mnt, 0); |
633 | if (ret) { | 628 | if (ret) { |
634 | fsnotify_put_mark(mark); | 629 | fsnotify_put_mark(mark); |
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index 7a966f456269..9ff67b61da8a 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h | |||
@@ -31,6 +31,7 @@ extern int inotify_handle_event(struct fsnotify_group *group, | |||
31 | struct fsnotify_iter_info *iter_info); | 31 | struct fsnotify_iter_info *iter_info); |
32 | 32 | ||
33 | extern const struct fsnotify_ops inotify_fsnotify_ops; | 33 | extern const struct fsnotify_ops inotify_fsnotify_ops; |
34 | extern struct kmem_cache *inotify_inode_mark_cachep; | ||
34 | 35 | ||
35 | #ifdef CONFIG_INOTIFY_USER | 36 | #ifdef CONFIG_INOTIFY_USER |
36 | static inline void dec_inotify_instances(struct ucounts *ucounts) | 37 | static inline void dec_inotify_instances(struct ucounts *ucounts) |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index ccd6a4055e0c..8b73332735ba 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -176,9 +176,20 @@ static void inotify_free_event(struct fsnotify_event *fsn_event) | |||
176 | kfree(INOTIFY_E(fsn_event)); | 176 | kfree(INOTIFY_E(fsn_event)); |
177 | } | 177 | } |
178 | 178 | ||
179 | /* ding dong the mark is dead */ | ||
180 | static void inotify_free_mark(struct fsnotify_mark *fsn_mark) | ||
181 | { | ||
182 | struct inotify_inode_mark *i_mark; | ||
183 | |||
184 | i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); | ||
185 | |||
186 | kmem_cache_free(inotify_inode_mark_cachep, i_mark); | ||
187 | } | ||
188 | |||
179 | const struct fsnotify_ops inotify_fsnotify_ops = { | 189 | const struct fsnotify_ops inotify_fsnotify_ops = { |
180 | .handle_event = inotify_handle_event, | 190 | .handle_event = inotify_handle_event, |
181 | .free_group_priv = inotify_free_group_priv, | 191 | .free_group_priv = inotify_free_group_priv, |
182 | .free_event = inotify_free_event, | 192 | .free_event = inotify_free_event, |
183 | .freeing_mark = inotify_freeing_mark, | 193 | .freeing_mark = inotify_freeing_mark, |
194 | .free_mark = inotify_free_mark, | ||
184 | }; | 195 | }; |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 07febafd826e..7cc7d3fb1862 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -47,7 +47,7 @@ | |||
47 | /* configurable via /proc/sys/fs/inotify/ */ | 47 | /* configurable via /proc/sys/fs/inotify/ */ |
48 | static int inotify_max_queued_events __read_mostly; | 48 | static int inotify_max_queued_events __read_mostly; |
49 | 49 | ||
50 | static struct kmem_cache *inotify_inode_mark_cachep __read_mostly; | 50 | struct kmem_cache *inotify_inode_mark_cachep __read_mostly; |
51 | 51 | ||
52 | #ifdef CONFIG_SYSCTL | 52 | #ifdef CONFIG_SYSCTL |
53 | 53 | ||
@@ -483,16 +483,6 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, | |||
483 | dec_inotify_watches(group->inotify_data.ucounts); | 483 | dec_inotify_watches(group->inotify_data.ucounts); |
484 | } | 484 | } |
485 | 485 | ||
486 | /* ding dong the mark is dead */ | ||
487 | static void inotify_free_mark(struct fsnotify_mark *fsn_mark) | ||
488 | { | ||
489 | struct inotify_inode_mark *i_mark; | ||
490 | |||
491 | i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); | ||
492 | |||
493 | kmem_cache_free(inotify_inode_mark_cachep, i_mark); | ||
494 | } | ||
495 | |||
496 | static int inotify_update_existing_watch(struct fsnotify_group *group, | 486 | static int inotify_update_existing_watch(struct fsnotify_group *group, |
497 | struct inode *inode, | 487 | struct inode *inode, |
498 | u32 arg) | 488 | u32 arg) |
@@ -558,7 +548,7 @@ static int inotify_new_watch(struct fsnotify_group *group, | |||
558 | if (unlikely(!tmp_i_mark)) | 548 | if (unlikely(!tmp_i_mark)) |
559 | return -ENOMEM; | 549 | return -ENOMEM; |
560 | 550 | ||
561 | fsnotify_init_mark(&tmp_i_mark->fsn_mark, group, inotify_free_mark); | 551 | fsnotify_init_mark(&tmp_i_mark->fsn_mark, group); |
562 | tmp_i_mark->fsn_mark.mask = mask; | 552 | tmp_i_mark->fsn_mark.mask = mask; |
563 | tmp_i_mark->wd = -1; | 553 | tmp_i_mark->wd = -1; |
564 | 554 | ||
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 2f743e2035e4..55955ded338d 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
@@ -195,9 +195,12 @@ static struct inode *fsnotify_detach_connector_from_object( | |||
195 | 195 | ||
196 | static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark) | 196 | static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark) |
197 | { | 197 | { |
198 | if (mark->group) | 198 | struct fsnotify_group *group = mark->group; |
199 | fsnotify_put_group(mark->group); | 199 | |
200 | mark->free_mark(mark); | 200 | if (WARN_ON_ONCE(!group)) |
201 | return; | ||
202 | group->ops->free_mark(mark); | ||
203 | fsnotify_put_group(group); | ||
201 | } | 204 | } |
202 | 205 | ||
203 | void fsnotify_put_mark(struct fsnotify_mark *mark) | 206 | void fsnotify_put_mark(struct fsnotify_mark *mark) |
@@ -732,13 +735,11 @@ void fsnotify_destroy_marks(struct fsnotify_mark_connector __rcu **connp) | |||
732 | * Nothing fancy, just initialize lists and locks and counters. | 735 | * Nothing fancy, just initialize lists and locks and counters. |
733 | */ | 736 | */ |
734 | void fsnotify_init_mark(struct fsnotify_mark *mark, | 737 | void fsnotify_init_mark(struct fsnotify_mark *mark, |
735 | struct fsnotify_group *group, | 738 | struct fsnotify_group *group) |
736 | void (*free_mark)(struct fsnotify_mark *mark)) | ||
737 | { | 739 | { |
738 | memset(mark, 0, sizeof(*mark)); | 740 | memset(mark, 0, sizeof(*mark)); |
739 | spin_lock_init(&mark->lock); | 741 | spin_lock_init(&mark->lock); |
740 | atomic_set(&mark->refcnt, 1); | 742 | atomic_set(&mark->refcnt, 1); |
741 | mark->free_mark = free_mark; | ||
742 | fsnotify_get_group(group); | 743 | fsnotify_get_group(group); |
743 | mark->group = group; | 744 | mark->group = group; |
744 | } | 745 | } |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index a64518e36bd5..c6c69318752b 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -104,6 +104,8 @@ struct fsnotify_ops { | |||
104 | void (*free_group_priv)(struct fsnotify_group *group); | 104 | void (*free_group_priv)(struct fsnotify_group *group); |
105 | void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); | 105 | void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); |
106 | void (*free_event)(struct fsnotify_event *event); | 106 | void (*free_event)(struct fsnotify_event *event); |
107 | /* called on final put+free to free memory */ | ||
108 | void (*free_mark)(struct fsnotify_mark *mark); | ||
107 | }; | 109 | }; |
108 | 110 | ||
109 | /* | 111 | /* |
@@ -261,7 +263,6 @@ struct fsnotify_mark { | |||
261 | #define FSNOTIFY_MARK_FLAG_ALIVE 0x02 | 263 | #define FSNOTIFY_MARK_FLAG_ALIVE 0x02 |
262 | #define FSNOTIFY_MARK_FLAG_ATTACHED 0x04 | 264 | #define FSNOTIFY_MARK_FLAG_ATTACHED 0x04 |
263 | unsigned int flags; /* flags [mark->lock] */ | 265 | unsigned int flags; /* flags [mark->lock] */ |
264 | void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */ | ||
265 | }; | 266 | }; |
266 | 267 | ||
267 | #ifdef CONFIG_FSNOTIFY | 268 | #ifdef CONFIG_FSNOTIFY |
@@ -341,8 +342,7 @@ extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group | |||
341 | /* Calculate mask of events for a list of marks */ | 342 | /* Calculate mask of events for a list of marks */ |
342 | extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); | 343 | extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); |
343 | extern void fsnotify_init_mark(struct fsnotify_mark *mark, | 344 | extern void fsnotify_init_mark(struct fsnotify_mark *mark, |
344 | struct fsnotify_group *group, | 345 | struct fsnotify_group *group); |
345 | void (*free_mark)(struct fsnotify_mark *mark)); | ||
346 | /* Find mark belonging to given group in the list of marks */ | 346 | /* Find mark belonging to given group in the list of marks */ |
347 | extern struct fsnotify_mark *fsnotify_find_mark( | 347 | extern struct fsnotify_mark *fsnotify_find_mark( |
348 | struct fsnotify_mark_connector __rcu **connp, | 348 | struct fsnotify_mark_connector __rcu **connp, |
diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index 2522ceaca758..4aad0a467fed 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c | |||
@@ -103,8 +103,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa | |||
103 | goto out; | 103 | goto out; |
104 | } | 104 | } |
105 | 105 | ||
106 | fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_group, | 106 | fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_group); |
107 | audit_fsnotify_free_mark); | ||
108 | audit_mark->mark.mask = AUDIT_FS_EVENTS; | 107 | audit_mark->mark.mask = AUDIT_FS_EVENTS; |
109 | audit_mark->path = pathname; | 108 | audit_mark->path = pathname; |
110 | audit_update_mark(audit_mark, dentry->d_inode); | 109 | audit_update_mark(audit_mark, dentry->d_inode); |
@@ -203,6 +202,7 @@ static int audit_mark_handle_event(struct fsnotify_group *group, | |||
203 | 202 | ||
204 | static const struct fsnotify_ops audit_mark_fsnotify_ops = { | 203 | static const struct fsnotify_ops audit_mark_fsnotify_ops = { |
205 | .handle_event = audit_mark_handle_event, | 204 | .handle_event = audit_mark_handle_event, |
205 | .free_mark = audit_fsnotify_free_mark, | ||
206 | }; | 206 | }; |
207 | 207 | ||
208 | static int __init audit_fsnotify_init(void) | 208 | static int __init audit_fsnotify_init(void) |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index da7f7a3e6a42..a14cff67a148 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -154,8 +154,7 @@ static struct audit_chunk *alloc_chunk(int count) | |||
154 | INIT_LIST_HEAD(&chunk->owners[i].list); | 154 | INIT_LIST_HEAD(&chunk->owners[i].list); |
155 | chunk->owners[i].index = i; | 155 | chunk->owners[i].index = i; |
156 | } | 156 | } |
157 | fsnotify_init_mark(&chunk->mark, audit_tree_group, | 157 | fsnotify_init_mark(&chunk->mark, audit_tree_group); |
158 | audit_tree_destroy_watch); | ||
159 | chunk->mark.mask = FS_IN_IGNORED; | 158 | chunk->mark.mask = FS_IN_IGNORED; |
160 | return chunk; | 159 | return chunk; |
161 | } | 160 | } |
@@ -1013,6 +1012,7 @@ static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify | |||
1013 | static const struct fsnotify_ops audit_tree_ops = { | 1012 | static const struct fsnotify_ops audit_tree_ops = { |
1014 | .handle_event = audit_tree_handle_event, | 1013 | .handle_event = audit_tree_handle_event, |
1015 | .freeing_mark = audit_tree_freeing_mark, | 1014 | .freeing_mark = audit_tree_freeing_mark, |
1015 | .free_mark = audit_tree_destroy_watch, | ||
1016 | }; | 1016 | }; |
1017 | 1017 | ||
1018 | static int __init audit_tree_init(void) | 1018 | static int __init audit_tree_init(void) |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index e32efed86828..13d30a8dfc56 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -157,8 +157,7 @@ static struct audit_parent *audit_init_parent(struct path *path) | |||
157 | 157 | ||
158 | INIT_LIST_HEAD(&parent->watches); | 158 | INIT_LIST_HEAD(&parent->watches); |
159 | 159 | ||
160 | fsnotify_init_mark(&parent->mark, audit_watch_group, | 160 | fsnotify_init_mark(&parent->mark, audit_watch_group); |
161 | audit_watch_free_mark); | ||
162 | parent->mark.mask = AUDIT_FS_WATCH; | 161 | parent->mark.mask = AUDIT_FS_WATCH; |
163 | ret = fsnotify_add_mark(&parent->mark, inode, NULL, 0); | 162 | ret = fsnotify_add_mark(&parent->mark, inode, NULL, 0); |
164 | if (ret < 0) { | 163 | if (ret < 0) { |
@@ -508,6 +507,7 @@ static int audit_watch_handle_event(struct fsnotify_group *group, | |||
508 | 507 | ||
509 | static const struct fsnotify_ops audit_watch_fsnotify_ops = { | 508 | static const struct fsnotify_ops audit_watch_fsnotify_ops = { |
510 | .handle_event = audit_watch_handle_event, | 509 | .handle_event = audit_watch_handle_event, |
510 | .free_mark = audit_watch_free_mark, | ||
511 | }; | 511 | }; |
512 | 512 | ||
513 | static int __init audit_watch_init(void) | 513 | static int __init audit_watch_init(void) |