1 #include <linux/fanotify.h>
6 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/wait.h>
12 static bool should_merge(
struct fsnotify_event *old,
struct fsnotify_event *
new)
14 pr_debug(
"%s: old=%p new=%p\n", __func__, old,
new);
16 if (old->to_tell == new->to_tell &&
17 old->data_type == new->data_type &&
18 old->tgid == new->tgid) {
19 switch (old->data_type) {
20 case (FSNOTIFY_EVENT_PATH):
21 if ((old->path.mnt == new->path.mnt) &&
22 (old->path.dentry == new->path.dentry))
25 case (FSNOTIFY_EVENT_NONE):
35 static struct fsnotify_event *fanotify_merge(
struct list_head *
list,
36 struct fsnotify_event *
event)
38 struct fsnotify_event_holder *test_holder;
39 struct fsnotify_event *test_event =
NULL;
40 struct fsnotify_event *new_event;
42 pr_debug(
"%s: list=%p event=%p\n", __func__, list, event);
46 if (should_merge(test_holder->event, event)) {
47 test_event = test_holder->event;
58 if (test_event->mask == event->mask)
67 test_event->mask |=
event->mask;
81 new_event->mask = (test_event->mask |
event->mask);
88 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
89 static int fanotify_get_response_from_access(
struct fsnotify_group *
group,
90 struct fsnotify_event *event)
94 pr_debug(
"%s: group=%p event=%p\n", __func__, group, event);
96 wait_event(group->fanotify_data.access_waitq, event->response ||
103 spin_lock(&event->lock);
104 switch (event->response) {
113 spin_unlock(&event->lock);
115 pr_debug(
"%s: group=%p event=%p about to return ret=%d\n", __func__,
122 static int fanotify_handle_event(
struct fsnotify_group *group,
123 struct fsnotify_mark *inode_mark,
125 struct fsnotify_event *event)
128 struct fsnotify_event *notify_event =
NULL;
141 pr_debug(
"%s: group=%p event=%p\n", __func__, group, event);
144 if (IS_ERR(notify_event))
145 return PTR_ERR(notify_event);
147 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
151 event = notify_event;
152 ret = fanotify_get_response_from_access(group, event);
162 static bool fanotify_should_send_event(
struct fsnotify_group *group,
163 struct inode *to_tell,
164 struct fsnotify_mark *inode_mark,
165 struct fsnotify_mark *vfsmnt_mark,
168 __u32 marks_mask, marks_ignored_mask;
171 pr_debug(
"%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p "
172 "mask=%x data=%p data_type=%d\n", __func__, group, to_tell,
173 inode_mark, vfsmnt_mark, event_mask, data, data_type);
176 if (data_type != FSNOTIFY_EVENT_PATH)
184 if (inode_mark && vfsmnt_mark) {
185 marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
186 marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
187 }
else if (inode_mark) {
192 if ((event_mask & FS_EVENT_ON_CHILD) &&
193 !(inode_mark->mask & FS_EVENT_ON_CHILD))
195 marks_mask = inode_mark->mask;
196 marks_ignored_mask = inode_mark->ignored_mask;
197 }
else if (vfsmnt_mark) {
198 marks_mask = vfsmnt_mark->mask;
199 marks_ignored_mask = vfsmnt_mark->ignored_mask;
205 (marks_ignored_mask & FS_ISDIR))
208 if (event_mask & marks_mask & ~marks_ignored_mask)
214 static void fanotify_free_group_priv(
struct fsnotify_group *group)
218 user = group->fanotify_data.user;
224 .handle_event = fanotify_handle_event,
225 .should_send_event = fanotify_should_send_event,
226 .free_group_priv = fanotify_free_group_priv,
227 .free_event_priv =
NULL,
228 .freeing_mark =
NULL,