]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.6
authorSasha Levin <sashal@kernel.org>
Wed, 13 May 2020 00:50:58 +0000 (20:50 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 13 May 2020 00:50:58 +0000 (20:50 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.6/fanotify-merge-duplicate-events-on-parent-and-child.patch [new file with mode: 0644]
queue-5.6/fsnotify-replace-inode-pointer-with-an-object-id.patch [new file with mode: 0644]
queue-5.6/series

diff --git a/queue-5.6/fanotify-merge-duplicate-events-on-parent-and-child.patch b/queue-5.6/fanotify-merge-duplicate-events-on-parent-and-child.patch
new file mode 100644 (file)
index 0000000..b02f5aa
--- /dev/null
@@ -0,0 +1,55 @@
+From d301556142fe790ee058083d2672b8415ac9d2f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Mar 2020 17:10:16 +0200
+Subject: fanotify: merge duplicate events on parent and child
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+[ Upstream commit f367a62a7cad2447d835a9f14fc63997a9137246 ]
+
+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>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 14d0ac4664595..f5d30573f4a99 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, (unsigned long)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));
+-- 
+2.20.1
+
diff --git a/queue-5.6/fsnotify-replace-inode-pointer-with-an-object-id.patch b/queue-5.6/fsnotify-replace-inode-pointer-with-an-object-id.patch
new file mode 100644 (file)
index 0000000..12567c9
--- /dev/null
@@ -0,0 +1,113 @@
+From 28eca04e867fe4e4ecdca591f477171b77cb990d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Mar 2020 17:10:15 +0200
+Subject: fsnotify: replace inode pointer with an object id
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+[ Upstream commit dfc2d2594e4a79204a3967585245f00644b8f838 ]
+
+The event inode field is used only for comparison in queue merges and
+cannot be dereferenced after handle_event(), because it does not hold a
+refcount on the inode.
+
+Replace it with an abstract id to do the same thing.
+
+Link: https://lore.kernel.org/r/20200319151022.31456-8-amir73il@gmail.com
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/notify/fanotify/fanotify.c        | 4 ++--
+ fs/notify/inotify/inotify_fsnotify.c | 4 ++--
+ fs/notify/inotify/inotify_user.c     | 2 +-
+ include/linux/fsnotify_backend.h     | 7 +++----
+ 4 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
+index 5778d1347b351..14d0ac4664595 100644
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -26,7 +26,7 @@ static bool should_merge(struct fsnotify_event *old_fsn,
+       old = FANOTIFY_E(old_fsn);
+       new = FANOTIFY_E(new_fsn);
+-      if (old_fsn->inode != new_fsn->inode || old->pid != new->pid ||
++      if (old_fsn->objectid != new_fsn->objectid || old->pid != new->pid ||
+           old->fh_type != new->fh_type || old->fh_len != new->fh_len)
+               return false;
+@@ -314,7 +314,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
+       if (!event)
+               goto out;
+ init: __maybe_unused
+-      fsnotify_init_event(&event->fse, inode);
++      fsnotify_init_event(&event->fse, (unsigned long)inode);
+       event->mask = mask;
+       if (FAN_GROUP_FLAG(group, FAN_REPORT_TID))
+               event->pid = get_pid(task_pid(current));
+diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
+index d510223d302ca..589dee9629938 100644
+--- a/fs/notify/inotify/inotify_fsnotify.c
++++ b/fs/notify/inotify/inotify_fsnotify.c
+@@ -39,7 +39,7 @@ static bool event_compare(struct fsnotify_event *old_fsn,
+       if (old->mask & FS_IN_IGNORED)
+               return false;
+       if ((old->mask == new->mask) &&
+-          (old_fsn->inode == new_fsn->inode) &&
++          (old_fsn->objectid == new_fsn->objectid) &&
+           (old->name_len == new->name_len) &&
+           (!old->name_len || !strcmp(old->name, new->name)))
+               return true;
+@@ -118,7 +118,7 @@ int inotify_handle_event(struct fsnotify_group *group,
+               mask &= ~IN_ISDIR;
+       fsn_event = &event->fse;
+-      fsnotify_init_event(fsn_event, inode);
++      fsnotify_init_event(fsn_event, (unsigned long)inode);
+       event->mask = mask;
+       event->wd = i_mark->wd;
+       event->sync_cookie = cookie;
+diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
+index 107537a543fd8..81ffc8629fc4b 100644
+--- a/fs/notify/inotify/inotify_user.c
++++ b/fs/notify/inotify/inotify_user.c
+@@ -635,7 +635,7 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events)
+               return ERR_PTR(-ENOMEM);
+       }
+       group->overflow_event = &oevent->fse;
+-      fsnotify_init_event(group->overflow_event, NULL);
++      fsnotify_init_event(group->overflow_event, 0);
+       oevent->mask = FS_Q_OVERFLOW;
+       oevent->wd = -1;
+       oevent->sync_cookie = 0;
+diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
+index 1915bdba2fad9..64cfb5446f4d4 100644
+--- a/include/linux/fsnotify_backend.h
++++ b/include/linux/fsnotify_backend.h
+@@ -133,8 +133,7 @@ struct fsnotify_ops {
+  */
+ struct fsnotify_event {
+       struct list_head list;
+-      /* inode may ONLY be dereferenced during handle_event(). */
+-      struct inode *inode;    /* either the inode the event happened to or its parent */
++      unsigned long objectid; /* identifier for queue merges */
+ };
+ /*
+@@ -500,10 +499,10 @@ extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
+ extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
+ static inline void fsnotify_init_event(struct fsnotify_event *event,
+-                                     struct inode *inode)
++                                     unsigned long objectid)
+ {
+       INIT_LIST_HEAD(&event->list);
+-      event->inode = inode;
++      event->objectid = objectid;
+ }
+ #else
+-- 
+2.20.1
+
index e4846ff0027b01f82c7708a9a7bb8c03641fa57e..0a34dcf6d5a672cbe44697f04e987eab9c3704c0 100644 (file)
@@ -114,3 +114,5 @@ mm-memcg-fix-error-return-value-of-mem_cgroup_css_alloc.patch
 bdi-move-bdi_dev_name-out-of-line.patch
 bdi-add-a-dev_name-field-to-struct-backing_dev_info.patch
 io_uring-don-t-use-fd-for-openat-openat2-statx.patch
+fsnotify-replace-inode-pointer-with-an-object-id.patch
+fanotify-merge-duplicate-events-on-parent-and-child.patch