Message ID | 20200520073255.20666-2-po-hsu.lin@canonical.com |
---|---|
State | New |
Headers | show |
Series | fix for fanotify15 from ubuntu_ltp_syscalls | expand |
On 20.05.20 09:32, Po-Hsu Lin wrote: > From: Amir Goldstein <amir73il@gmail.com> > > With inotify, when a watch is set on a directory and on its child, an > event on the child is reported twice, once with wd of the parent watch > and once with wd of the child watch without the filename. > > With fanotify, when a watch is set on a directory and on its child, an > event on the child is reported twice, but it has the exact same > information - either an open file descriptor of the child or an encoded > fid of the child. > > The reason that the two identical events are not merged is because the > object id used for merging events in the queue is the child inode in one > event and parent inode in the other. > > For events with path or dentry data, use the victim inode instead of the > watched inode as the object id for event merging, so that the event > reported on parent will be merged with the event reported on the child. > > Link: https://lore.kernel.org/r/20200319151022.31456-9-amir73il@gmail.com > Signed-off-by: Amir Goldstein <amir73il@gmail.com> > Signed-off-by: Jan Kara <jack@suse.cz> > (backported from commit f367a62a7cad2447d835a9f14fc63997a9137246) > [PHLin: backported with the same logic] > Signed-off-by: Po-Hsu Lin <po-hsu.lin@canonical.com> > --- I can see no BugLink in there or the cover email. -Stefan > fs/notify/fanotify/fanotify.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c > index 5778d13..f1ca308 100644 > --- a/fs/notify/fanotify/fanotify.c > +++ b/fs/notify/fanotify/fanotify.c > @@ -314,7 +314,12 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, > if (!event) > goto out; > init: __maybe_unused > - fsnotify_init_event(&event->fse, inode); > + /* > + * Use the victim inode instead of the watching inode as the id for > + * event queue, so event reported on parent is merged with event > + * reported on child when both directory and child watches exist. > + */ > + fsnotify_init_event(&event->fse, (unsigned long)id); > event->mask = mask; > if (FAN_GROUP_FLAG(group, FAN_REPORT_TID)) > event->pid = get_pid(task_pid(current)); >
Sorry I will add the bug link in V2.
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 5778d13..f1ca308 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -314,7 +314,12 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, if (!event) goto out; init: __maybe_unused - fsnotify_init_event(&event->fse, inode); + /* + * Use the victim inode instead of the watching inode as the id for + * event queue, so event reported on parent is merged with event + * reported on child when both directory and child watches exist. + */ + fsnotify_init_event(&event->fse, (unsigned long)id); event->mask = mask; if (FAN_GROUP_FLAG(group, FAN_REPORT_TID)) event->pid = get_pid(task_pid(current));