Messages in this thread Patch in this message | | | From | Eric Paris <> | Subject | [PATCH -v3 6/8] fsnotify: add group priorities | Date | Tue, 25 Nov 2008 12:21:23 -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 | 28 ++++++++++++++++++++++++---- include/linux/fsnotify_backend.h | 4 +++- 2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/fs/notify/group.c b/fs/notify/group.c index dcc0547..bb8d6c6 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -79,15 +79,17 @@ void fsnotify_put_group(struct fsnotify_group *group) return; } -struct fsnotify_group *fsnotify_find_group(unsigned int group_num, unsigned long mask, struct fsnotify_ops *ops) +struct fsnotify_group *fsnotify_find_group(unsigned int priority, unsigned int group_num, + unsigned long mask, struct fsnotify_ops *ops) { struct fsnotify_group *group_iter; struct fsnotify_group *group = NULL; mutex_lock(&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; @@ -105,6 +107,7 @@ struct fsnotify_group *fsnotify_find_group(unsigned int group_num, unsigned long atomic_set(&group->refcnt, 1); + group->priority = priority; group->group_num = group_num; group->mask = mask; @@ -114,9 +117,26 @@ struct fsnotify_group *fsnotify_find_group(unsigned int group_num, unsigned long group->ops = ops; - /* add it */ - list_add_rcu(&group->group_list, &fsnotify_groups); + /* Do we need to be the first entry? */ + if (list_empty(&fsnotify_groups)) { + list_add_rcu(&group->group_list, &fsnotify_groups); + goto out; + } + + 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); + break; + } + /* are we at the end? if so insert at end */ + if (list_is_last(&group_iter->group_list, &fsnotify_groups)) { + list_add_tail_rcu(&group->group_list, &fsnotify_groups); + break; + } + } out: mutex_unlock(&fsnotify_grp_mutex); fsnotify_recalc_global_mask(); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 6a7b95c..e0b5528 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -57,6 +57,8 @@ struct fsnotify_group { struct mutex notification_mutex;/* protect the notification_list */ struct list_head notification_list; /* list of event_holder this group needs to send to userspace */ wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */ + + unsigned int priority; /* order this group should receive msgs. low first */ }; #ifdef CONFIG_FSNOTIFY @@ -67,7 +69,7 @@ extern void fsnotify(struct file *file, struct dentry *dentry, struct inode *ino /* called from fsnotify interfaces, such as fanotify or dnotify */ extern void fsnotify_recalc_global_mask(void); extern void fsnotify_get_group(struct fsnotify_group *group); -extern struct fsnotify_group *fsnotify_find_group(unsigned int group_num, unsigned long mask, struct fsnotify_ops *ops); +extern struct fsnotify_group *fsnotify_find_group(unsigned int priority, unsigned int group_num, unsigned long mask, struct fsnotify_ops *ops); extern void fsnotify_put_group(struct fsnotify_group *group); #else
| |