summaryrefslogtreecommitdiff
path: root/fs/notify/fanotify/fanotify.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2020-12-02 14:07:09 +0200
committerJan Kara <jack@suse.cz>2020-12-11 11:40:43 +0100
commitfecc4559780d52d174ea05e3bf543669165389c3 (patch)
treeb50b549f4c647bbd4ee4dda2603cb2e8b8b2195b /fs/notify/fanotify/fanotify.c
parent1a2620a99803ad660edc5d22fd9c66cce91ceb1c (diff)
fsnotify: fix events reported to watching parent and child
fsnotify_parent() used to send two separate events to backends when a parent inode is watching children and the child inode is also watching. In an attempt to avoid duplicate events in fanotify, we unified the two backend callbacks to a single callback and handled the reporting of the two separate events for the relevant backends (inotify and dnotify). However the handling is buggy and can result in inotify and dnotify listeners receiving events of the type they never asked for or spurious events. The problem is the unified event callback with two inode marks (parent and child) is called when any of the parent and child inodes are watched and interested in the event, but the parent inode's mark that is interested in the event on the child is not necessarily the one we are currently reporting to (it could belong to a different group). So before reporting the parent or child event flavor to backend we need to check that the mark is really interested in that event flavor. The semantics of INODE and CHILD marks were hard to follow and made the logic more complicated than it should have been. Replace it with INODE and PARENT marks semantics to hopefully make the logic more clear. Thanks to Hugh Dickins for spotting a bug in the earlier version of this patch. Fixes: 497b0c5a7c06 ("fsnotify: send event to parent and child with single callback") CC: stable@vger.kernel.org Link: https://lore.kernel.org/r/20201202120713.702387-4-amir73il@gmail.com Reported-by: Hugh Dickins <hughd@google.com> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/fanotify/fanotify.c')
-rw-r--r--fs/notify/fanotify/fanotify.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 9167884a61ec..1192c9953620 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -268,12 +268,11 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group,
continue;
/*
- * If the event is for a child and this mark is on a parent not
+ * If the event is on a child and this mark is on a parent not
* watching children, don't send it!
*/
- if (event_mask & FS_EVENT_ON_CHILD &&
- type == FSNOTIFY_OBJ_TYPE_INODE &&
- !(mark->mask & FS_EVENT_ON_CHILD))
+ if (type == FSNOTIFY_OBJ_TYPE_PARENT &&
+ !(mark->mask & FS_EVENT_ON_CHILD))
continue;
marks_mask |= mark->mask;