Messages in this thread Patch in this message | | | From | Eric Paris <> | Subject | [PATCH -V2 03/13] fsnotify: add group priorities | Date | Fri, 27 Mar 2009 16:05:20 -0400 |
| |
This introduces an ordering to fnotify groups. It's most interesting because an HSM would need to run before a typical access notifier. And an access control system would need to run between the two.
Signed-off-by: Eric Paris <eparis@redhat.com> ---
fs/notify/group.c | 29 ++++++++++++++++++++++------- include/linux/fsnotify_backend.h | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/fs/notify/group.c b/fs/notify/group.c index 88d040b..dd1d18d 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -49,8 +49,21 @@ void fsnotify_recalc_global_mask(void) static void fsnotify_add_group(struct fsnotify_group *group) { - list_add_rcu(&group->group_list, &fsnotify_groups); + int priority = group->priority; + struct fsnotify_group *group_iter; + group->evicted = 0; + list_for_each_entry(group_iter, &fsnotify_groups, group_list) { + /* insert in front of this one? */ + if (priority < group_iter->priority) { + /* I used list_add_tail() to insert in front of group_iter... */ + list_add_tail_rcu(&group->group_list, &group_iter->group_list); + return; + } + } + + /* apparently we need to be the last entry */ + list_add_tail_rcu(&group->group_list, &fsnotify_groups); } static void fsnotify_get_group(struct fsnotify_group *group) @@ -101,8 +114,8 @@ void fsnotify_put_group(struct fsnotify_group *group) fsnotify_destroy_group(group); } -static struct fsnotify_group *fsnotify_find_group(unsigned int group_num, __u32 mask, - const struct fsnotify_ops *ops) +static struct fsnotify_group *fsnotify_find_group(unsigned int priority, unsigned int group_num, + __u32 mask, const struct fsnotify_ops *ops) { struct fsnotify_group *group_iter; struct fsnotify_group *group = NULL; @@ -110,8 +123,9 @@ static struct fsnotify_group *fsnotify_find_group(unsigned int group_num, __u32 BUG_ON(!mutex_is_locked(&fsnotify_grp_mutex)); list_for_each_entry_rcu(group_iter, &fsnotify_groups, group_list) { - if (group_iter->group_num == group_num) { + if (group_iter->priority == priority) { if ((group_iter->mask == mask) && + (group_iter->group_num == group_num) && (group_iter->ops == ops)) { fsnotify_get_group(group_iter); group = group_iter; @@ -131,8 +145,8 @@ static struct fsnotify_group *fsnotify_find_group(unsigned int group_num, __u32 * the allocation and the initialization, but this is only called when notification * systems make changes, so why make it more complex? */ -struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, __u32 mask, - const struct fsnotify_ops *ops) +struct fsnotify_group *fsnotify_obtain_group(unsigned int priority, unsigned int group_num, + __u32 mask, const struct fsnotify_ops *ops) { struct fsnotify_group *group, *tgroup; @@ -142,13 +156,14 @@ struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, __u32 mask, atomic_set(&group->refcnt, 1); + group->priority = priority; group->group_num = group_num; group->mask = mask; group->ops = ops; mutex_lock(&fsnotify_grp_mutex); - tgroup = fsnotify_find_group(group_num, mask, ops); + tgroup = fsnotify_find_group(priority, group_num, mask, ops); if (tgroup) { /* group already exists */ mutex_unlock(&fsnotify_grp_mutex); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 0523333..a349691 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -76,6 +76,7 @@ struct fsnotify_group { const struct fsnotify_ops *ops; /* how this group handles things */ + unsigned int priority; /* order this group should receive msgs. low first */ unsigned int evicted:1; /* has this group been evicted? */ /* groups can define private fields here */ @@ -115,7 +116,8 @@ extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is) /* called from fsnotify interfaces, such as fanotify or dnotify */ extern void fsnotify_recalc_global_mask(void); -extern struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, __u32 mask, const struct fsnotify_ops *ops); +extern struct fsnotify_group *fsnotify_obtain_group(unsigned int priority, unsigned int group_num, + __u32 mask, const struct fsnotify_ops *ops); extern void fsnotify_put_group(struct fsnotify_group *group); extern void fsnotify_get_event(struct fsnotify_event *event);
| |