fsnotify: fix events reported to watching parent and child
authorAmir Goldstein <amir73il@gmail.com>
Wed, 2 Dec 2020 12:07:09 +0000 (14:07 +0200)
committerJan Kara <jack@suse.cz>
Fri, 11 Dec 2020 10:40:43 +0000 (11:40 +0100)
commitfecc4559780d52d174ea05e3bf543669165389c3
treeb50b549f4c647bbd4ee4dda2603cb2e8b8b2195b
parent1a2620a99803ad660edc5d22fd9c66cce91ceb1c
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>
fs/notify/fanotify/fanotify.c
fs/notify/fsnotify.c
include/linux/fsnotify_backend.h