#endif
static int fanotify_handle_event(struct fsnotify_group *group,
- struct fsnotify_mark *mark,
+ struct fsnotify_mark *inode_mark,
+ struct fsnotify_mark *fanotify_mark,
struct fsnotify_event *event)
{
int ret = 0;
return ret;
}
-static bool should_send_vfsmount_event(struct fsnotify_group *group, struct vfsmount *mnt,
- struct inode *inode, __u32 mask)
+static bool fanotify_should_send_event(struct fsnotify_group *group,
+ struct inode *to_tell,
+ struct fsnotify_mark *inode_mark,
+ struct fsnotify_mark *vfsmnt_mark,
+ __u32 event_mask, void *data, int data_type)
{
- struct fsnotify_mark *mnt_mark;
- struct fsnotify_mark *inode_mark;
+ __u32 marks_mask, marks_ignored_mask;
- pr_debug("%s: group=%p vfsmount=%p mask=%x\n",
- __func__, group, mnt, mask);
+ pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p "
+ "mask=%x data=%p data_type=%d\n", __func__, group, to_tell,
+ inode_mark, vfsmnt_mark, event_mask, data, data_type);
- mnt_mark = fsnotify_find_vfsmount_mark(group, mnt);
- if (!mnt_mark)
- return false;
-
- mask &= mnt_mark->mask;
- mask &= ~mnt_mark->ignored_mask;
-
- if (mask) {
- inode_mark = fsnotify_find_inode_mark(group, inode);
- if (inode_mark) {
- mask &= ~inode_mark->ignored_mask;
- fsnotify_put_mark(inode_mark);
- }
- }
-
- /* find took a reference */
- fsnotify_put_mark(mnt_mark);
-
- return mask;
-}
-
-static bool should_send_inode_event(struct fsnotify_group *group, struct inode *inode,
- __u32 mask)
-{
- struct fsnotify_mark *fsn_mark;
-
- pr_debug("%s: group=%p inode=%p mask=%x\n",
- __func__, group, inode, mask);
-
- fsn_mark = fsnotify_find_inode_mark(group, inode);
- if (!fsn_mark)
- return false;
-
- /* if the event is for a child and this inode doesn't care about
- * events on the child, don't send it! */
- if ((mask & FS_EVENT_ON_CHILD) &&
- !(fsn_mark->mask & FS_EVENT_ON_CHILD)) {
- mask = 0;
- } else {
- /*
- * We care about children, but do we care about this particular
- * type of event?
- */
- mask &= ~FS_EVENT_ON_CHILD;
- mask &= fsn_mark->mask;
- mask &= ~fsn_mark->ignored_mask;
- }
-
- /* find took a reference */
- fsnotify_put_mark(fsn_mark);
-
- return mask;
-}
-
-static bool fanotify_should_send_event(struct fsnotify_group *group, struct inode *to_tell,
- struct vfsmount *mnt, struct fsnotify_mark *mark,
- __u32 mask, void *data, int data_type)
-{
- pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x data=%p data_type=%d\n",
- __func__, group, to_tell, mnt, mask, data, data_type);
+ pr_debug("%s: group=%p vfsmount_mark=%p inode_mark=%p mask=%x\n",
+ __func__, group, vfsmnt_mark, inode_mark, event_mask);
/* sorry, fanotify only gives a damn about files and dirs */
if (!S_ISREG(to_tell->i_mode) &&
if (data_type != FSNOTIFY_EVENT_FILE)
return false;
- if (mnt)
- return should_send_vfsmount_event(group, mnt, to_tell, mask);
- else
- return should_send_inode_event(group, to_tell, mask);
+ if (inode_mark && vfsmnt_mark) {
+ marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
+ marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
+ } else if (inode_mark) {
+ /*
+ * if the event is for a child and this inode doesn't care about
+ * events on the child, don't send it!
+ */
+ if ((event_mask & FS_EVENT_ON_CHILD) &&
+ !(inode_mark->mask & FS_EVENT_ON_CHILD))
+ return false;
+ marks_mask = inode_mark->mask;
+ marks_ignored_mask = inode_mark->ignored_mask;
+ } else if (vfsmnt_mark) {
+ marks_mask = vfsmnt_mark->mask;
+ marks_ignored_mask = vfsmnt_mark->ignored_mask;
+ } else {
+ BUG();
+ }
+
+ if (event_mask & marks_mask & ~marks_ignored_mask)
+ return true;
+
+ return false;
}
const struct fsnotify_ops fanotify_fsnotify_ops = {