fsnotify: remove destroy_list from fsnotify_mark
authorJan Kara <jack@suse.cz>
Sat, 13 Dec 2014 00:58:39 +0000 (16:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 13 Dec 2014 20:42:53 +0000 (12:42 -0800)
destroy_list is used to track marks which still need waiting for srcu
period end before they can be freed.  However by the time mark is added to
destroy_list it isn't in group's list of marks anymore and thus we can
reuse fsnotify_mark->g_list for queueing into destroy_list.  This saves
two pointers for each fsnotify_mark.

Signed-off-by: Jan Kara <jack@suse.cz>
Cc: Eric Paris <eparis@redhat.com>
Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/notify/mark.c
include/linux/fsnotify_backend.h

index 3942d5c..92e48c7 100644 (file)
@@ -161,7 +161,7 @@ void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
        mutex_unlock(&group->mark_mutex);
 
        spin_lock(&destroy_lock);
-       list_add(&mark->destroy_list, &destroy_list);
+       list_add(&mark->g_list, &destroy_list);
        spin_unlock(&destroy_lock);
        wake_up(&destroy_waitq);
        /*
@@ -370,7 +370,7 @@ err:
        spin_unlock(&mark->lock);
 
        spin_lock(&destroy_lock);
-       list_add(&mark->destroy_list, &destroy_list);
+       list_add(&mark->g_list, &destroy_list);
        spin_unlock(&destroy_lock);
        wake_up(&destroy_waitq);
 
@@ -469,8 +469,8 @@ static int fsnotify_mark_destroy(void *ignored)
 
                synchronize_srcu(&fsnotify_mark_srcu);
 
-               list_for_each_entry_safe(mark, next, &private_destroy_list, destroy_list) {
-                       list_del_init(&mark->destroy_list);
+               list_for_each_entry_safe(mark, next, &private_destroy_list, g_list) {
+                       list_del_init(&mark->g_list);
                        fsnotify_put_mark(mark);
                }
 
index 442847a..0f313f9 100644 (file)
@@ -212,7 +212,11 @@ struct fsnotify_mark {
         * in kernel that found and may be using this mark. */
        atomic_t refcnt;                /* active things looking at this mark */
        struct fsnotify_group *group;   /* group this mark is for */
-       struct list_head g_list;        /* list of marks by group->i_fsnotify_marks */
+       struct list_head g_list;        /* list of marks by group->i_fsnotify_marks
+                                        * Also reused for queueing mark into
+                                        * destroy_list when it's waiting for
+                                        * the end of SRCU period before it can
+                                        * be freed */
        spinlock_t lock;                /* protect group and inode */
        struct hlist_node obj_list;     /* list of marks for inode / vfsmount */
        struct list_head free_list;     /* tmp list used when freeing this mark */
@@ -227,7 +231,6 @@ struct fsnotify_mark {
 #define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
 #define FSNOTIFY_MARK_FLAG_ALIVE               0x10
        unsigned int flags;             /* vfsmount or inode mark? */
-       struct list_head destroy_list;
        void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
 };