All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Jan Kara <jack@suse.cz>
Cc: Matthew Bobrowski <mbobrowski@mbobrowski.org>,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH 6/7] fanotify: report new parent and name in MOVED_FROM event
Date: Fri, 29 Oct 2021 14:40:27 +0300	[thread overview]
Message-ID: <20211029114028.569755-7-amir73il@gmail.com> (raw)
In-Reply-To: <20211029114028.569755-1-amir73il@gmail.com>

In the special case of MOVED_FROM event, if we are reporting the child
fid due to FAN_REPORT_TARGET_FID init flag, we also report the new
parent and name.

The new parent and name are reported using a new info record of type
FAN_EVENT_INFO_TYPE_DFID_NAME2 that follows the info record of type
FAN_EVENT_INFO_TYPE_DFID_NAME with the old parent and name.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fanotify/fanotify.h      | 17 +++++++++++++++++
 fs/notify/fanotify/fanotify_user.c | 29 +++++++++++++++++++++++++++--
 include/uapi/linux/fanotify.h      |  1 +
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h
index 0864e7efe23c..26d471aab054 100644
--- a/fs/notify/fanotify/fanotify.h
+++ b/fs/notify/fanotify/fanotify.h
@@ -339,6 +339,13 @@ static inline int fanotify_event_dir_fh_len(struct fanotify_event *event)
 	return info ? fanotify_info_dir_fh_len(info) : 0;
 }
 
+static inline int fanotify_event_dir2_fh_len(struct fanotify_event *event)
+{
+	struct fanotify_info *info = fanotify_event_info(event);
+
+	return info ? fanotify_info_dir2_fh_len(info) : 0;
+}
+
 static inline bool fanotify_event_has_object_fh(struct fanotify_event *event)
 {
 	/* For error events, even zeroed fh are reported. */
@@ -352,6 +359,16 @@ static inline bool fanotify_event_has_dir_fh(struct fanotify_event *event)
 	return fanotify_event_dir_fh_len(event) > 0;
 }
 
+/* For MOVED_FROM event with FAN_REPORT_TARGET_FID */
+static inline bool fanotify_event_has_two_names(struct fanotify_event *event)
+{
+	struct fanotify_info *info = fanotify_event_info(event);
+
+	return info && info->name_len && info->name2_len &&
+		fanotify_info_dir_fh_len(info) > 0 &&
+		fanotify_info_dir2_fh_len(info) > 0;
+}
+
 struct fanotify_path_event {
 	struct fanotify_event fae;
 	struct path path;
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index d973f36676a9..d6420e10740d 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -134,7 +134,7 @@ static size_t fanotify_event_len(unsigned int info_mode,
 {
 	size_t event_len = FAN_EVENT_METADATA_LEN;
 	struct fanotify_info *info;
-	int dir_fh_len;
+	int dir_fh_len, dir2_fh_len;
 	int fh_len;
 	int dot_len = 0;
 
@@ -149,6 +149,11 @@ static size_t fanotify_event_len(unsigned int info_mode,
 	if (fanotify_event_has_dir_fh(event)) {
 		dir_fh_len = fanotify_event_dir_fh_len(event);
 		event_len += fanotify_fid_info_len(dir_fh_len, info->name_len);
+		if (fanotify_event_has_two_names(event)) {
+			dir2_fh_len = fanotify_event_dir2_fh_len(event);
+			event_len += fanotify_fid_info_len(dir2_fh_len,
+							   info->name2_len);
+		}
 	} else if ((info_mode & FAN_REPORT_NAME) &&
 		   (event->mask & FAN_ONDIR)) {
 		/*
@@ -379,6 +384,7 @@ static int copy_fid_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh,
 			return -EFAULT;
 		break;
 	case FAN_EVENT_INFO_TYPE_DFID_NAME:
+	case FAN_EVENT_INFO_TYPE_DFID_NAME2:
 		if (WARN_ON_ONCE(!name || !name_len))
 			return -EFAULT;
 		break;
@@ -478,7 +484,10 @@ static int copy_info_records_to_user(struct fanotify_event *event,
 	unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD;
 
 	/*
-	 * Event info records order is as follows: dir fid + name, child fid.
+	 * Event info records order is as follows:
+	 * 1. dir fid + name
+	 * 2. (optional) new dir fid + new name
+	 * 3. (optional) child fid
 	 */
 	if (fanotify_event_has_dir_fh(event)) {
 		info_type = info->name_len ? FAN_EVENT_INFO_TYPE_DFID_NAME :
@@ -496,6 +505,22 @@ static int copy_info_records_to_user(struct fanotify_event *event,
 		total_bytes += ret;
 	}
 
+	/* New dir fid + name can only be reported after old dir fid + name */
+	if (info_type && fanotify_event_has_two_names(event)) {
+		info_type = FAN_EVENT_INFO_TYPE_DFID_NAME2;
+		ret = copy_fid_info_to_user(fanotify_event_fsid(event),
+					    fanotify_info_dir2_fh(info),
+					    info_type,
+					    fanotify_info_name2(info),
+					    info->name2_len, buf, count);
+		if (ret < 0)
+			return ret;
+
+		buf += ret;
+		count -= ret;
+		total_bytes += ret;
+	}
+
 	if (fanotify_event_has_object_fh(event)) {
 		const char *dot = NULL;
 		int dot_len = 0;
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index f9202ce31b0d..1ac31a912cea 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -131,6 +131,7 @@ struct fanotify_event_metadata {
 #define FAN_EVENT_INFO_TYPE_DFID	3
 #define FAN_EVENT_INFO_TYPE_PIDFD	4
 #define FAN_EVENT_INFO_TYPE_ERROR	5
+#define FAN_EVENT_INFO_TYPE_DFID_NAME2	6 /* For FAN_MOVED_FROM */
 
 /* Variable length info record following event metadata */
 struct fanotify_event_info_header {
-- 
2.33.1


  parent reply	other threads:[~2021-10-29 11:40 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-29 11:40 [PATCH 0/7] Report more information in fanotify dirent events Amir Goldstein
2021-10-29 11:40 ` [PATCH 1/7] fsnotify: pass dentry instead of inode data for move events Amir Goldstein
2021-10-29 11:40 ` [PATCH 2/7] fanotify: introduce group flag FAN_REPORT_TARGET_FID Amir Goldstein
2021-10-29 11:40 ` [PATCH 3/7] fanotify: use macros to get the offset to fanotify_info buffer Amir Goldstein
2021-10-29 11:40 ` [PATCH 4/7] fanotify: support secondary dir fh and name in fanotify_info Amir Goldstein
2021-10-29 11:40 ` [PATCH 5/7] fanotify: record new parent and name in MOVED_FROM event Amir Goldstein
2021-11-12 16:48   ` Jan Kara
2021-11-13  9:40     ` Amir Goldstein
2021-11-15  8:18       ` Jan Kara
2021-10-29 11:40 ` Amir Goldstein [this message]
2021-10-29 11:40 ` [PATCH 7/7] fanotify: enable the FAN_REPORT_TARGET_FID flag Amir Goldstein
2021-11-06 16:29 ` [PATCH 0/7] Report more information in fanotify dirent events Amir Goldstein
2021-11-12 16:39   ` Jan Kara
2021-11-13  9:49     ` Amir Goldstein
2021-11-13 19:31       ` Amir Goldstein
2021-11-15 10:23         ` Jan Kara
2021-11-15 12:22           ` Amir Goldstein
2021-11-15 14:37             ` Jan Kara
2021-11-16  6:59               ` Amir Goldstein
2021-11-16 10:12                 ` Jan Kara
2021-11-18 12:47                   ` Amir Goldstein
2021-11-18 16:29                     ` Jan Kara
2021-11-18 16:43                       ` Amir Goldstein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211029114028.569755-7-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mbobrowski@mbobrowski.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.