Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Jan Kara 054c636e 7b129323

+41 -35
+2 -1
fs/notify/dnotify/dnotify.c
··· 135 135 136 136 static struct fsnotify_ops dnotify_fsnotify_ops = { 137 137 .handle_event = dnotify_handle_event, 138 + .free_mark = dnotify_free_mark, 138 139 }; 139 140 140 141 /* ··· 306 305 307 306 /* set up the new_fsn_mark and new_dn_mark */ 308 307 new_fsn_mark = &new_dn_mark->fsn_mark; 309 - fsnotify_init_mark(new_fsn_mark, dnotify_group, dnotify_free_mark); 308 + fsnotify_init_mark(new_fsn_mark, dnotify_group); 310 309 new_fsn_mark->mask = mask; 311 310 new_dn_mark->dn = NULL; 312 311
+6
fs/notify/fanotify/fanotify.c
··· 262 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 270 const struct fsnotify_ops fanotify_fsnotify_ops = { 266 271 .handle_event = fanotify_handle_event, 267 272 .free_group_priv = fanotify_free_group_priv, 268 273 .free_event = fanotify_free_event, 274 + .free_mark = fanotify_free_mark, 269 275 };
+1
fs/notify/fanotify/fanotify.h
··· 2 2 #include <linux/path.h> 3 3 #include <linux/slab.h> 4 4 5 + extern struct kmem_cache *fanotify_mark_cache; 5 6 extern struct kmem_cache *fanotify_event_cachep; 6 7 extern struct kmem_cache *fanotify_perm_event_cachep; 7 8
+2 -7
fs/notify/fanotify/fanotify_user.c
··· 41 41 42 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 45 struct kmem_cache *fanotify_event_cachep __read_mostly; 46 46 struct kmem_cache *fanotify_perm_event_cachep __read_mostly; 47 47 ··· 445 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 448 static int fanotify_find_path(int dfd, const char __user *filename, 454 449 struct path *path, unsigned int flags) 455 450 { ··· 623 628 if (!mark) 624 629 return ERR_PTR(-ENOMEM); 625 630 626 - fsnotify_init_mark(mark, group, fanotify_free_mark); 631 + fsnotify_init_mark(mark, group); 627 632 ret = fsnotify_add_mark_locked(mark, inode, mnt, 0); 628 633 if (ret) { 629 634 fsnotify_put_mark(mark);
+1
fs/notify/inotify/inotify.h
··· 31 31 struct fsnotify_iter_info *iter_info); 32 32 33 33 extern const struct fsnotify_ops inotify_fsnotify_ops; 34 + extern struct kmem_cache *inotify_inode_mark_cachep; 34 35 35 36 #ifdef CONFIG_INOTIFY_USER 36 37 static inline void dec_inotify_instances(struct ucounts *ucounts)
+11
fs/notify/inotify/inotify_fsnotify.c
··· 176 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 189 const struct fsnotify_ops inotify_fsnotify_ops = { 180 190 .handle_event = inotify_handle_event, 181 191 .free_group_priv = inotify_free_group_priv, 182 192 .free_event = inotify_free_event, 183 193 .freeing_mark = inotify_freeing_mark, 194 + .free_mark = inotify_free_mark, 184 195 };
+2 -12
fs/notify/inotify/inotify_user.c
··· 47 47 /* configurable via /proc/sys/fs/inotify/ */ 48 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 52 #ifdef CONFIG_SYSCTL 53 53 ··· 483 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 486 static int inotify_update_existing_watch(struct fsnotify_group *group, 497 487 struct inode *inode, 498 488 u32 arg) ··· 548 558 if (unlikely(!tmp_i_mark)) 549 559 return -ENOMEM; 550 560 551 - fsnotify_init_mark(&tmp_i_mark->fsn_mark, group, inotify_free_mark); 561 + fsnotify_init_mark(&tmp_i_mark->fsn_mark, group); 552 562 tmp_i_mark->fsn_mark.mask = mask; 553 563 tmp_i_mark->wd = -1; 554 564
+7 -6
fs/notify/mark.c
··· 195 195 196 196 static void fsnotify_final_mark_destroy(struct fsnotify_mark *mark) 197 197 { 198 - if (mark->group) 199 - fsnotify_put_group(mark->group); 200 - mark->free_mark(mark); 198 + struct fsnotify_group *group = mark->group; 199 + 200 + if (WARN_ON_ONCE(!group)) 201 + return; 202 + group->ops->free_mark(mark); 203 + fsnotify_put_group(group); 201 204 } 202 205 203 206 void fsnotify_put_mark(struct fsnotify_mark *mark) ··· 735 732 * Nothing fancy, just initialize lists and locks and counters. 736 733 */ 737 734 void fsnotify_init_mark(struct fsnotify_mark *mark, 738 - struct fsnotify_group *group, 739 - void (*free_mark)(struct fsnotify_mark *mark)) 735 + struct fsnotify_group *group) 740 736 { 741 737 memset(mark, 0, sizeof(*mark)); 742 738 spin_lock_init(&mark->lock); 743 739 atomic_set(&mark->refcnt, 1); 744 - mark->free_mark = free_mark; 745 740 fsnotify_get_group(group); 746 741 mark->group = group; 747 742 }
+3 -3
include/linux/fsnotify_backend.h
··· 104 104 void (*free_group_priv)(struct fsnotify_group *group); 105 105 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); 106 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 /* ··· 263 261 #define FSNOTIFY_MARK_FLAG_ALIVE 0x02 264 262 #define FSNOTIFY_MARK_FLAG_ATTACHED 0x04 265 263 unsigned int flags; /* flags [mark->lock] */ 266 - void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */ 267 264 }; 268 265 269 266 #ifdef CONFIG_FSNOTIFY ··· 342 341 /* Calculate mask of events for a list of marks */ 343 342 extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); 344 343 extern void fsnotify_init_mark(struct fsnotify_mark *mark, 345 - struct fsnotify_group *group, 346 - void (*free_mark)(struct fsnotify_mark *mark)); 344 + struct fsnotify_group *group); 347 345 /* Find mark belonging to given group in the list of marks */ 348 346 extern struct fsnotify_mark *fsnotify_find_mark( 349 347 struct fsnotify_mark_connector __rcu **connp,
+2 -2
kernel/audit_fsnotify.c
··· 103 103 goto out; 104 104 } 105 105 106 - fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_group, 107 - audit_fsnotify_free_mark); 106 + fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_group); 108 107 audit_mark->mark.mask = AUDIT_FS_EVENTS; 109 108 audit_mark->path = pathname; 110 109 audit_update_mark(audit_mark, dentry->d_inode); ··· 202 203 203 204 static const struct fsnotify_ops audit_mark_fsnotify_ops = { 204 205 .handle_event = audit_mark_handle_event, 206 + .free_mark = audit_fsnotify_free_mark, 205 207 }; 206 208 207 209 static int __init audit_fsnotify_init(void)
+2 -2
kernel/audit_tree.c
··· 154 154 INIT_LIST_HEAD(&chunk->owners[i].list); 155 155 chunk->owners[i].index = i; 156 156 } 157 - fsnotify_init_mark(&chunk->mark, audit_tree_group, 158 - audit_tree_destroy_watch); 157 + fsnotify_init_mark(&chunk->mark, audit_tree_group); 159 158 chunk->mark.mask = FS_IN_IGNORED; 160 159 return chunk; 161 160 } ··· 1012 1013 static const struct fsnotify_ops audit_tree_ops = { 1013 1014 .handle_event = audit_tree_handle_event, 1014 1015 .freeing_mark = audit_tree_freeing_mark, 1016 + .free_mark = audit_tree_destroy_watch, 1015 1017 }; 1016 1018 1017 1019 static int __init audit_tree_init(void)
+2 -2
kernel/audit_watch.c
··· 157 157 158 158 INIT_LIST_HEAD(&parent->watches); 159 159 160 - fsnotify_init_mark(&parent->mark, audit_watch_group, 161 - audit_watch_free_mark); 160 + fsnotify_init_mark(&parent->mark, audit_watch_group); 162 161 parent->mark.mask = AUDIT_FS_WATCH; 163 162 ret = fsnotify_add_mark(&parent->mark, inode, NULL, 0); 164 163 if (ret < 0) { ··· 507 508 508 509 static const struct fsnotify_ops audit_watch_fsnotify_ops = { 509 510 .handle_event = audit_watch_handle_event, 511 + .free_mark = audit_watch_free_mark, 510 512 }; 511 513 512 514 static int __init audit_watch_init(void)