summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2018-04-05 16:18:03 +0300
committerJan Kara <jack@suse.cz>2018-04-13 15:52:49 +0200
commit92183a42898dc400b89da35685d1814ac6acd3d8 (patch)
treecaad53c6a808a571a2d794c810896d505ed8c66c
parent5ac7c2fd6e7102532104907c0df94abca826ec5c (diff)
downloadlinux-92183a42898dc400b89da35685d1814ac6acd3d8.tar.bz2
fsnotify: fix ignore mask logic in send_to_group()
The ignore mask logic in send_to_group() does not match the logic in fanotify_should_send_event(). In the latter, a vfsmount mark ignore mask precedes an inode mark mask and in the former, it does not. That difference may cause events to be sent to fanotify backend for no reason. Fix the logic in send_to_group() to match that of fanotify_should_send_event(). Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/notify/fsnotify.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 219b269c737e..613ec7e5a465 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -192,8 +192,9 @@ static int send_to_group(struct inode *to_tell,
struct fsnotify_iter_info *iter_info)
{
struct fsnotify_group *group = NULL;
- __u32 inode_test_mask = 0;
- __u32 vfsmount_test_mask = 0;
+ __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+ __u32 marks_mask = 0;
+ __u32 marks_ignored_mask = 0;
if (unlikely(!inode_mark && !vfsmount_mark)) {
BUG();
@@ -213,29 +214,25 @@ static int send_to_group(struct inode *to_tell,
/* does the inode mark tell us to do something? */
if (inode_mark) {
group = inode_mark->group;
- inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
- inode_test_mask &= inode_mark->mask;
- inode_test_mask &= ~inode_mark->ignored_mask;
+ marks_mask |= inode_mark->mask;
+ marks_ignored_mask |= inode_mark->ignored_mask;
}
/* does the vfsmount_mark tell us to do something? */
if (vfsmount_mark) {
- vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
group = vfsmount_mark->group;
- vfsmount_test_mask &= vfsmount_mark->mask;
- vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
- if (inode_mark)
- vfsmount_test_mask &= ~inode_mark->ignored_mask;
+ marks_mask |= vfsmount_mark->mask;
+ marks_ignored_mask |= vfsmount_mark->ignored_mask;
}
pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
- " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
+ " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
" data=%p data_is=%d cookie=%d\n",
- __func__, group, to_tell, mask, inode_mark,
- inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
+ __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
+ marks_mask, marks_ignored_mask, data,
data_is, cookie);
- if (!inode_test_mask && !vfsmount_test_mask)
+ if (!(test_mask & marks_mask & ~marks_ignored_mask))
return 0;
return group->ops->handle_event(group, to_tell, inode_mark,