Messages in this thread Patch in this message | | | From | Eric Paris <> | Subject | [RFC PATCH -v4 06/14] fsnotify: add group priorities | Date | Fri, 12 Dec 2008 16:51:46 -0500 |
| |
In preperation for blocking fsnotify calls group priorities must be added. When multiple groups request the same event type the lowest priority group will receive the notification first.
Signed-off-by: Eric Paris <eparis@redhat.com> ---
fs/notify/group.c | 30 ++++++++++++++++++++++++------ include/linux/fsnotify_backend.h | 4 +++- 2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/fs/notify/group.c b/fs/notify/group.c index 40935c3..0dd6e82 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -49,7 +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; + + list_for_each_entry(group_iter, &fsnotify_groups, group_list) { + BUG_ON(list_empty(&fsnotify_groups)); + /* 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); } void fsnotify_get_group(struct fsnotify_group *group) @@ -91,14 +105,16 @@ void fsnotify_put_group(struct fsnotify_group *group) } } -static struct fsnotify_group *fsnotify_find_group(unsigned int group_num, __u64 mask, const struct fsnotify_ops *ops) +static struct fsnotify_group *fsnotify_find_group(unsigned int priority, unsigned int group_num, + __u64 mask, const struct fsnotify_ops *ops) { struct fsnotify_group *group_iter; struct fsnotify_group *group = NULL; 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; @@ -109,13 +125,14 @@ static struct fsnotify_group *fsnotify_find_group(unsigned int group_num, __u64 return group; } -struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, __u64 mask, const struct fsnotify_ops *ops) +struct fsnotify_group *fsnotify_obtain_group(unsigned int priority, unsigned int group_num, + __u64 mask, const struct fsnotify_ops *ops) { struct fsnotify_group *group, *tgroup; int idx; idx = srcu_read_lock(&fsnotify_grp_srcu_struct); - group = fsnotify_find_group(group_num, mask, ops); + group = fsnotify_find_group(priority, group_num, mask, ops); srcu_read_unlock(&fsnotify_grp_srcu_struct, idx); if (group) return group; @@ -126,6 +143,7 @@ struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, __u64 mask, atomic_set(&group->refcnt, 1); + group->priority = priority; group->group_num = group_num; group->mask = mask; @@ -133,7 +151,7 @@ struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, __u64 mask, group->private = NULL; mutex_lock(&fsnotify_grp_mutex); - tgroup = fsnotify_find_group(group_num, mask, ops); + tgroup = fsnotify_find_group(priority, group_num, mask, ops); /* we raced and something else inserted the same group */ if (tgroup) { mutex_unlock(&fsnotify_grp_mutex); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 5264db1..924902e 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -85,6 +85,8 @@ struct fsnotify_group { const struct fsnotify_ops *ops; /* how this group handles things */ + unsigned int priority; /* order this group should receive msgs. low first */ + void *private; /* private data for implementers (dnotify, inotify, fanotify) */ }; @@ -95,7 +97,7 @@ extern void fsnotify(struct inode *to_tell, __u64 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, __u64 mask, const struct fsnotify_ops *ops); +extern struct fsnotify_group *fsnotify_obtain_group(unsigned int priority, unsigned int group_num, __u64 mask, const struct fsnotify_ops *ops); extern void fsnotify_put_group(struct fsnotify_group *group); extern void fsnotify_get_group(struct fsnotify_group *group);
| |