1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #include <linux/fsnotify_backend.h> |
3 | #include <linux/inotify.h> |
4 | #include <linux/slab.h> /* struct kmem_cache */ |
5 | |
6 | struct inotify_event_info { |
7 | struct fsnotify_event fse; |
8 | u32 mask; |
9 | int wd; |
10 | u32 sync_cookie; |
11 | int name_len; |
12 | char name[]; |
13 | }; |
14 | |
15 | struct inotify_inode_mark { |
16 | struct fsnotify_mark fsn_mark; |
17 | int wd; |
18 | }; |
19 | |
20 | static inline struct inotify_event_info *INOTIFY_E(struct fsnotify_event *fse) |
21 | { |
22 | return container_of(fse, struct inotify_event_info, fse); |
23 | } |
24 | |
25 | /* |
26 | * INOTIFY_USER_FLAGS represents all of the mask bits that we expose to |
27 | * userspace. There is at least one bit (FS_EVENT_ON_CHILD) which is |
28 | * used only internally to the kernel. |
29 | */ |
30 | #define INOTIFY_USER_MASK (IN_ALL_EVENTS) |
31 | |
32 | static inline __u32 inotify_mark_user_mask(struct fsnotify_mark *fsn_mark) |
33 | { |
34 | __u32 mask = fsn_mark->mask & INOTIFY_USER_MASK; |
35 | |
36 | if (fsn_mark->flags & FSNOTIFY_MARK_FLAG_EXCL_UNLINK) |
37 | mask |= IN_EXCL_UNLINK; |
38 | if (fsn_mark->flags & FSNOTIFY_MARK_FLAG_IN_ONESHOT) |
39 | mask |= IN_ONESHOT; |
40 | |
41 | return mask; |
42 | } |
43 | |
44 | extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, |
45 | struct fsnotify_group *group); |
46 | extern int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, |
47 | u32 mask, struct inode *inode, |
48 | struct inode *dir, |
49 | const struct qstr *name, u32 cookie); |
50 | |
51 | extern const struct fsnotify_ops inotify_fsnotify_ops; |
52 | extern struct kmem_cache *inotify_inode_mark_cachep; |
53 | |
54 | #ifdef CONFIG_INOTIFY_USER |
55 | static inline void dec_inotify_instances(struct ucounts *ucounts) |
56 | { |
57 | dec_ucount(ucounts, type: UCOUNT_INOTIFY_INSTANCES); |
58 | } |
59 | |
60 | static inline struct ucounts *inc_inotify_watches(struct ucounts *ucounts) |
61 | { |
62 | return inc_ucount(ns: ucounts->ns, uid: ucounts->uid, type: UCOUNT_INOTIFY_WATCHES); |
63 | } |
64 | |
65 | static inline void dec_inotify_watches(struct ucounts *ucounts) |
66 | { |
67 | dec_ucount(ucounts, type: UCOUNT_INOTIFY_WATCHES); |
68 | } |
69 | #endif |
70 | |