28 #include <linux/inotify.h>
30 #include <linux/slab.h>
31 #include <linux/types.h>
32 #include <linux/sched.h>
40 static bool event_compare(
struct fsnotify_event *old,
struct fsnotify_event *
new)
42 if ((old->mask == new->mask) &&
43 (old->to_tell == new->to_tell) &&
44 (old->data_type == new->data_type) &&
45 (old->name_len == new->name_len)) {
46 switch (old->data_type) {
47 case (FSNOTIFY_EVENT_INODE):
52 !
strcmp(old->file_name, new->file_name))
55 case (FSNOTIFY_EVENT_PATH):
56 if ((old->path.mnt == new->path.mnt) &&
57 (old->path.dentry == new->path.dentry))
60 case (FSNOTIFY_EVENT_NONE):
61 if (old->mask & FS_Q_OVERFLOW)
63 else if (old->mask & FS_IN_IGNORED)
71 static struct fsnotify_event *inotify_merge(
struct list_head *
list,
72 struct fsnotify_event *
event)
74 struct fsnotify_event_holder *last_holder;
75 struct fsnotify_event *last_event;
78 spin_lock(&event->lock);
81 last_event = last_holder->event;
82 if (event_compare(last_event, event))
87 spin_unlock(&event->lock);
92 static int inotify_handle_event(
struct fsnotify_group *
group,
93 struct fsnotify_mark *inode_mark,
94 struct fsnotify_mark *vfsmount_mark,
95 struct fsnotify_event *event)
98 struct inode *to_tell;
100 struct fsnotify_event_private_data *fsn_event_priv;
101 struct fsnotify_event *added_event;
106 pr_debug(
"%s: group=%p event=%p to_tell=%p mask=%x\n", __func__, group,
107 event, event->to_tell, event->mask);
109 to_tell =
event->to_tell;
121 fsn_event_priv->group =
group;
127 if (!IS_ERR(added_event))
130 ret = PTR_ERR(added_event);
139 static void inotify_freeing_mark(
struct fsnotify_mark *fsn_mark,
struct fsnotify_group *group)
144 static bool inotify_should_send_event(
struct fsnotify_group *group,
struct inode *
inode,
145 struct fsnotify_mark *inode_mark,
146 struct fsnotify_mark *vfsmount_mark,
149 if ((inode_mark->mask & FS_EXCL_UNLINK) &&
150 (data_type == FSNOTIFY_EVENT_PATH)) {
153 if (d_unlinked(path->
dentry))
167 static int idr_callback(
int id,
void *
p,
void *data)
169 struct fsnotify_mark *fsn_mark;
171 static bool warned =
false;
180 WARN(1,
"inotify closing but id=%d for fsn_mark=%p in group=%p still in "
181 "idr. Probably leaking memory\n",
id, p, data);
191 fsn_mark->group, fsn_mark->i.inode, i_mark->
wd);
195 static void inotify_free_group_priv(
struct fsnotify_group *group)
198 idr_for_each(&group->inotify_data.idr, idr_callback, group);
201 atomic_dec(&group->inotify_data.user->inotify_devs);
217 .handle_event = inotify_handle_event,
218 .should_send_event = inotify_should_send_event,
219 .free_group_priv = inotify_free_group_priv,
221 .freeing_mark = inotify_freeing_mark,