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 v2 6/9] fanotify: record old and new parent and name in FAN_RENAME event
Date: Fri, 19 Nov 2021 09:17:35 +0200 [thread overview]
Message-ID: <20211119071738.1348957-7-amir73il@gmail.com> (raw)
In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com>
In the special case of FAN_RENAME event, we record both the old
and new parent and name.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/notify/fanotify/fanotify.c | 44 +++++++++++++++++++++++++++++++----
include/uapi/linux/fanotify.h | 2 ++
2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index 447e97396c58..018b32a57702 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -592,21 +592,28 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *dir,
__kernel_fsid_t *fsid,
const struct qstr *name,
struct inode *child,
+ struct dentry *moved,
unsigned int *hash,
gfp_t gfp)
{
struct fanotify_name_event *fne;
struct fanotify_info *info;
struct fanotify_fh *dfh, *ffh;
+ struct inode *dir2 = moved ? d_inode(moved->d_parent) : NULL;
+ const struct qstr *name2 = moved ? &moved->d_name : NULL;
unsigned int dir_fh_len = fanotify_encode_fh_len(dir);
+ unsigned int dir2_fh_len = fanotify_encode_fh_len(dir2);
unsigned int child_fh_len = fanotify_encode_fh_len(child);
unsigned long name_len = name ? name->len : 0;
+ unsigned long name2_len = name2 ? name2->len : 0;
unsigned int len, size;
/* Reserve terminating null byte even for empty name */
- size = sizeof(*fne) + name_len + 1;
+ size = sizeof(*fne) + name_len + name2_len + 2;
if (dir_fh_len)
size += FANOTIFY_FH_HDR_LEN + dir_fh_len;
+ if (dir2_fh_len)
+ size += FANOTIFY_FH_HDR_LEN + dir2_fh_len;
if (child_fh_len)
size += FANOTIFY_FH_HDR_LEN + child_fh_len;
fne = kmalloc(size, gfp);
@@ -623,6 +630,11 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *dir,
len = fanotify_encode_fh(dfh, dir, dir_fh_len, hash, 0);
fanotify_info_set_dir_fh(info, len);
}
+ if (dir2_fh_len) {
+ dfh = fanotify_info_dir2_fh(info);
+ len = fanotify_encode_fh(dfh, dir2, dir2_fh_len, hash, 0);
+ fanotify_info_set_dir2_fh(info, len);
+ }
if (child_fh_len) {
ffh = fanotify_info_file_fh(info);
len = fanotify_encode_fh(ffh, child, child_fh_len, hash, 0);
@@ -632,11 +644,22 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *dir,
fanotify_info_copy_name(info, name);
*hash ^= full_name_hash((void *)name_len, name->name, name_len);
}
+ if (name2_len) {
+ fanotify_info_copy_name2(info, name2);
+ *hash ^= full_name_hash((void *)name2_len, name2->name,
+ name2_len);
+ }
pr_debug("%s: size=%u dir_fh_len=%u child_fh_len=%u name_len=%u name='%.*s'\n",
__func__, size, dir_fh_len, child_fh_len,
info->name_len, info->name_len, fanotify_info_name(info));
+ if (dir2_fh_len) {
+ pr_debug("%s: dir2_fh_len=%u name2_len=%u name2='%.*s'\n",
+ __func__, dir2_fh_len, info->name2_len,
+ info->name2_len, fanotify_info_name2(info));
+ }
+
return &fne->fae;
}
@@ -692,6 +715,7 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
struct inode *dirid = fanotify_dfid_inode(mask, data, data_type, dir);
const struct path *path = fsnotify_data_path(data, data_type);
struct mem_cgroup *old_memcg;
+ struct dentry *moved = NULL;
struct inode *child = NULL;
bool name_event = false;
unsigned int hash = 0;
@@ -727,6 +751,17 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
} else if ((mask & ALL_FSNOTIFY_DIRENT_EVENTS) || !ondir) {
name_event = true;
}
+
+ /*
+ * In the special case of FAN_RENAME event, we record both
+ * old and new parent+name.
+ * 'dirid' and 'file_name' are the old parent+name and
+ * 'moved' has the new parent+name.
+ */
+ if (mask & FAN_RENAME) {
+ moved = fsnotify_data_dentry(data, data_type);
+ name_event = true;
+ }
}
/*
@@ -748,9 +783,9 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
} else if (fanotify_is_error_event(mask)) {
event = fanotify_alloc_error_event(group, fsid, data,
data_type, &hash);
- } else if (name_event && (file_name || child)) {
- event = fanotify_alloc_name_event(id, fsid, file_name, child,
- &hash, gfp);
+ } else if (name_event && (file_name || moved || child)) {
+ event = fanotify_alloc_name_event(dirid, fsid, file_name, child,
+ moved, &hash, gfp);
} else if (fid_mode) {
event = fanotify_alloc_fid_event(id, fsid, &hash, gfp);
} else {
@@ -860,6 +895,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
BUILD_BUG_ON(FAN_OPEN_EXEC != FS_OPEN_EXEC);
BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM);
BUILD_BUG_ON(FAN_FS_ERROR != FS_ERROR);
+ BUILD_BUG_ON(FAN_RENAME != FS_RENAME);
BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 20);
diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h
index 60f73639a896..9d0e2dc5767b 100644
--- a/include/uapi/linux/fanotify.h
+++ b/include/uapi/linux/fanotify.h
@@ -28,6 +28,8 @@
#define FAN_EVENT_ON_CHILD 0x08000000 /* Interested in child events */
+#define FAN_RENAME 0x10000000 /* File was renamed */
+
#define FAN_ONDIR 0x40000000 /* Event occurred against dir */
/* helper events */
--
2.33.1
next prev parent reply other threads:[~2021-11-19 7:17 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-19 7:17 [PATCH v2 0/9] Extend fanotify dirent events Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 1/9] fanotify: introduce group flag FAN_REPORT_TARGET_FID Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 2/9] fsnotify: generate FS_RENAME event with rich information Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 3/9] fanotify: use macros to get the offset to fanotify_info buffer Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 4/9] fanotify: use helpers to parcel " Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 5/9] fanotify: support secondary dir fh and name in fanotify_info Amir Goldstein
2021-11-19 7:17 ` Amir Goldstein [this message]
2021-11-26 14:44 ` [PATCH v2 6/9] fanotify: record old and new parent and name in FAN_RENAME event Jan Kara
2021-11-19 7:17 ` [PATCH v2 7/9] fanotify: record either old name new name or both for FAN_RENAME Amir Goldstein
2021-11-26 15:14 ` Jan Kara
2021-11-29 19:15 ` Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 8/9] fanotify: report old and/or new parent+name in FAN_RENAME event Amir Goldstein
2021-11-19 7:17 ` [PATCH v2 9/9] fanotify: wire up " Amir Goldstein
2021-11-20 12:59 ` [PATCH v2 0/9] Extend fanotify dirent events Amir Goldstein
2021-11-26 15:28 ` Jan Kara
2021-11-29 19:12 ` 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=20211119071738.1348957-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).