1
2
3
4
5
6
7#ifndef __LINUX_FSNOTIFY_BACKEND_H
8#define __LINUX_FSNOTIFY_BACKEND_H
9
10#ifdef __KERNEL__
11
12#include <linux/idr.h>
13#include <linux/fs.h>
14#include <linux/list.h>
15#include <linux/path.h>
16#include <linux/spinlock.h>
17#include <linux/types.h>
18
19#include <linux/atomic.h>
20
21
22
23
24
25
26
27#define FS_ACCESS 0x00000001
28#define FS_MODIFY 0x00000002
29#define FS_ATTRIB 0x00000004
30#define FS_CLOSE_WRITE 0x00000008
31#define FS_CLOSE_NOWRITE 0x00000010
32#define FS_OPEN 0x00000020
33#define FS_MOVED_FROM 0x00000040
34#define FS_MOVED_TO 0x00000080
35#define FS_CREATE 0x00000100
36#define FS_DELETE 0x00000200
37#define FS_DELETE_SELF 0x00000400
38#define FS_MOVE_SELF 0x00000800
39
40#define FS_UNMOUNT 0x00002000
41#define FS_Q_OVERFLOW 0x00004000
42#define FS_IN_IGNORED 0x00008000
43
44#define FS_OPEN_PERM 0x00010000
45#define FS_ACCESS_PERM 0x00020000
46
47#define FS_EXCL_UNLINK 0x04000000
48#define FS_ISDIR 0x40000000
49#define FS_IN_ONESHOT 0x80000000
50
51#define FS_DN_RENAME 0x10000000
52#define FS_DN_MULTISHOT 0x20000000
53
54
55
56#define FS_EVENT_ON_CHILD 0x08000000
57
58
59
60#define FS_EVENTS_POSS_ON_CHILD (FS_ACCESS | FS_MODIFY | FS_ATTRIB |\
61 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN |\
62 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE |\
63 FS_DELETE | FS_OPEN_PERM | FS_ACCESS_PERM)
64
65#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO)
66
67#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM)
68
69#define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \
70 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \
71 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \
72 FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \
73 FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
74 FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \
75 FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \
76 FS_DN_MULTISHOT | FS_EVENT_ON_CHILD)
77
78struct fsnotify_group;
79struct fsnotify_event;
80struct fsnotify_mark;
81struct fsnotify_event_private_data;
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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,
102 struct fsnotify_mark *inode_mark,
103 struct fsnotify_mark *vfsmount_mark,
104 struct fsnotify_event *event);
105 void (*free_group_priv)(struct fsnotify_group *group);
106 void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
107 void (*free_event_priv)(struct fsnotify_event_private_data *priv);
108};
109
110
111
112
113
114
115
116struct fsnotify_group {
117
118
119
120
121
122
123
124
125 atomic_t refcnt;
126
127 const struct fsnotify_ops *ops;
128
129
130 struct mutex notification_mutex;
131 struct list_head notification_list;
132 wait_queue_head_t notification_waitq;
133 unsigned int q_len;
134 unsigned int max_events;
135
136
137
138
139 #define FS_PRIO_0 0
140 #define FS_PRIO_1 1
141 #define FS_PRIO_2 2
142 unsigned int priority;
143
144
145 struct mutex mark_mutex;
146 atomic_t num_marks;
147
148
149 struct list_head marks_list;
150
151 struct fasync_struct *fsn_fa;
152
153
154 union {
155 void *private;
156#ifdef CONFIG_INOTIFY_USER
157 struct inotify_group_private_data {
158 spinlock_t idr_lock;
159 struct idr idr;
160 struct user_struct *user;
161 } inotify_data;
162#endif
163#ifdef CONFIG_FANOTIFY
164 struct fanotify_group_private_data {
165#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
166
167 struct mutex access_mutex;
168 struct list_head access_list;
169 wait_queue_head_t access_waitq;
170 atomic_t bypass_perm;
171#endif
172 int f_flags;
173 unsigned int max_marks;
174 struct user_struct *user;
175 } fanotify_data;
176#endif
177 };
178};
179
180
181
182
183
184
185
186
187
188
189
190struct fsnotify_event_holder {
191 struct fsnotify_event *event;
192 struct list_head event_list;
193};
194
195
196
197
198
199struct fsnotify_event_private_data {
200 struct fsnotify_group *group;
201 struct list_head event_list;
202};
203
204
205
206
207
208
209struct fsnotify_event {
210
211
212
213
214
215 struct fsnotify_event_holder holder;
216 spinlock_t lock;
217
218 struct inode *to_tell;
219
220
221
222
223
224
225
226
227 union {
228 struct path path;
229 struct inode *inode;
230 };
231
232#define FSNOTIFY_EVENT_NONE 0
233#define FSNOTIFY_EVENT_PATH 1
234#define FSNOTIFY_EVENT_INODE 2
235 int data_type;
236 atomic_t refcnt;
237 __u32 mask;
238
239 u32 sync_cookie;
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;
246#endif
247
248 struct list_head private_data_list;
249};
250
251
252
253
254struct fsnotify_inode_mark {
255 struct inode *inode;
256 struct hlist_node i_list;
257 struct list_head free_i_list;
258};
259
260
261
262
263struct fsnotify_vfsmount_mark {
264 struct vfsmount *mnt;
265 struct hlist_node m_list;
266 struct list_head free_m_list;
267};
268
269
270
271
272
273
274
275
276
277
278
279struct fsnotify_mark {
280 __u32 mask;
281
282
283 atomic_t refcnt;
284 struct fsnotify_group *group;
285 struct list_head g_list;
286 spinlock_t lock;
287 union {
288 struct fsnotify_inode_mark i;
289 struct fsnotify_vfsmount_mark m;
290 };
291 __u32 ignored_mask;
292#define FSNOTIFY_MARK_FLAG_INODE 0x01
293#define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02
294#define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04
295#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
296#define FSNOTIFY_MARK_FLAG_ALIVE 0x10
297 unsigned int flags;
298 struct list_head destroy_list;
299 void (*free_mark)(struct fsnotify_mark *mark);
300};
301
302#ifdef CONFIG_FSNOTIFY
303
304
305
306
307extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
308 const unsigned char *name, u32 cookie);
309extern int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
310extern void __fsnotify_inode_delete(struct inode *inode);
311extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
312extern u32 fsnotify_get_cookie(void);
313
314static inline int fsnotify_inode_watches_children(struct inode *inode)
315{
316
317 if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD))
318 return 0;
319
320
321 return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD;
322}
323
324
325
326
327
328static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
329{
330 struct dentry *parent;
331
332 assert_spin_locked(&dentry->d_lock);
333
334
335
336
337
338
339
340
341 parent = dentry->d_parent;
342 if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))
343 dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
344 else
345 dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
346}
347
348
349
350
351static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)
352{
353 if (!inode)
354 return;
355
356 spin_lock(&dentry->d_lock);
357 __fsnotify_update_dcache_flags(dentry);
358 spin_unlock(&dentry->d_lock);
359}
360
361
362
363
364extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops);
365
366extern void fsnotify_get_group(struct fsnotify_group *group);
367
368extern void fsnotify_put_group(struct fsnotify_group *group);
369
370extern void fsnotify_destroy_group(struct fsnotify_group *group);
371
372extern int fsnotify_fasync(int fd, struct file *file, int on);
373
374extern void fsnotify_get_event(struct fsnotify_event *event);
375extern void fsnotify_put_event(struct fsnotify_event *event);
376
377extern struct fsnotify_event_private_data *fsnotify_remove_priv_from_event(struct fsnotify_group *group,
378 struct fsnotify_event *event);
379
380
381extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group,
382 struct fsnotify_event *event,
383 struct fsnotify_event_private_data *priv,
384 struct fsnotify_event *(*merge)(struct list_head *,
385 struct fsnotify_event *));
386
387extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
388
389extern struct fsnotify_event *fsnotify_peek_notify_event(struct fsnotify_group *group);
390
391extern struct fsnotify_event *fsnotify_remove_notify_event(struct fsnotify_group *group);
392
393
394
395
396extern void fsnotify_recalc_vfsmount_mask(struct vfsmount *mnt);
397
398extern void fsnotify_recalc_inode_mask(struct inode *inode);
399extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(struct fsnotify_mark *mark));
400
401extern struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, struct inode *inode);
402
403extern struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt);
404
405extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old);
406
407extern void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask);
408
409extern void fsnotify_set_mark_mask_locked(struct fsnotify_mark *mark, __u32 mask);
410
411extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
412 struct inode *inode, struct vfsmount *mnt, int allow_dups);
413extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, struct fsnotify_group *group,
414 struct inode *inode, struct vfsmount *mnt, int allow_dups);
415
416extern void fsnotify_destroy_mark(struct fsnotify_mark *mark,
417 struct fsnotify_group *group);
418extern void fsnotify_destroy_mark_locked(struct fsnotify_mark *mark,
419 struct fsnotify_group *group);
420
421extern void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group);
422
423extern void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group);
424
425extern void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, unsigned int flags);
426
427extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);
428extern void fsnotify_get_mark(struct fsnotify_mark *mark);
429extern void fsnotify_put_mark(struct fsnotify_mark *mark);
430extern void fsnotify_unmount_inodes(struct list_head *list);
431
432
433extern struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask,
434 void *data, int data_is,
435 const unsigned char *name,
436 u32 cookie, gfp_t gfp);
437
438
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
443#else
444
445static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
446 const unsigned char *name, u32 cookie)
447{
448 return 0;
449}
450
451static inline int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
452{
453 return 0;
454}
455
456static inline void __fsnotify_inode_delete(struct inode *inode)
457{}
458
459static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
460{}
461
462static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
463{}
464
465static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode)
466{}
467
468static inline u32 fsnotify_get_cookie(void)
469{
470 return 0;
471}
472
473static inline void fsnotify_unmount_inodes(struct list_head *list)
474{}
475
476#endif
477
478#endif
479
480#endif
481