summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-12-18 02:24:23 (GMT)
committerEric Paris <eparis@redhat.com>2010-07-28 13:58:51 (GMT)
commit4ca763523e040dc61191d4866a82981a5d30a4e9 (patch)
tree9b02105e7c84853dd89eff16837a9b7fba2a1050
parent36fddebaa8a9186d4f5817ab798a83400b2fb2e7 (diff)
downloadlinux-4ca763523e040dc61191d4866a82981a5d30a4e9.tar.xz
fsnotify: add groups to fsnotify_inode_groups when registering inode watch
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>
-rw-r--r--fs/notify/fsnotify.h2
-rw-r--r--fs/notify/group.c18
-rw-r--r--fs/notify/inode_mark.c7
3 files changed, 17 insertions, 10 deletions
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index ec5aee4..5bd2241 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -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);
diff --git a/fs/notify/group.c b/fs/notify/group.c
index 656c534..34fccbd 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -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;
}
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 7d2962e..a3230c4 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -323,6 +323,13 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry,
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
* group->mark_lock