aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2009-05-21 17:01:37 -0400
committerEric Paris <eparis@redhat.com>2009-06-11 14:57:53 -0400
commita2d8bc6cb4a3024661baf877242f123787d0c054 (patch)
tree4ff3f93877a8992d5383c14fb6012ab9b1954660 /include
parent3c5119c05d624f95f4967d16b38c9624b816bdb9 (diff)
fsnotify: generic notification queue and waitq
inotify needs to do asyc notification in which event information is stored on a queue until the listener is ready to receive it. This patch implements a generic notification queue for inotify (and later fanotify) to store events to be sent at a later time. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'include')
-rw-r--r--include/linux/fsnotify_backend.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 9ea800e840f1..15f8f82a5c57 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -119,6 +119,13 @@ struct fsnotify_group {
119 119
120 const struct fsnotify_ops *ops; /* how this group handles things */ 120 const struct fsnotify_ops *ops; /* how this group handles things */
121 121
122 /* needed to send notification to userspace */
123 struct mutex notification_mutex; /* protect the notification_list */
124 struct list_head notification_list; /* list of event_holder this group needs to send to userspace */
125 wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */
126 unsigned int q_len; /* events on the queue */
127 unsigned int max_events; /* maximum events allowed on the list */
128
122 /* stores all fastapth entries assoc with this group so they can be cleaned on unregister */ 129 /* stores all fastapth entries assoc with this group so they can be cleaned on unregister */
123 spinlock_t mark_lock; /* protect mark_entries list */ 130 spinlock_t mark_lock; /* protect mark_entries list */
124 atomic_t num_marks; /* 1 for each mark entry and 1 for not being 131 atomic_t num_marks; /* 1 for each mark entry and 1 for not being
@@ -136,11 +143,32 @@ struct fsnotify_group {
136}; 143};
137 144
138/* 145/*
146 * A single event can be queued in multiple group->notification_lists.
147 *
148 * each group->notification_list will point to an event_holder which in turns points
149 * to the actual event that needs to be sent to userspace.
150 *
151 * Seemed cheaper to create a refcnt'd event and a small holder for every group
152 * than create a different event for every group
153 *
154 */
155struct fsnotify_event_holder {
156 struct fsnotify_event *event;
157 struct list_head event_list;
158};
159
160/*
139 * all of the information about the original object we want to now send to 161 * all of the information about the original object we want to now send to
140 * a group. If you want to carry more info from the accessing task to the 162 * a group. If you want to carry more info from the accessing task to the
141 * listener this structure is where you need to be adding fields. 163 * listener this structure is where you need to be adding fields.
142 */ 164 */
143struct fsnotify_event { 165struct fsnotify_event {
166 /*
167 * If we create an event we are also likely going to need a holder
168 * to link to a group. So embed one holder in the event. Means only
169 * one allocation for the common case where we only have one group
170 */
171 struct fsnotify_event_holder holder;
144 spinlock_t lock; /* protection for the associated event_holder and private_list */ 172 spinlock_t lock; /* protection for the associated event_holder and private_list */
145 /* to_tell may ONLY be dereferenced during handle_event(). */ 173 /* to_tell may ONLY be dereferenced during handle_event(). */
146 struct inode *to_tell; /* either the inode the event happened to or its parent */ 174 struct inode *to_tell; /* either the inode the event happened to or its parent */
@@ -264,6 +292,15 @@ extern void fsnotify_put_event(struct fsnotify_event *event);
264extern struct fsnotify_event_private_data *fsnotify_get_priv_from_event(struct fsnotify_group *group, 292extern struct fsnotify_event_private_data *fsnotify_get_priv_from_event(struct fsnotify_group *group,
265 struct fsnotify_event *event); 293 struct fsnotify_event *event);
266 294
295/* attach the event to the group notification queue */
296extern int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_event *event);
297/* true if the group notification queue is empty */
298extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
299/* return, but do not dequeue the first event on the notification queue */
300extern struct fsnotify_event *fsnotify_peek_notify_event(struct fsnotify_group *group);
301/* reutnr AND dequeue the first event on the notification queue */
302extern struct fsnotify_event *fsnotify_remove_notify_event(struct fsnotify_group *group);
303
267/* functions used to manipulate the marks attached to inodes */ 304/* functions used to manipulate the marks attached to inodes */
268 305
269/* run all marks associated with an inode and update inode->i_fsnotify_mask */ 306/* run all marks associated with an inode and update inode->i_fsnotify_mask */