aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/fsnotify_backend.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/fsnotify_backend.h')
-rw-r--r--include/linux/fsnotify_backend.h118
1 files changed, 27 insertions, 91 deletions
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 4b2ee8d12f5e..7d8d5e608594 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -15,7 +15,6 @@
15#include <linux/path.h> /* struct path */ 15#include <linux/path.h> /* struct path */
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/types.h> 17#include <linux/types.h>
18
19#include <linux/atomic.h> 18#include <linux/atomic.h>
20 19
21/* 20/*
@@ -79,6 +78,7 @@ struct fsnotify_group;
79struct fsnotify_event; 78struct fsnotify_event;
80struct fsnotify_mark; 79struct fsnotify_mark;
81struct fsnotify_event_private_data; 80struct fsnotify_event_private_data;
81struct fsnotify_fname;
82 82
83/* 83/*
84 * Each group much define these ops. The fsnotify infrastructure will call 84 * Each group much define these ops. The fsnotify infrastructure will call
@@ -94,17 +94,27 @@ struct fsnotify_event_private_data;
94 * userspace messages that marks have been removed. 94 * userspace messages that marks have been removed.
95 */ 95 */
96struct fsnotify_ops { 96struct fsnotify_ops {
97 bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode,
98 struct fsnotify_mark *inode_mark,
99 struct fsnotify_mark *vfsmount_mark,
100 __u32 mask, void *data, int data_type);
101 int (*handle_event)(struct fsnotify_group *group, 97 int (*handle_event)(struct fsnotify_group *group,
98 struct inode *inode,
102 struct fsnotify_mark *inode_mark, 99 struct fsnotify_mark *inode_mark,
103 struct fsnotify_mark *vfsmount_mark, 100 struct fsnotify_mark *vfsmount_mark,
104 struct fsnotify_event *event); 101 u32 mask, void *data, int data_type,
102 const unsigned char *file_name);
105 void (*free_group_priv)(struct fsnotify_group *group); 103 void (*free_group_priv)(struct fsnotify_group *group);
106 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); 104 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
107 void (*free_event_priv)(struct fsnotify_event_private_data *priv); 105 void (*free_event)(struct fsnotify_event *event);
106};
107
108/*
109 * all of the information about the original object we want to now send to
110 * a group. If you want to carry more info from the accessing task to the
111 * listener this structure is where you need to be adding fields.
112 */
113struct fsnotify_event {
114 struct list_head list;
115 /* inode may ONLY be dereferenced during handle_event(). */
116 struct inode *inode; /* either the inode the event happened to or its parent */
117 u32 mask; /* the type of access, bitwise OR for FS_* event types */
108}; 118};
109 119
110/* 120/*
@@ -148,7 +158,11 @@ struct fsnotify_group {
148 * a group */ 158 * a group */
149 struct list_head marks_list; /* all inode marks for this group */ 159 struct list_head marks_list; /* all inode marks for this group */
150 160
151 struct fasync_struct *fsn_fa; /* async notification */ 161 struct fasync_struct *fsn_fa; /* async notification */
162
163 struct fsnotify_event overflow_event; /* Event we queue when the
164 * notification list is too
165 * full */
152 166
153 /* groups can define private fields here or use the void *private */ 167 /* groups can define private fields here or use the void *private */
154 union { 168 union {
@@ -177,76 +191,10 @@ struct fsnotify_group {
177 }; 191 };
178}; 192};
179 193
180/*
181 * A single event can be queued in multiple group->notification_lists.
182 *
183 * each group->notification_list will point to an event_holder which in turns points
184 * to the actual event that needs to be sent to userspace.
185 *
186 * Seemed cheaper to create a refcnt'd event and a small holder for every group
187 * than create a different event for every group
188 *
189 */
190struct fsnotify_event_holder {
191 struct fsnotify_event *event;
192 struct list_head event_list;
193};
194
195/*
196 * Inotify needs to tack data onto an event. This struct lets us later find the
197 * correct private data of the correct group.
198 */
199struct fsnotify_event_private_data {
200 struct fsnotify_group *group;
201 struct list_head event_list;
202};
203
204/*
205 * all of the information about the original object we want to now send to
206 * a group. If you want to carry more info from the accessing task to the
207 * listener this structure is where you need to be adding fields.
208 */
209struct fsnotify_event {
210 /*
211 * If we create an event we are also likely going to need a holder
212 * to link to a group. So embed one holder in the event. Means only
213 * one allocation for the common case where we only have one group
214 */
215 struct fsnotify_event_holder holder;
216 spinlock_t lock; /* protection for the associated event_holder and private_list */
217 /* to_tell may ONLY be dereferenced during handle_event(). */
218 struct inode *to_tell; /* either the inode the event happened to or its parent */
219 /*
220 * depending on the event type we should have either a path or inode
221 * We hold a reference on path, but NOT on inode. Since we have the ref on
222 * the path, it may be dereferenced at any point during this object's
223 * lifetime. That reference is dropped when this object's refcnt hits
224 * 0. If this event contains an inode instead of a path, the inode may
225 * ONLY be used during handle_event().
226 */
227 union {
228 struct path path;
229 struct inode *inode;
230 };
231/* when calling fsnotify tell it if the data is a path or inode */ 194/* when calling fsnotify tell it if the data is a path or inode */
232#define FSNOTIFY_EVENT_NONE 0 195#define FSNOTIFY_EVENT_NONE 0
233#define FSNOTIFY_EVENT_PATH 1 196#define FSNOTIFY_EVENT_PATH 1
234#define FSNOTIFY_EVENT_INODE 2 197#define FSNOTIFY_EVENT_INODE 2
235 int data_type; /* which of the above union we have */
236 atomic_t refcnt; /* how many groups still are using/need to send this event */
237 __u32 mask; /* the type of access, bitwise OR for FS_* event types */
238
239 u32 sync_cookie; /* used to corrolate events, namely inotify mv events */
240 const unsigned char *file_name;
241 size_t name_len;
242 struct pid *tgid;
243
244#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
245 __u32 response; /* userspace answer to question */
246#endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
247
248 struct list_head private_data_list; /* groups can store private data here */
249};
250 198
251/* 199/*
252 * Inode specific fields in an fsnotify_mark 200 * Inode specific fields in an fsnotify_mark
@@ -370,17 +318,12 @@ extern void fsnotify_put_group(struct fsnotify_group *group);
370extern void fsnotify_destroy_group(struct fsnotify_group *group); 318extern void fsnotify_destroy_group(struct fsnotify_group *group);
371/* fasync handler function */ 319/* fasync handler function */
372extern int fsnotify_fasync(int fd, struct file *file, int on); 320extern int fsnotify_fasync(int fd, struct file *file, int on);
373/* take a reference to an event */ 321/* Free event from memory */
374extern void fsnotify_get_event(struct fsnotify_event *event); 322extern void fsnotify_destroy_event(struct fsnotify_group *group,
375extern void fsnotify_put_event(struct fsnotify_event *event); 323 struct fsnotify_event *event);
376/* find private data previously attached to an event and unlink it */
377extern struct fsnotify_event_private_data *fsnotify_remove_priv_from_event(struct fsnotify_group *group,
378 struct fsnotify_event *event);
379
380/* attach the event to the group notification queue */ 324/* attach the event to the group notification queue */
381extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group, 325extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group,
382 struct fsnotify_event *event, 326 struct fsnotify_event *event,
383 struct fsnotify_event_private_data *priv,
384 struct fsnotify_event *(*merge)(struct list_head *, 327 struct fsnotify_event *(*merge)(struct list_head *,
385 struct fsnotify_event *)); 328 struct fsnotify_event *));
386/* true if the group notification queue is empty */ 329/* true if the group notification queue is empty */
@@ -430,15 +373,8 @@ extern void fsnotify_put_mark(struct fsnotify_mark *mark);
430extern void fsnotify_unmount_inodes(struct list_head *list); 373extern void fsnotify_unmount_inodes(struct list_head *list);
431 374
432/* put here because inotify does some weird stuff when destroying watches */ 375/* put here because inotify does some weird stuff when destroying watches */
433extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, 376extern void fsnotify_init_event(struct fsnotify_event *event,
434 void *data, int data_is, 377 struct inode *to_tell, u32 mask);
435 const unsigned char *name,
436 u32 cookie, gfp_t gfp);
437
438/* fanotify likes to change events after they are on lists... */
439extern struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_event);
440extern int fsnotify_replace_event(struct fsnotify_event_holder *old_holder,
441 struct fsnotify_event *new_event);
442 378
443#else 379#else
444 380