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.h200
1 files changed, 133 insertions, 67 deletions
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 4d6f47b51189..e40190d16878 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -41,6 +41,10 @@
41#define FS_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 41#define FS_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
42#define FS_IN_IGNORED 0x00008000 /* last inotify event here */ 42#define FS_IN_IGNORED 0x00008000 /* last inotify event here */
43 43
44#define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */
45#define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */
46
47#define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */
44#define FS_IN_ISDIR 0x40000000 /* event occurred against dir */ 48#define FS_IN_ISDIR 0x40000000 /* event occurred against dir */
45#define FS_IN_ONESHOT 0x80000000 /* only send event once */ 49#define FS_IN_ONESHOT 0x80000000 /* only send event once */
46 50
@@ -58,13 +62,20 @@
58 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\ 62 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\
59 FS_DELETE) 63 FS_DELETE)
60 64
61/* listeners that hard code group numbers near the top */ 65#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
62#define DNOTIFY_GROUP_NUM UINT_MAX 66
63#define INOTIFY_GROUP_NUM (DNOTIFY_GROUP_NUM-1) 67#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
68 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
69 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
70 FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
71 FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
72 FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \
73 FS_IN_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
74 FS_DN_MULTISHOT | FS_EVENT_ON_CHILD)
64 75
65struct fsnotify_group; 76struct fsnotify_group;
66struct fsnotify_event; 77struct fsnotify_event;
67struct fsnotify_mark_entry; 78struct fsnotify_mark;
68struct fsnotify_event_private_data; 79struct fsnotify_event_private_data;
69 80
70/* 81/*
@@ -80,10 +91,16 @@ struct fsnotify_event_private_data;
80 * valid group and inode to use to clean up. 91 * valid group and inode to use to clean up.
81 */ 92 */
82struct fsnotify_ops { 93struct fsnotify_ops {
83 bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode, __u32 mask); 94 bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode,
84 int (*handle_event)(struct fsnotify_group *group, struct fsnotify_event *event); 95 struct fsnotify_mark *inode_mark,
96 struct fsnotify_mark *vfsmount_mark,
97 __u32 mask, void *data, int data_type);
98 int (*handle_event)(struct fsnotify_group *group,
99 struct fsnotify_mark *inode_mark,
100 struct fsnotify_mark *vfsmount_mark,
101 struct fsnotify_event *event);
85 void (*free_group_priv)(struct fsnotify_group *group); 102 void (*free_group_priv)(struct fsnotify_group *group);
86 void (*freeing_mark)(struct fsnotify_mark_entry *entry, struct fsnotify_group *group); 103 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
87 void (*free_event_priv)(struct fsnotify_event_private_data *priv); 104 void (*free_event_priv)(struct fsnotify_event_private_data *priv);
88}; 105};
89 106
@@ -95,22 +112,6 @@ struct fsnotify_ops {
95 */ 112 */
96struct fsnotify_group { 113struct fsnotify_group {
97 /* 114 /*
98 * global list of all groups receiving events from fsnotify.
99 * anchored by fsnotify_groups and protected by either fsnotify_grp_mutex
100 * or fsnotify_grp_srcu depending on write vs read.
101 */
102 struct list_head group_list;
103
104 /*
105 * Defines all of the event types in which this group is interested.
106 * This mask is a bitwise OR of the FS_* events from above. Each time
107 * this mask changes for a group (if it changes) the correct functions
108 * must be called to update the global structures which indicate global
109 * interest in event types.
110 */
111 __u32 mask;
112
113 /*
114 * How the refcnt is used is up to each group. When the refcnt hits 0 115 * How the refcnt is used is up to each group. When the refcnt hits 0
115 * fsnotify will clean up all of the resources associated with this group. 116 * fsnotify will clean up all of the resources associated with this group.
116 * As an example, the dnotify group will always have a refcnt=1 and that 117 * As an example, the dnotify group will always have a refcnt=1 and that
@@ -119,7 +120,6 @@ struct fsnotify_group {
119 * closed. 120 * closed.
120 */ 121 */
121 atomic_t refcnt; /* things with interest in this group */ 122 atomic_t refcnt; /* things with interest in this group */
122 unsigned int group_num; /* simply prevents accidental group collision */
123 123
124 const struct fsnotify_ops *ops; /* how this group handles things */ 124 const struct fsnotify_ops *ops; /* how this group handles things */
125 125
@@ -130,15 +130,12 @@ struct fsnotify_group {
130 unsigned int q_len; /* events on the queue */ 130 unsigned int q_len; /* events on the queue */
131 unsigned int max_events; /* maximum events allowed on the list */ 131 unsigned int max_events; /* maximum events allowed on the list */
132 132
133 /* stores all fastapth entries assoc with this group so they can be cleaned on unregister */ 133 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */
134 spinlock_t mark_lock; /* protect mark_entries list */ 134 spinlock_t mark_lock; /* protect marks_list */
135 atomic_t num_marks; /* 1 for each mark entry and 1 for not being 135 atomic_t num_marks; /* 1 for each mark and 1 for not being
136 * past the point of no return when freeing 136 * past the point of no return when freeing
137 * a group */ 137 * a group */
138 struct list_head mark_entries; /* all inode mark entries for this group */ 138 struct list_head marks_list; /* all inode marks for this group */
139
140 /* prevents double list_del of group_list. protected by global fsnotify_grp_mutex */
141 bool on_group_list;
142 139
143 /* groups can define private fields here or use the void *private */ 140 /* groups can define private fields here or use the void *private */
144 union { 141 union {
@@ -152,6 +149,18 @@ struct fsnotify_group {
152 struct user_struct *user; 149 struct user_struct *user;
153 } inotify_data; 150 } inotify_data;
154#endif 151#endif
152#ifdef CONFIG_FANOTIFY
153 struct fanotify_group_private_data {
154#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
155 /* allows a group to block waiting for a userspace response */
156 struct mutex access_mutex;
157 struct list_head access_list;
158 wait_queue_head_t access_waitq;
159 bool bypass_perm; /* protected by access_mutex */
160#endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
161 int f_flags;
162 } fanotify_data;
163#endif /* CONFIG_FANOTIFY */
155 }; 164 };
156}; 165};
157 166
@@ -210,20 +219,42 @@ struct fsnotify_event {
210#define FSNOTIFY_EVENT_NONE 0 219#define FSNOTIFY_EVENT_NONE 0
211#define FSNOTIFY_EVENT_PATH 1 220#define FSNOTIFY_EVENT_PATH 1
212#define FSNOTIFY_EVENT_INODE 2 221#define FSNOTIFY_EVENT_INODE 2
213#define FSNOTIFY_EVENT_FILE 3
214 int data_type; /* which of the above union we have */ 222 int data_type; /* which of the above union we have */
215 atomic_t refcnt; /* how many groups still are using/need to send this event */ 223 atomic_t refcnt; /* how many groups still are using/need to send this event */
216 __u32 mask; /* the type of access, bitwise OR for FS_* event types */ 224 __u32 mask; /* the type of access, bitwise OR for FS_* event types */
217 225
218 u32 sync_cookie; /* used to corrolate events, namely inotify mv events */ 226 u32 sync_cookie; /* used to corrolate events, namely inotify mv events */
219 char *file_name; 227 const unsigned char *file_name;
220 size_t name_len; 228 size_t name_len;
229 struct pid *tgid;
230
231#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
232 __u32 response; /* userspace answer to question */
233#endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
221 234
222 struct list_head private_data_list; /* groups can store private data here */ 235 struct list_head private_data_list; /* groups can store private data here */
223}; 236};
224 237
225/* 238/*
226 * a mark is simply an entry attached to an in core inode which allows an 239 * Inode specific fields in an fsnotify_mark
240 */
241struct fsnotify_inode_mark {
242 struct inode *inode; /* inode this mark is associated with */
243 struct hlist_node i_list; /* list of marks by inode->i_fsnotify_marks */
244 struct list_head free_i_list; /* tmp list used when freeing this mark */
245};
246
247/*
248 * Mount point specific fields in an fsnotify_mark
249 */
250struct fsnotify_vfsmount_mark {
251 struct vfsmount *mnt; /* vfsmount this mark is associated with */
252 struct hlist_node m_list; /* list of marks by inode->i_fsnotify_marks */
253 struct list_head free_m_list; /* tmp list used when freeing this mark */
254};
255
256/*
257 * a mark is simply an object attached to an in core inode which allows an
227 * fsnotify listener to indicate they are either no longer interested in events 258 * fsnotify listener to indicate they are either no longer interested in events
228 * of a type matching mask or only interested in those events. 259 * of a type matching mask or only interested in those events.
229 * 260 *
@@ -232,19 +263,28 @@ struct fsnotify_event {
232 * (such as dnotify) will flush these when the open fd is closed and not at 263 * (such as dnotify) will flush these when the open fd is closed and not at
233 * inode eviction or modification. 264 * inode eviction or modification.
234 */ 265 */
235struct fsnotify_mark_entry { 266struct fsnotify_mark {
236 __u32 mask; /* mask this mark entry is for */ 267 __u32 mask; /* mask this mark is for */
237 /* we hold ref for each i_list and g_list. also one ref for each 'thing' 268 /* we hold ref for each i_list and g_list. also one ref for each 'thing'
238 * in kernel that found and may be using this mark. */ 269 * in kernel that found and may be using this mark. */
239 atomic_t refcnt; /* active things looking at this mark */ 270 atomic_t refcnt; /* active things looking at this mark */
240 struct inode *inode; /* inode this entry is associated with */ 271 struct fsnotify_group *group; /* group this mark is for */
241 struct fsnotify_group *group; /* group this mark entry is for */ 272 struct list_head g_list; /* list of marks by group->i_fsnotify_marks */
242 struct hlist_node i_list; /* list of mark_entries by inode->i_fsnotify_mark_entries */ 273 spinlock_t lock; /* protect group and inode */
243 struct list_head g_list; /* list of mark_entries by group->i_fsnotify_mark_entries */ 274 union {
244 spinlock_t lock; /* protect group, inode, and killme */ 275 struct fsnotify_inode_mark i;
245 struct list_head free_i_list; /* tmp list used when freeing this mark */ 276 struct fsnotify_vfsmount_mark m;
277 };
278 __u32 ignored_mask; /* events types to ignore */
246 struct list_head free_g_list; /* tmp list used when freeing this mark */ 279 struct list_head free_g_list; /* tmp list used when freeing this mark */
247 void (*free_mark)(struct fsnotify_mark_entry *entry); /* called on final put+free */ 280#define FSNOTIFY_MARK_FLAG_INODE 0x01
281#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
282#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04
283#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
284#define FSNOTIFY_MARK_FLAG_ALIVE 0x10
285 unsigned int flags; /* vfsmount or inode mark? */
286 struct list_head destroy_list;
287 void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
248}; 288};
249 289
250#ifdef CONFIG_FSNOTIFY 290#ifdef CONFIG_FSNOTIFY
@@ -252,10 +292,11 @@ struct fsnotify_mark_entry {
252/* called from the vfs helpers */ 292/* called from the vfs helpers */
253 293
254/* main fsnotify call to send events */ 294/* main fsnotify call to send events */
255extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, 295extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
256 const char *name, u32 cookie); 296 const unsigned char *name, u32 cookie);
257extern void __fsnotify_parent(struct dentry *dentry, __u32 mask); 297extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
258extern void __fsnotify_inode_delete(struct inode *inode); 298extern void __fsnotify_inode_delete(struct inode *inode);
299extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
259extern u32 fsnotify_get_cookie(void); 300extern u32 fsnotify_get_cookie(void);
260 301
261static inline int fsnotify_inode_watches_children(struct inode *inode) 302static inline int fsnotify_inode_watches_children(struct inode *inode)
@@ -304,15 +345,9 @@ static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode
304 345
305/* called from fsnotify listeners, such as fanotify or dnotify */ 346/* called from fsnotify listeners, such as fanotify or dnotify */
306 347
307/* must call when a group changes its ->mask */
308extern void fsnotify_recalc_global_mask(void);
309/* get a reference to an existing or create a new group */ 348/* get a reference to an existing or create a new group */
310extern struct fsnotify_group *fsnotify_obtain_group(unsigned int group_num, 349extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops);
311 __u32 mask, 350/* drop reference on a group from fsnotify_alloc_group */
312 const struct fsnotify_ops *ops);
313/* run all marks associated with this group and update group->mask */
314extern void fsnotify_recalc_group_mask(struct fsnotify_group *group);
315/* drop reference on a group from fsnotify_obtain_group */
316extern void fsnotify_put_group(struct fsnotify_group *group); 351extern void fsnotify_put_group(struct fsnotify_group *group);
317 352
318/* take a reference to an event */ 353/* take a reference to an event */
@@ -323,8 +358,11 @@ extern struct fsnotify_event_private_data *fsnotify_remove_priv_from_event(struc
323 struct fsnotify_event *event); 358 struct fsnotify_event *event);
324 359
325/* attach the event to the group notification queue */ 360/* attach the event to the group notification queue */
326extern int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_event *event, 361extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group,
327 struct fsnotify_event_private_data *priv); 362 struct fsnotify_event *event,
363 struct fsnotify_event_private_data *priv,
364 struct fsnotify_event *(*merge)(struct list_head *,
365 struct fsnotify_event *));
328/* true if the group notification queue is empty */ 366/* true if the group notification queue is empty */
329extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group); 367extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
330/* return, but do not dequeue the first event on the notification queue */ 368/* return, but do not dequeue the first event on the notification queue */
@@ -334,38 +372,66 @@ extern struct fsnotify_event *fsnotify_remove_notify_event(struct fsnotify_group
334 372
335/* functions used to manipulate the marks attached to inodes */ 373/* functions used to manipulate the marks attached to inodes */
336 374
375/* run all marks associated with a vfsmount and update mnt->mnt_fsnotify_mask */
376extern void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt);
337/* run all marks associated with an inode and update inode->i_fsnotify_mask */ 377/* run all marks associated with an inode and update inode->i_fsnotify_mask */
338extern void fsnotify_recalc_inode_mask(struct inode *inode); 378extern void fsnotify_recalc_inode_mask(struct inode *inode);
339extern void fsnotify_init_mark(struct fsnotify_mark_entry *entry, void (*free_mark)(struct fsnotify_mark_entry *entry)); 379extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(struct fsnotify_mark *mark));
340/* find (and take a reference) to a mark associated with group and inode */ 380/* find (and take a reference) to a mark associated with group and inode */
341extern struct fsnotify_mark_entry *fsnotify_find_mark_entry(struct fsnotify_group *group, struct inode *inode); 381extern struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, struct inode *inode);
382/* find (and take a reference) to a mark associated with group and vfsmount */
383extern struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt);
384/* copy the values from old into new */
385extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old);
386/* set the ignored_mask of a mark */
387extern void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask);
388/* set the mask of a mark (might pin the object into memory */
389extern void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask);
342/* attach the mark to both the group and the inode */ 390/* attach the mark to both the group and the inode */
343extern int fsnotify_add_mark(struct fsnotify_mark_entry *entry, struct fsnotify_group *group, struct inode *inode); 391extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
392 struct inode *inode, struct vfsmount *mnt, int allow_dups);
344/* given a mark, flag it to be freed when all references are dropped */ 393/* given a mark, flag it to be freed when all references are dropped */
345extern void fsnotify_destroy_mark_by_entry(struct fsnotify_mark_entry *entry); 394extern void fsnotify_destroy_mark(struct fsnotify_mark *mark);
395/* run all the marks in a group, and clear all of the vfsmount marks */
396extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group);
397/* run all the marks in a group, and clear all of the inode marks */
398extern void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group);
399/* run all the marks in a group, and clear all of the marks where mark->flags & flags is true*/
400extern void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, unsigned int flags);
346/* run all the marks in a group, and flag them to be freed */ 401/* run all the marks in a group, and flag them to be freed */
347extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group); 402extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);
348extern void fsnotify_get_mark(struct fsnotify_mark_entry *entry); 403extern void fsnotify_get_mark(struct fsnotify_mark *mark);
349extern void fsnotify_put_mark(struct fsnotify_mark_entry *entry); 404extern void fsnotify_put_mark(struct fsnotify_mark *mark);
350extern void fsnotify_unmount_inodes(struct list_head *list); 405extern void fsnotify_unmount_inodes(struct list_head *list);
351 406
352/* put here because inotify does some weird stuff when destroying watches */ 407/* put here because inotify does some weird stuff when destroying watches */
353extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask, 408extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask,
354 void *data, int data_is, const char *name, 409 void *data, int data_is,
410 const unsigned char *name,
355 u32 cookie, gfp_t gfp); 411 u32 cookie, gfp_t gfp);
356 412
413/* fanotify likes to change events after they are on lists... */
414extern struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_event);
415extern int fsnotify_replace_event(struct fsnotify_event_holder *old_holder,
416 struct fsnotify_event *new_event);
417
357#else 418#else
358 419
359static inline void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, 420static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
360 const char *name, u32 cookie) 421 const unsigned char *name, u32 cookie)
361{} 422{
423 return 0;
424}
362 425
363static inline void __fsnotify_parent(struct dentry *dentry, __u32 mask) 426static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
364{} 427{}
365 428
366static inline void __fsnotify_inode_delete(struct inode *inode) 429static inline void __fsnotify_inode_delete(struct inode *inode)
367{} 430{}
368 431
432static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
433{}
434
369static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) 435static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
370{} 436{}
371 437