fsnotify: add groups to fsnotify_inode_groups when registering inode watch
authorEric Paris <eparis@redhat.com>
Fri, 18 Dec 2009 02:24:23 +0000 (21:24 -0500)
committerEric Paris <eparis@redhat.com>
Wed, 28 Jul 2010 13:58:51 +0000 (09:58 -0400)
Currently all fsnotify groups are added immediately to the
fsnotify_inode_groups list upon creation.  This means, even groups with no
watches (common for audit) will be on the global tracking list and will
get checked for every event.  This patch adds groups to the global list on
when the first inode mark is added to the group.

Signed-of-by: Eric Paris <eparis@redhat.com>
fs/notify/fsnotify.h
fs/notify/group.c
fs/notify/inode_mark.c

index ec5aee43bdc5856caef154be76e5abded9e6c8dd..5bd22412017f1ccdff02f6da8b023bac26f38ce5 100644 (file)
@@ -16,6 +16,8 @@ extern __u32 fsnotify_inode_mask;
 /* destroy all events sitting in this groups notification queue */
 extern void fsnotify_flush_notify(struct fsnotify_group *group);
 
+/* add a group to the inode group list */
+extern void fsnotify_add_inode_group(struct fsnotify_group *group);
 /* final kfree of a group */
 extern void fsnotify_final_destroy_group(struct fsnotify_group *group);
 
index 656c534ffb666975b6b0bc40b885c8a67251a919..34fccbd2809cec35f3c6a7a062c4e38ddb3f4385 100644 (file)
@@ -77,12 +77,15 @@ void fsnotify_recalc_group_mask(struct fsnotify_group *group)
                fsnotify_recalc_global_mask();
 }
 
-static void fsnotify_add_group(struct fsnotify_group *group)
+void fsnotify_add_inode_group(struct fsnotify_group *group)
 {
-       BUG_ON(!mutex_is_locked(&fsnotify_grp_mutex));
+       mutex_lock(&fsnotify_grp_mutex);
 
+       if (!group->on_inode_group_list)
+               list_add_tail_rcu(&group->inode_group_list, &fsnotify_inode_groups);
        group->on_inode_group_list = 1;
-       list_add_tail_rcu(&group->inode_group_list, &fsnotify_inode_groups);
+
+       mutex_unlock(&fsnotify_grp_mutex);
 }
 
 /*
@@ -188,22 +191,17 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
         */
        atomic_set(&group->num_marks, 1);
 
-
        mutex_init(&group->notification_mutex);
        INIT_LIST_HEAD(&group->notification_list);
        init_waitqueue_head(&group->notification_waitq);
        group->max_events = UINT_MAX;
 
+       INIT_LIST_HEAD(&group->inode_group_list);
+
        spin_lock_init(&group->mark_lock);
        INIT_LIST_HEAD(&group->mark_entries);
 
        group->ops = ops;
 
-       mutex_lock(&fsnotify_grp_mutex);
-
-       fsnotify_add_group(group);
-
-       mutex_unlock(&fsnotify_grp_mutex);
-
        return group;
 }
index 7d2962e5328ee5c0575ae02fd43e250ccdb85daa..a3230c485531865d7a7b1340ea931015af96403a 100644 (file)
@@ -322,6 +322,13 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry,
        if (unlikely(!inode))
                return -EINVAL;
 
+       /*
+        * if this group isn't being testing for inode type events we need
+        * to start testing
+        */
+       if (unlikely(list_empty(&group->inode_group_list)))
+               fsnotify_add_inode_group(group);
+
        /*
         * LOCKING ORDER!!!!
         * entry->lock