From patchwork Fri Nov 19 07:17:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628389 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0FBA2C433FE for ; Fri, 19 Nov 2021 07:17:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EC3FC61B04 for ; Fri, 19 Nov 2021 07:17:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233687AbhKSHUq (ORCPT ); Fri, 19 Nov 2021 02:20:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231667AbhKSHUq (ORCPT ); Fri, 19 Nov 2021 02:20:46 -0500 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8D19AC061574 for ; Thu, 18 Nov 2021 23:17:44 -0800 (PST) Received: by mail-wr1-x42d.google.com with SMTP id u18so16430766wrg.5 for ; Thu, 18 Nov 2021 23:17:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6d1QVvdCUQXe+/rLlA6XdfalKLkh4mUpnaYWDbHrQf8=; b=Kyr+REYE90/2bVW3tNMH4/Y5vH6xCjXPeeYOt2q+BEAMmoVjxWQk0zgMUAezah8/KR Dh3Np7o+EXI0T1zxmjPMVakrD7cj1T0Xl1416ke/cmMXY7pzFy7Ea+7GCATHcxWdWdAP gwUwYLjAsj9UqWevvt6GmV5rLzQW2MUf/cM3UahLS4VwA+JxIL3+Ta8L4Ns0AdJlohah QphSfESCrxKyZ4IQ6ZtHcXf/w99rr21aZMwq4w29u2Yg929CCnfWwjYClNIwXK1q8qEu ChNN0f/a13J24aaNPMH6wYDs75BUFGrJlCcTgueZh7beSu+RKKel71UP2aFGUVAKP6MG 2wjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6d1QVvdCUQXe+/rLlA6XdfalKLkh4mUpnaYWDbHrQf8=; b=jOAjz0h6XnqFVZlF+1Ye/MCv5zJpkuia0izOoJQNdF9Wh93t0+Ri4FE31Ut15KE60Q Yy4VgOeQU1MrnX+xsjQ6WTRi26Gz1OcooDoXBllfCC4NbaecmoO7EMzQVwkNqnWNvfBK mPD4LKObT+DoMttO7stAh5qxZFm1w4eGK5tgx4nVzioscdfHhVh6g+psXmvix/BHbhkJ p5zTmPxZAFPKPlZXrMHWc7oj6kHJXcBbfOThSq2we2Rz+uu2dj/A8pvNSldnFyMGJrWB /9a0RZds1lfThsmK7Q0UkrhqfTVnumEFzJDchhs+CY7IfRvxn7AXoRXIeRysRTzqB9Di W8jA== X-Gm-Message-State: AOAM530tBjIQeo0oAjDfzBBS12kdFWintAYWOmsr/Ov3yF1idHtRoUdz oOkpHLVideXjxpIlkoBzD9q8ImBE48w= X-Google-Smtp-Source: ABdhPJzxVAAlu+NDDAbe0Cf+0wUdM+OSpqDTi8rgB1c52KSmFaUz1on+D4lXBXIoaf0b4DNaf28U3w== X-Received: by 2002:adf:a2de:: with SMTP id t30mr4688876wra.58.1637306263129; Thu, 18 Nov 2021 23:17:43 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:42 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 1/9] fanotify: introduce group flag FAN_REPORT_TARGET_FID Date: Fri, 19 Nov 2021 09:17:30 +0200 Message-Id: <20211119071738.1348957-2-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org FAN_REPORT_FID is ambiguous in that it reports the fid of the child for some events and the fid of the parent for create/delete/move events. The new FAN_REPORT_TARGET_FID flag is an implicit request to report the fid of the target object of the operation (a.k.a the child inode) also in create/delete/move events in addition to the fid of the parent and the name of the child. To reduce the test matrix for uninteresting use cases, the new FAN_REPORT_TARGET_FID flag requires both FAN_REPORT_NAME and FAN_REPORT_FID. The convenience macro FAN_REPORT_DFID_NAME_TARGET combines FAN_REPORT_TARGET_FID with all the required flags. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 48 ++++++++++++++++++++++-------- fs/notify/fanotify/fanotify_user.c | 11 ++++++- include/linux/fanotify.h | 2 +- include/uapi/linux/fanotify.h | 4 +++ 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b6091775aa6e..9b1641ecfe97 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -458,17 +458,41 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, } /* - * The inode to use as identifier when reporting fid depends on the event. - * Report the modified directory inode on dirent modification events. - * Report the "victim" inode otherwise. + * FAN_REPORT_FID is ambiguous in that it reports the fid of the child for + * some events and the fid of the parent for create/delete/move events. + * + * With the FAN_REPORT_TARGET_FID flag, the fid of the child is reported + * also in create/delete/move events in addition to the fid of the parent + * and the name of the child. + */ +static inline bool fanotify_report_child_fid(unsigned int fid_mode, u32 mask) +{ + if (mask & ALL_FSNOTIFY_DIRENT_EVENTS) + return (fid_mode & FAN_REPORT_TARGET_FID); + + return (fid_mode & FAN_REPORT_FID) && !(mask & FAN_ONDIR); +} + +/* + * The inode to use as identifier when reporting fid depends on the event + * and the group flags. + * + * With the group flag FAN_REPORT_TARGET_FID, always report the child fid. + * + * Without the group flag FAN_REPORT_TARGET_FID, report the modified directory + * fid on dirent events and the child fid otherwise. + * * For example: - * FS_ATTRIB reports the child inode even if reported on a watched parent. - * FS_CREATE reports the modified dir inode and not the created inode. + * FS_ATTRIB reports the child fid even if reported on a watched parent. + * FS_CREATE reports the modified dir fid without FAN_REPORT_TARGET_FID. + * and reports the created child fid with FAN_REPORT_TARGET_FID. */ static struct inode *fanotify_fid_inode(u32 event_mask, const void *data, - int data_type, struct inode *dir) + int data_type, struct inode *dir, + unsigned int fid_mode) { - if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS) + if ((event_mask & ALL_FSNOTIFY_DIRENT_EVENTS) && + !(fid_mode & FAN_REPORT_TARGET_FID)) return dir; return fsnotify_data_inode(data, data_type); @@ -647,10 +671,11 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, { struct fanotify_event *event = NULL; gfp_t gfp = GFP_KERNEL_ACCOUNT; - struct inode *id = fanotify_fid_inode(mask, data, data_type, dir); + unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); + struct inode *id = fanotify_fid_inode(mask, data, data_type, dir, + fid_mode); struct inode *dirid = fanotify_dfid_inode(mask, data, data_type, dir); const struct path *path = fsnotify_data_path(data, data_type); - unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); struct mem_cgroup *old_memcg; struct inode *child = NULL; bool name_event = false; @@ -660,11 +685,10 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, if ((fid_mode & FAN_REPORT_DIR_FID) && dirid) { /* - * With both flags FAN_REPORT_DIR_FID and FAN_REPORT_FID, we - * report the child fid for events reported on a non-dir child + * For certain events and group flags, report the child fid * in addition to reporting the parent fid and maybe child name. */ - if ((fid_mode & FAN_REPORT_FID) && id != dirid && !ondir) + if (fanotify_report_child_fid(fid_mode, mask) && id != dirid) child = id; id = dirid; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 559bc1e9926d..0ade5031733d 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1275,6 +1275,15 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) if ((fid_mode & FAN_REPORT_NAME) && !(fid_mode & FAN_REPORT_DIR_FID)) return -EINVAL; + /* + * FAN_REPORT_TARGET_FID requires FAN_REPORT_NAME and FAN_REPORT_FID + * and is used as an indication to report both dir and child fid on all + * dirent events. + */ + if ((fid_mode & FAN_REPORT_TARGET_FID) && + (!(fid_mode & FAN_REPORT_NAME) || !(fid_mode & FAN_REPORT_FID))) + return -EINVAL; + f_flags = O_RDWR | FMODE_NONOTIFY; if (flags & FAN_CLOEXEC) f_flags |= O_CLOEXEC; @@ -1667,7 +1676,7 @@ static int __init fanotify_user_setup(void) FANOTIFY_DEFAULT_MAX_USER_MARKS); BUILD_BUG_ON(FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS); - BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 11); + BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 12); BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 9); fanotify_mark_cache = KMEM_CACHE(fsnotify_mark, diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 616af2ea20f3..376e050e6f38 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -25,7 +25,7 @@ extern struct ctl_table fanotify_table[]; /* for sysctl */ #define FANOTIFY_CLASS_BITS (FAN_CLASS_NOTIF | FANOTIFY_PERM_CLASSES) -#define FANOTIFY_FID_BITS (FAN_REPORT_FID | FAN_REPORT_DFID_NAME) +#define FANOTIFY_FID_BITS (FAN_REPORT_DFID_NAME_TARGET) #define FANOTIFY_INFO_MODES (FANOTIFY_FID_BITS | FAN_REPORT_PIDFD) diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index bd1932c2074d..60f73639a896 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -57,9 +57,13 @@ #define FAN_REPORT_FID 0x00000200 /* Report unique file id */ #define FAN_REPORT_DIR_FID 0x00000400 /* Report unique directory id */ #define FAN_REPORT_NAME 0x00000800 /* Report events with name */ +#define FAN_REPORT_TARGET_FID 0x00001000 /* Report dirent target id */ /* Convenience macro - FAN_REPORT_NAME requires FAN_REPORT_DIR_FID */ #define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME) +/* Convenience macro - FAN_REPORT_TARGET_FID requires all other FID flags */ +#define FAN_REPORT_DFID_NAME_TARGET (FAN_REPORT_DFID_NAME | \ + FAN_REPORT_FID | FAN_REPORT_TARGET_FID) /* Deprecated - do not use this in programs and do not add new flags here! */ #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \ From patchwork Fri Nov 19 07:17:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628391 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27065C433EF for ; Fri, 19 Nov 2021 07:17:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 102B061AFD for ; Fri, 19 Nov 2021 07:17:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233719AbhKSHUu (ORCPT ); Fri, 19 Nov 2021 02:20:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233682AbhKSHUr (ORCPT ); Fri, 19 Nov 2021 02:20:47 -0500 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1E18C061574 for ; Thu, 18 Nov 2021 23:17:45 -0800 (PST) Received: by mail-wr1-x42b.google.com with SMTP id a9so16423813wrr.8 for ; Thu, 18 Nov 2021 23:17:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ukibpyvVO4XMaS0yh32YqXftFH9VAVvKgHaiUJfMW7U=; b=hubfvO6XOE3eoPd0i4swS4dktPZaRPdxdTL+F9VWSA2N6zRcBD0yIonT4uRo0fvPm/ VkIAUh3MMfchdm3AVurvVQl29BNYKtqIMzR8jCDLBt4XB9FaBLGYXo9E4oVlJL4+KAXr X5ydVh3FHOvAUmXx2c0jiqilsqLTk80L6vNZmFLeIVbhHIE7wUAS7H1F+I6rx7Fe/ega zvID4PkszwszSJJUpMf7BusWU1EGFWXWFez0c5IWFwRTib172NoqBFXe8h0gV/Ui82/I hMB/DxfsROQvWN1csyy6eaXXpeIDTE3rbVkTuXPCdis8ICtA+PcQDhLzeVBrXD4xOFiU 4ghQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ukibpyvVO4XMaS0yh32YqXftFH9VAVvKgHaiUJfMW7U=; b=24L5N7bvqv/nWjkToZiTO+UWyWNvi/q+zvZR5M6PjeDLJEAhdJPmvw/ujiDHccCaqf iUX3uarQXmIuxwGvjevZYw95Ylj1uJaErr7CUi2OKsdb2TF3TM903g0tBrH44Lp1AnP/ D4TAqEruo+OoBtfyq2VJ/PYaWTDkDUjEjXQFZbbS4dZ7FZjdB+KwZCnQMGamyyUSgdFP pNPe3REpgq/GW35J3e3F2Fy6YB4Cx+tRZWenjyZylbPSBLiPK7tj/Djz93Nd+YAW+/xu tFRtjUxQQmiFpTOnhdxmaRwSIdiBMt8j2YaJnYnwpualjkchspURk0ZtwrwpmJ6YUi5F IZwg== X-Gm-Message-State: AOAM5324jEpIqgFLdVOVXHRfGss6RPtIJSHJJ+UiMLGval7cmWQCfA2h QE2Ocqm2zWsBrozOymdI9cRKM+HfQvk= X-Google-Smtp-Source: ABdhPJyXldEUm9ClAStoOdPb64I3bTWB6KdS1WLq5sVdZptsC7JmWGTZRTpgwMq23z+JZbso41BWpQ== X-Received: by 2002:a5d:6d84:: with SMTP id l4mr4948671wrs.266.1637306264363; Thu, 18 Nov 2021 23:17:44 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:43 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 2/9] fsnotify: generate FS_RENAME event with rich information Date: Fri, 19 Nov 2021 09:17:31 +0200 Message-Id: <20211119071738.1348957-3-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The dnotify FS_DN_RENAME event is used to request notification about a move within the same parent directory and was always coupled with the FS_MOVED_FROM event. Rename the FS_DN_RENAME event flag to FS_RENAME, decouple it from FS_MOVED_FROM and report it with the moved dentry instead of the moved inode, so it has the information about both old and new parent and name. Generate the FS_RENAME event regardless of same parent dir and apply the "same parent" rule in the generic fsnotify_handle_event() helper that is used to call backends with ->handle_inode_event() method (i.e. dnotify). The ->handle_inode_event() method is not rich enough to report both old and new parent and name anyway. The enriched event is reported to fanotify over the ->handle_event() method with the marks array slots for inode and parent mark types hold the old and new parent inode marks of the group. The enriched event will be used for reporting old and new parent+name to fanotify groups with FAN_RENAME events. Signed-off-by: Amir Goldstein --- fs/notify/dnotify/dnotify.c | 2 +- fs/notify/fsnotify.c | 14 ++++++++++++++ include/linux/dnotify.h | 2 +- include/linux/fsnotify.h | 9 ++++++--- include/linux/fsnotify_backend.h | 6 +++--- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index e85e13c50d6d..d5ebebb034ff 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -196,7 +196,7 @@ static __u32 convert_arg(unsigned long arg) if (arg & DN_ATTRIB) new_mask |= FS_ATTRIB; if (arg & DN_RENAME) - new_mask |= FS_DN_RENAME; + new_mask |= FS_RENAME; if (arg & DN_CREATE) new_mask |= (FS_CREATE | FS_MOVED_TO); diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 4034ca566f95..fc21a3b5b86c 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -279,6 +279,14 @@ static int fsnotify_handle_event(struct fsnotify_group *group, __u32 mask, WARN_ON_ONCE(fsnotify_iter_vfsmount_mark(iter_info))) return 0; + /* + * For FS_RENAME, inode is old_dir and parent is new_dir. + * The only ->handle_inode_event() backend that supports FS_RENAME is + * dnotify, where it means file was renamed within same parent. + */ + if ((mask & FS_RENAME) && parent_mark != inode_mark) + return 0; + if (parent_mark) { /* * parent_mark indicates that the parent inode is watching @@ -470,6 +478,7 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, struct fsnotify_iter_info iter_info = {}; struct mount *mnt = NULL; struct inode *parent = NULL; + struct dentry *moved; int ret = 0; __u32 test_mask, marks_mask; @@ -479,6 +488,11 @@ int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, if (!inode) { /* Dirent event - report on TYPE_INODE to dir */ inode = dir; + /* For FS_RENAME, inode is old_dir and parent is new_dir */ + if (mask & FS_RENAME) { + moved = fsnotify_data_dentry(data, data_type); + parent = moved->d_parent->d_inode; + } } else if (mask & FS_EVENT_ON_CHILD) { /* * Event on child - report on TYPE_PARENT to dir if it is diff --git a/include/linux/dnotify.h b/include/linux/dnotify.h index 0aad774beaec..b87c3b85a166 100644 --- a/include/linux/dnotify.h +++ b/include/linux/dnotify.h @@ -26,7 +26,7 @@ struct dnotify_struct { FS_MODIFY | FS_MODIFY_CHILD |\ FS_ACCESS | FS_ACCESS_CHILD |\ FS_ATTRIB | FS_ATTRIB_CHILD |\ - FS_CREATE | FS_DN_RENAME |\ + FS_CREATE | FS_RENAME |\ FS_MOVED_FROM | FS_MOVED_TO) extern int dir_notify_enable; diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 787545e87eeb..3a2d7dc3c607 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -144,16 +144,19 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, u32 fs_cookie = fsnotify_get_cookie(); __u32 old_dir_mask = FS_MOVED_FROM; __u32 new_dir_mask = FS_MOVED_TO; + __u32 rename_mask = FS_RENAME; const struct qstr *new_name = &moved->d_name; - if (old_dir == new_dir) - old_dir_mask |= FS_DN_RENAME; - if (isdir) { old_dir_mask |= FS_ISDIR; new_dir_mask |= FS_ISDIR; + rename_mask |= FS_ISDIR; } + /* Event with information about both old and new parent+name */ + fsnotify_name(rename_mask, moved, FSNOTIFY_EVENT_DENTRY, + old_dir, old_name, 0); + fsnotify_name(old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_dir, old_name, fs_cookie); fsnotify_name(new_dir_mask, source, FSNOTIFY_EVENT_INODE, diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 51ef2b079bfa..357467050380 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -63,7 +63,7 @@ */ #define FS_EVENT_ON_CHILD 0x08000000 -#define FS_DN_RENAME 0x10000000 /* file renamed */ +#define FS_RENAME 0x10000000 /* File was renamed */ #define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */ #define FS_ISDIR 0x40000000 /* event occurred against dir */ #define FS_IN_ONESHOT 0x80000000 /* only send event once */ @@ -76,7 +76,7 @@ * The watching parent may get an FS_ATTRIB|FS_EVENT_ON_CHILD event * when a directory entry inside a child subdir changes. */ -#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE) +#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE | FS_RENAME) #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \ FS_OPEN_EXEC_PERM) @@ -101,7 +101,7 @@ /* Events that can be reported to backends */ #define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \ FS_EVENTS_POSS_ON_CHILD | \ - FS_DELETE_SELF | FS_MOVE_SELF | FS_DN_RENAME | \ + FS_DELETE_SELF | FS_MOVE_SELF | \ FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ FS_ERROR) From patchwork Fri Nov 19 07:17:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628393 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98BCCC433FE for ; Fri, 19 Nov 2021 07:17:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8430861B3D for ; Fri, 19 Nov 2021 07:17:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233737AbhKSHUw (ORCPT ); Fri, 19 Nov 2021 02:20:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46004 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233694AbhKSHUs (ORCPT ); Fri, 19 Nov 2021 02:20:48 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02678C06173E for ; Thu, 18 Nov 2021 23:17:47 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id b184-20020a1c1bc1000000b0033140bf8dd5so6713380wmb.5 for ; Thu, 18 Nov 2021 23:17:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=doaEFdEkruCJZPvutxr6JHq6+EhQEfwiw9SykkAMsFY=; b=STaCoshsydvgaa0XcEgXS3ZeXHaI9xDQ8z4xW2KnZh+//z9QZZ+PQA9lwINf1G51Yo 9Jn7RxJQBJZZSdRtErXahh8mstGVkUi72RKOkt0m2BKibKhisuUK194On2SWpQxwuf/b 2sUBN9EwiUWjhmyZqsdvIiPNT0+ZgaT0T2shorNSa9S/5U4jbTJuDXZo3OPzDubJ6gV+ cZOLZ9p/kGjzLuhH3fxQEQE33UzqWKBsUoI5cLcYEdd6z9HySdeUDwQ94zqCrvXeaXGd 0ng1lwDYWsixZI5FtkB5ypMuiow9rkFue6/eHKKWSyby3yjemGWXbPkvM2iJRnTE+beM mndA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=doaEFdEkruCJZPvutxr6JHq6+EhQEfwiw9SykkAMsFY=; b=Ds91ovlUraZxNMDWTXHj8nawOn8coLCqmAvRDMwDfjzJDsstCTVAg6uKTwXW+iZWQ0 2gA3Y+3clBkWQ9Cg8tcweoQ/BVGLWKlUVKzbXvhHgQNPoF2b+N4yL5nQ+qELVwoMEogb zaFspsysHoA8FLWmMyu3QRrw5XO2lxTIJHIC4Fm7zd+mY5hBIsDF51zLA28wOOdwFFsv ujnC4pTWHtGwINf0nHm3BFkZG7h1dViGBglRjcQIC3K7HpWTmOD83rkWgGMtdxRCsIUN xjGj/uxxLnkvTewXgesfhWKz7ExGFsasDI8MaXPh1IKJwk2lXqiYXGEGC6nvfU8anK7P svbA== X-Gm-Message-State: AOAM531VKQgvbQKMGY6p3Moqd7g8o+6/M4bbBwivRza75qS1Hg783sk9 kH6BqvRj6DcsQuJZENn+KsxAjQr1Ue0= X-Google-Smtp-Source: ABdhPJwQyNnxRbidp1WP0A3zDOzvtmBvCMR1GqKAbUw1aUlBQjOlpB5KHbRtz7JYmubaW8g4EKSV8g== X-Received: by 2002:a05:600c:22d9:: with SMTP id 25mr4051645wmg.71.1637306265561; Thu, 18 Nov 2021 23:17:45 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:45 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 3/9] fanotify: use macros to get the offset to fanotify_info buffer Date: Fri, 19 Nov 2021 09:17:32 +0200 Message-Id: <20211119071738.1348957-4-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The fanotify_info buffer contains up to two file handles and a name. Use macros to simplify the code that access the different items within the buffer. Add assertions to verify that stored fh len and name len do not overflow the u8 stored value in fanotify_info header. Remove the unused fanotify_info_len() helper. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 2 +- fs/notify/fanotify/fanotify.h | 41 +++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 9b1641ecfe97..4a812411ae5b 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -411,7 +411,7 @@ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, * be zero in that case if encoding fh len failed. */ err = -ENOENT; - if (fh_len < 4 || WARN_ON_ONCE(fh_len % 4)) + if (fh_len < 4 || WARN_ON_ONCE(fh_len % 4) || fh_len > MAX_HANDLE_SZ) goto out_err; /* No external buffer in a variable size allocated fh */ diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index d25f500bf7e7..dd23ba659e76 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -49,6 +49,22 @@ struct fanotify_info { * (optional) file_fh starts at buf[dir_fh_totlen] * name starts at buf[dir_fh_totlen + file_fh_totlen] */ +#define FANOTIFY_DIR_FH_SIZE(info) ((info)->dir_fh_totlen) +#define FANOTIFY_FILE_FH_SIZE(info) ((info)->file_fh_totlen) +#define FANOTIFY_NAME_SIZE(info) ((info)->name_len + 1) + +#define FANOTIFY_DIR_FH_OFFSET(info) 0 +#define FANOTIFY_FILE_FH_OFFSET(info) \ + (FANOTIFY_DIR_FH_OFFSET(info) + FANOTIFY_DIR_FH_SIZE(info)) +#define FANOTIFY_NAME_OFFSET(info) \ + (FANOTIFY_FILE_FH_OFFSET(info) + FANOTIFY_FILE_FH_SIZE(info)) + +#define FANOTIFY_DIR_FH_BUF(info) \ + ((info)->buf + FANOTIFY_DIR_FH_OFFSET(info)) +#define FANOTIFY_FILE_FH_BUF(info) \ + ((info)->buf + FANOTIFY_FILE_FH_OFFSET(info)) +#define FANOTIFY_NAME_BUF(info) \ + ((info)->buf + FANOTIFY_NAME_OFFSET(info)) } __aligned(4); static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) @@ -87,7 +103,7 @@ static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *inf { BUILD_BUG_ON(offsetof(struct fanotify_info, buf) % 4); - return (struct fanotify_fh *)info->buf; + return (struct fanotify_fh *)FANOTIFY_DIR_FH_BUF(info); } static inline int fanotify_info_file_fh_len(struct fanotify_info *info) @@ -101,32 +117,35 @@ static inline int fanotify_info_file_fh_len(struct fanotify_info *info) static inline struct fanotify_fh *fanotify_info_file_fh(struct fanotify_info *info) { - return (struct fanotify_fh *)(info->buf + info->dir_fh_totlen); + return (struct fanotify_fh *)FANOTIFY_FILE_FH_BUF(info); } -static inline const char *fanotify_info_name(struct fanotify_info *info) +static inline char *fanotify_info_name(struct fanotify_info *info) { - return info->buf + info->dir_fh_totlen + info->file_fh_totlen; + if (!info->name_len) + return NULL; + + return FANOTIFY_NAME_BUF(info); } static inline void fanotify_info_init(struct fanotify_info *info) { + BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN + MAX_HANDLE_SZ > U8_MAX); + BUILD_BUG_ON(NAME_MAX > U8_MAX); + info->dir_fh_totlen = 0; info->file_fh_totlen = 0; info->name_len = 0; } -static inline unsigned int fanotify_info_len(struct fanotify_info *info) -{ - return info->dir_fh_totlen + info->file_fh_totlen + info->name_len; -} - static inline void fanotify_info_copy_name(struct fanotify_info *info, const struct qstr *name) { + if (WARN_ON_ONCE(name->len > NAME_MAX)) + return; + info->name_len = name->len; - strcpy(info->buf + info->dir_fh_totlen + info->file_fh_totlen, - name->name); + strcpy(fanotify_info_name(info), name->name); } /* From patchwork Fri Nov 19 07:17:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628395 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F871C433EF for ; Fri, 19 Nov 2021 07:17:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F25861AFB for ; Fri, 19 Nov 2021 07:17:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233746AbhKSHUx (ORCPT ); Fri, 19 Nov 2021 02:20:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46008 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233716AbhKSHUt (ORCPT ); Fri, 19 Nov 2021 02:20:49 -0500 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 45420C061574 for ; Thu, 18 Nov 2021 23:17:48 -0800 (PST) Received: by mail-wm1-x32e.google.com with SMTP id r9-20020a7bc089000000b00332f4abf43fso7155370wmh.0 for ; Thu, 18 Nov 2021 23:17:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3rZBLdsgOnXEUuEzMVPJfSZkyib3Ve4bmbVA52LhnRo=; b=SxpHkYUVzyesWTin9jz8d1v7KZTMLsUkXSxSvl2HyPyDWvs5fWOBkT3t3VqdmlIrt8 z8ZFZRkwqJnP0rs+iDR4nZtiOmD3E5yUGtH/aih6CeE64Q9Dqmn3nKztBCwHmKwhozVg gvsvMHNXO0yhNQe2taUteZs9yI13Pk9dgW1TvXeLj30KdcOPZI2yTUWuUKzvYDSaJe4n iCOvNuKiuXPXHQKTWLqiEP+JuMC5r8p2/zQWkULyoiaU3rDHGeZv6Wo8jgbP70WD/Fdi n1l0byn38dBdyKxkuTD/ZaPGaU8VPZ5pArWo5horN2KCwvXu3kZwPFm8T9YjA6vJS+ju U8+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3rZBLdsgOnXEUuEzMVPJfSZkyib3Ve4bmbVA52LhnRo=; b=PKOQPFhsMbly+mWHErbufsrdy7mumGiZUgsTqjKt29ucNgWhocKKS5AnBZRHUSnZI+ M4ZWPt6yWDzJSatdRgaHo79rSK4PZOFzmEGuWEa7AT7rTyBzqOvinJUwkcfJucbbtexm y0NfimnFvM252/1k6Lf/pREB4qc2HPZoTrZW1FaWNGnClx3RnTbz/xNA/fFKK50pDLEL m+lhfATUhnHw5kh55l3ezQ6vS4XewIWREMYG0x2lMT4aM4LUmkUprDQq3sV2Ava5q0u3 9gWKlB0H1hiE582OoW9R2aByNjSSMI5AGhiFyVba1sYhGuJHZrM4WoMlm9bUoNZHfDQu y3Lw== X-Gm-Message-State: AOAM531JoLwIQq8TcMj7pZudOAaSqarjwS3rl3V2dvaDHnYqWWOefaq5 2qXTj/8YYiMe11q1iglN7H0/B5yRZIY= X-Google-Smtp-Source: ABdhPJxmZg5Tdg7zEngo3xDib7lX/pnkwOejpyhrpNVk4wR0e8gklDrgh6zvQZqExoDgvXQrj4HGmg== X-Received: by 2002:a1c:1941:: with SMTP id 62mr3997465wmz.131.1637306266858; Thu, 18 Nov 2021 23:17:46 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:46 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 4/9] fanotify: use helpers to parcel fanotify_info buffer Date: Fri, 19 Nov 2021 09:17:33 +0200 Message-Id: <20211119071738.1348957-5-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org fanotify_info buffer is parceled into variable sized records, so the records must be written in order: dir_fh, file_fh, name. Use helpers to assert that order and make fanotify_alloc_name_event() a bit more generic to allow empty dir_fh record and to allow expanding to more records (i.e. name2) soon. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 35 +++++++++++++++++++---------------- fs/notify/fanotify/fanotify.h | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 4a812411ae5b..a274f57726dd 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -576,7 +576,7 @@ static struct fanotify_event *fanotify_alloc_fid_event(struct inode *id, return &ffe->fae; } -static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, +static struct fanotify_event *fanotify_alloc_name_event(struct inode *dir, __kernel_fsid_t *fsid, const struct qstr *name, struct inode *child, @@ -586,15 +586,17 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, struct fanotify_name_event *fne; struct fanotify_info *info; struct fanotify_fh *dfh, *ffh; - unsigned int dir_fh_len = fanotify_encode_fh_len(id); + unsigned int dir_fh_len = fanotify_encode_fh_len(dir); unsigned int child_fh_len = fanotify_encode_fh_len(child); - unsigned int size; + unsigned long name_len = name ? name->len : 0; + unsigned int len, size; - size = sizeof(*fne) + FANOTIFY_FH_HDR_LEN + dir_fh_len; + /* Reserve terminating null byte even for empty name */ + size = sizeof(*fne) + name_len + 1; + if (dir_fh_len) + size += FANOTIFY_FH_HDR_LEN + dir_fh_len; if (child_fh_len) size += FANOTIFY_FH_HDR_LEN + child_fh_len; - if (name) - size += name->len + 1; fne = kmalloc(size, gfp); if (!fne) return NULL; @@ -604,22 +606,23 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, *hash ^= fanotify_hash_fsid(fsid); info = &fne->info; fanotify_info_init(info); - dfh = fanotify_info_dir_fh(info); - info->dir_fh_totlen = fanotify_encode_fh(dfh, id, dir_fh_len, hash, 0); + if (dir_fh_len) { + dfh = fanotify_info_dir_fh(info); + len = fanotify_encode_fh(dfh, dir, dir_fh_len, hash, 0); + fanotify_info_set_dir_fh(info, len); + } if (child_fh_len) { ffh = fanotify_info_file_fh(info); - info->file_fh_totlen = fanotify_encode_fh(ffh, child, - child_fh_len, hash, 0); + len = fanotify_encode_fh(ffh, child, child_fh_len, hash, 0); + fanotify_info_set_file_fh(info, len); } - if (name) { - long salt = name->len; - + if (name_len) { fanotify_info_copy_name(info, name); - *hash ^= full_name_hash((void *)salt, name->name, name->len); + *hash ^= full_name_hash((void *)name_len, name->name, name_len); } - pr_debug("%s: ino=%lu size=%u dir_fh_len=%u child_fh_len=%u name_len=%u name='%.*s'\n", - __func__, id->i_ino, size, dir_fh_len, child_fh_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)); return &fne->fae; diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index dd23ba659e76..7ac6f9f1e414 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -138,6 +138,26 @@ static inline void fanotify_info_init(struct fanotify_info *info) info->name_len = 0; } +/* These set/copy helpers MUST be called by order */ +static inline void fanotify_info_set_dir_fh(struct fanotify_info *info, + unsigned int totlen) +{ + if (WARN_ON_ONCE(info->file_fh_totlen > 0) || + WARN_ON_ONCE(info->name_len > 0)) + return; + + info->dir_fh_totlen = totlen; +} + +static inline void fanotify_info_set_file_fh(struct fanotify_info *info, + unsigned int totlen) +{ + if (WARN_ON_ONCE(info->name_len > 0)) + return; + + info->file_fh_totlen = totlen; +} + static inline void fanotify_info_copy_name(struct fanotify_info *info, const struct qstr *name) { From patchwork Fri Nov 19 07:17:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628397 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DBA2C4332F for ; Fri, 19 Nov 2021 07:17:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 17CEF61AFB for ; Fri, 19 Nov 2021 07:17:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233720AbhKSHUz (ORCPT ); Fri, 19 Nov 2021 02:20:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233725AbhKSHUv (ORCPT ); Fri, 19 Nov 2021 02:20:51 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CFDBEC061574 for ; Thu, 18 Nov 2021 23:17:49 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id c71-20020a1c9a4a000000b0032cdcc8cbafso6718355wme.3 for ; Thu, 18 Nov 2021 23:17:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=J39aaDexhztw7oyBWU3wiRKPDiup181acFLjJmms/nw=; b=gktTQsHc9Vtv/5DQP+8EUraXSPLgSCTBoK4vR62qN+DPIrAXrTWBMQgIoCWY+lqGi+ P9xGVlSz8H/A4w+BnnSTbzVvhpkxTTzOxIiqC9T47aDzlPaIbKVlmQWtHpoFC0WYfne2 fmzXXeg5qTsaMP4j+GRe+M1G6MN2OB7phiAdYOs0ESqX0ipmbWCv6bjFzTYJAXMmEtnv wML2mQhvycpR9SODCXT+p98gFfx3RPXcbSmVCvfqODyUxBbls19OAi1O+GzCEhpTalyk umdAl0uDGgN4jmEGtbranZxNcus/wrZ7qgKw9AU+ppjTSOcFJOwuo9t81DlsrBZVl3kA aRyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=J39aaDexhztw7oyBWU3wiRKPDiup181acFLjJmms/nw=; b=5hBrZ1/797Mku05j2+o95bvPIum2XDcbKqsVcsC0Nd3M0M5hsy8oYJTGactEiXfAwF xr0EADItSXh2RSR7bTvW0wOIJq2fpe7FXaMeqtN8phcICSP20snwSkQnMdTpxSx0133+ 2unF1LHrX0bEKsaEkfH3G87WG5Gl6Xq9eBawQCGVgeM6eXHMS5QaUXn4yrQ0QZsrdrAj usy7c1nUC8inSO9+BFM8g4HxcZs8frPuxy+xvdMmwutrDnrBygHCvA+7i7GouEYXQmov wPVtmXR3xSdQC7T4l4W1D1PsE5r1BB/JBdC0C8/VOGS4EP+I+8AgYOxBAz00kEukmxg1 JxnQ== X-Gm-Message-State: AOAM5313vXZgszx9DC/dyHIiePQUM+rQPQSPqC5hfCfxuUpcUBFjpzOo NcUs4m6bB3bWV8M2qALpFc0= X-Google-Smtp-Source: ABdhPJxZq/a/vNaTlPZhJAryMszMFMT2XaS/VgUw03N2NTH9A1sCi0R2Z8/O561PSm/7pg7LYBfv4g== X-Received: by 2002:a7b:cf35:: with SMTP id m21mr4074102wmg.140.1637306268384; Thu, 18 Nov 2021 23:17:48 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:47 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 5/9] fanotify: support secondary dir fh and name in fanotify_info Date: Fri, 19 Nov 2021 09:17:34 +0200 Message-Id: <20211119071738.1348957-6-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Allow storing a secondary dir fh and name tupple in fanotify_info. This will be used to store the new parent and name information in FAN_RENAME event. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 20 ++++++-- fs/notify/fanotify/fanotify.h | 79 +++++++++++++++++++++++++++--- fs/notify/fanotify/fanotify_user.c | 3 +- 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index a274f57726dd..447e97396c58 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -76,8 +76,10 @@ static bool fanotify_info_equal(struct fanotify_info *info1, struct fanotify_info *info2) { if (info1->dir_fh_totlen != info2->dir_fh_totlen || + info1->dir2_fh_totlen != info2->dir2_fh_totlen || info1->file_fh_totlen != info2->file_fh_totlen || - info1->name_len != info2->name_len) + info1->name_len != info2->name_len || + info1->name2_len != info2->name2_len) return false; if (info1->dir_fh_totlen && @@ -85,14 +87,24 @@ static bool fanotify_info_equal(struct fanotify_info *info1, fanotify_info_dir_fh(info2))) return false; + if (info1->dir2_fh_totlen && + !fanotify_fh_equal(fanotify_info_dir2_fh(info1), + fanotify_info_dir2_fh(info2))) + return false; + if (info1->file_fh_totlen && !fanotify_fh_equal(fanotify_info_file_fh(info1), fanotify_info_file_fh(info2))) return false; - return !info1->name_len || - !memcmp(fanotify_info_name(info1), fanotify_info_name(info2), - info1->name_len); + if (info1->name_len && + memcmp(fanotify_info_name(info1), fanotify_info_name(info2), + info1->name_len)) + return false; + + return !info1->name2_len || + !memcmp(fanotify_info_name2(info1), fanotify_info_name2(info2), + info1->name2_len); } static bool fanotify_name_event_equal(struct fanotify_name_event *fne1, diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 7ac6f9f1e414..8fa3bc0effd4 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -40,31 +40,45 @@ struct fanotify_fh { struct fanotify_info { /* size of dir_fh/file_fh including fanotify_fh hdr size */ u8 dir_fh_totlen; + u8 dir2_fh_totlen; u8 file_fh_totlen; u8 name_len; - u8 pad; + u8 name2_len; + u8 pad[3]; unsigned char buf[]; /* * (struct fanotify_fh) dir_fh starts at buf[0] - * (optional) file_fh starts at buf[dir_fh_totlen] - * name starts at buf[dir_fh_totlen + file_fh_totlen] + * (optional) dir2_fh starts at buf[dir_fh_totlen] + * (optional) file_fh starts at buf[dir_fh_totlen + dir2_fh_totlen] + * name starts at buf[dir_fh_totlen + dir2_fh_totlen + file_fh_totlen] + * ... */ #define FANOTIFY_DIR_FH_SIZE(info) ((info)->dir_fh_totlen) +#define FANOTIFY_DIR2_FH_SIZE(info) ((info)->dir2_fh_totlen) #define FANOTIFY_FILE_FH_SIZE(info) ((info)->file_fh_totlen) #define FANOTIFY_NAME_SIZE(info) ((info)->name_len + 1) +#define FANOTIFY_NAME2_SIZE(info) ((info)->name2_len + 1) #define FANOTIFY_DIR_FH_OFFSET(info) 0 -#define FANOTIFY_FILE_FH_OFFSET(info) \ +#define FANOTIFY_DIR2_FH_OFFSET(info) \ (FANOTIFY_DIR_FH_OFFSET(info) + FANOTIFY_DIR_FH_SIZE(info)) +#define FANOTIFY_FILE_FH_OFFSET(info) \ + (FANOTIFY_DIR2_FH_OFFSET(info) + FANOTIFY_DIR2_FH_SIZE(info)) #define FANOTIFY_NAME_OFFSET(info) \ (FANOTIFY_FILE_FH_OFFSET(info) + FANOTIFY_FILE_FH_SIZE(info)) +#define FANOTIFY_NAME2_OFFSET(info) \ + (FANOTIFY_NAME_OFFSET(info) + FANOTIFY_NAME_SIZE(info)) #define FANOTIFY_DIR_FH_BUF(info) \ ((info)->buf + FANOTIFY_DIR_FH_OFFSET(info)) +#define FANOTIFY_DIR2_FH_BUF(info) \ + ((info)->buf + FANOTIFY_DIR2_FH_OFFSET(info)) #define FANOTIFY_FILE_FH_BUF(info) \ ((info)->buf + FANOTIFY_FILE_FH_OFFSET(info)) #define FANOTIFY_NAME_BUF(info) \ ((info)->buf + FANOTIFY_NAME_OFFSET(info)) +#define FANOTIFY_NAME2_BUF(info) \ + ((info)->buf + FANOTIFY_NAME2_OFFSET(info)) } __aligned(4); static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) @@ -106,6 +120,20 @@ static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *inf return (struct fanotify_fh *)FANOTIFY_DIR_FH_BUF(info); } +static inline int fanotify_info_dir2_fh_len(struct fanotify_info *info) +{ + if (!info->dir2_fh_totlen || + WARN_ON_ONCE(info->dir2_fh_totlen < FANOTIFY_FH_HDR_LEN)) + return 0; + + return info->dir2_fh_totlen - FANOTIFY_FH_HDR_LEN; +} + +static inline struct fanotify_fh *fanotify_info_dir2_fh(struct fanotify_info *info) +{ + return (struct fanotify_fh *)FANOTIFY_DIR2_FH_BUF(info); +} + static inline int fanotify_info_file_fh_len(struct fanotify_info *info) { if (!info->file_fh_totlen || @@ -128,31 +156,55 @@ static inline char *fanotify_info_name(struct fanotify_info *info) return FANOTIFY_NAME_BUF(info); } +static inline char *fanotify_info_name2(struct fanotify_info *info) +{ + if (!info->name2_len) + return NULL; + + return FANOTIFY_NAME2_BUF(info); +} + static inline void fanotify_info_init(struct fanotify_info *info) { BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN + MAX_HANDLE_SZ > U8_MAX); BUILD_BUG_ON(NAME_MAX > U8_MAX); info->dir_fh_totlen = 0; + info->dir2_fh_totlen = 0; info->file_fh_totlen = 0; info->name_len = 0; + info->name2_len = 0; } /* These set/copy helpers MUST be called by order */ static inline void fanotify_info_set_dir_fh(struct fanotify_info *info, unsigned int totlen) { - if (WARN_ON_ONCE(info->file_fh_totlen > 0) || - WARN_ON_ONCE(info->name_len > 0)) + if (WARN_ON_ONCE(info->dir2_fh_totlen > 0) || + WARN_ON_ONCE(info->file_fh_totlen > 0) || + WARN_ON_ONCE(info->name_len > 0) || + WARN_ON_ONCE(info->name2_len > 0)) return; info->dir_fh_totlen = totlen; } +static inline void fanotify_info_set_dir2_fh(struct fanotify_info *info, + unsigned int totlen) +{ + if (WARN_ON_ONCE(info->file_fh_totlen > 0) || + WARN_ON_ONCE(info->name_len > 0) || + WARN_ON_ONCE(info->name2_len > 0)) + return; + + info->dir2_fh_totlen = totlen; +} + static inline void fanotify_info_set_file_fh(struct fanotify_info *info, unsigned int totlen) { - if (WARN_ON_ONCE(info->name_len > 0)) + if (WARN_ON_ONCE(info->name_len > 0) || + WARN_ON_ONCE(info->name2_len > 0)) return; info->file_fh_totlen = totlen; @@ -161,13 +213,24 @@ static inline void fanotify_info_set_file_fh(struct fanotify_info *info, static inline void fanotify_info_copy_name(struct fanotify_info *info, const struct qstr *name) { - if (WARN_ON_ONCE(name->len > NAME_MAX)) + if (WARN_ON_ONCE(name->len > NAME_MAX) || + WARN_ON_ONCE(info->name2_len > 0)) return; info->name_len = name->len; strcpy(fanotify_info_name(info), name->name); } +static inline void fanotify_info_copy_name2(struct fanotify_info *info, + const struct qstr *name) +{ + if (WARN_ON_ONCE(name->len > NAME_MAX)) + return; + + info->name2_len = name->len; + strcpy(fanotify_info_name2(info), name->name); +} + /* * Common structure for fanotify events. Concrete structs are allocated in * fanotify_handle_event() and freed when the information is retrieved by diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 0ade5031733d..ba72e49819f1 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -332,11 +332,10 @@ static int process_access_response(struct fsnotify_group *group, static size_t copy_error_info_to_user(struct fanotify_event *event, char __user *buf, int count) { - struct fanotify_event_info_error info; + struct fanotify_event_info_error info = { }; struct fanotify_error_event *fee = FANOTIFY_EE(event); info.hdr.info_type = FAN_EVENT_INFO_TYPE_ERROR; - info.hdr.pad = 0; info.hdr.len = FANOTIFY_ERROR_INFO_LEN; if (WARN_ON(count < info.hdr.len)) From patchwork Fri Nov 19 07:17:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628399 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86E29C433F5 for ; Fri, 19 Nov 2021 07:17:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 735A761AFB for ; Fri, 19 Nov 2021 07:17:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233742AbhKSHUz (ORCPT ); Fri, 19 Nov 2021 02:20:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233770AbhKSHUz (ORCPT ); Fri, 19 Nov 2021 02:20:55 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37AC2C061574 for ; Thu, 18 Nov 2021 23:17:53 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id r8so16390989wra.7 for ; Thu, 18 Nov 2021 23:17:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QLctcL5T46VkqjthcDRiuvoVOo5U7FB4/ucokOl9sTA=; b=YIQJAHV4/yC+fhhV1l1BxtoSsdLNgPIZ8Uz8ZCq6SzrPtLsLT9Fh6jt0z9xGFjYsKc gZW46s9g64jrifSEZkuhKJ8jK3ciglPMYJxP1zqbw9fKdStFq/3rhZYXorgFM/QwB+Hi AZaXttOVjlRTizcLD1uOzFQBRSpfr4tLxk3AGbV3yYKNNA8TZXnyME0Xssrj2mTLHfYd AQdLce8UA1Xj9yQtJ5Q7JcDkz1MnwnT1v/1MF1EDpl9pxNMfU4mau3H5p9cwLiUl5UCw 1HjwZthLsRWMQCk/z+Z9vg+oRlNVnt3xJBR6H3j7FqDWwqExg4SpNGhoulXrA9SBCBiI UasQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QLctcL5T46VkqjthcDRiuvoVOo5U7FB4/ucokOl9sTA=; b=7wgrZRgpNERiEk+Q0gu3wGjLY4C/7IETM5z2Ttl/GIhM4fZypr27/lXBPDjQXlHYzP gSyaChGL0snFWfbGwMowhWQODkvjKp/C+R/OiwuXrNEbLZkmxDZLUCm8KB8c13UCP00W TGLWcb6RI4+25PcW7F0UXA8/cpxrQ3k4BNr0cCDun7hw1T+FE+6U+KPkiy4rf8Y4QQb3 u+av4nHdgTY9a6Y0hd2oKmZxAH+dOPaM7lVZTF4mF4UhAn5RcwsE9OFECqh6Y4nTW7M7 p/QP4LOhuCbVz0pe1Lc2OSykITR4ZuICvAs1Dx7noBEnTM75YxVd7X4ySvJvd7pAgSJh +1lw== X-Gm-Message-State: AOAM531/MRJlMyQr80hmOG9eu1/0NgZE1PA7hV3NYfL3Ovk0KmTwHleB QaAKRn/2oa9CE2O1y6c6Ftvcxx7EayA= X-Google-Smtp-Source: ABdhPJwUNOgbuzXU7bxbDE3waOskf63VN/SQcdkyJq2vvndShjM2prTga5Xoi+RbIuIFiZvV4CvwIw== X-Received: by 2002:a5d:4e52:: with SMTP id r18mr4391304wrt.224.1637306271806; Thu, 18 Nov 2021 23:17:51 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:51 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , 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 Message-Id: <20211119071738.1348957-7-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In the special case of FAN_RENAME event, we record both the old and new parent and name. Signed-off-by: Amir Goldstein --- 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 */ From patchwork Fri Nov 19 07:17:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628401 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F6FDC433FE for ; Fri, 19 Nov 2021 07:17:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 485A861AFB for ; Fri, 19 Nov 2021 07:17:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233775AbhKSHU4 (ORCPT ); Fri, 19 Nov 2021 02:20:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233725AbhKSHUz (ORCPT ); Fri, 19 Nov 2021 02:20:55 -0500 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5AC9BC061574 for ; Thu, 18 Nov 2021 23:17:54 -0800 (PST) Received: by mail-wm1-x336.google.com with SMTP id y196so7557349wmc.3 for ; Thu, 18 Nov 2021 23:17:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4OQYxFBCXONbiG6AxXy9dYO5XcrX6u9dgMZf1tvq0b0=; b=gJm/UfinY+s+jqANvGQowSjy5dCenFyyNlentFy/WfP6+HoMQVqPC/B+ghnnkVrsd6 b7LpTbXW8haoMWstt8N4hMzqSRWEXWRLALpzA0Iuip2I6bjKKF3ut+La8TSYY3y4xn/E Xa29/KEm6peK+zhXkHL0zoCXhl2y4KZppbrofDNefR5vfYR+AxRIuPeJO8nhTj5Wl6Or rsGamH2H1VhD4DwGEBCfEacgi4fktWKHymrMsLeW+uGYzGkz+WRG62X2je6zcs9DKa04 7jMi9nVobvEzxasxNeJatAqDGaox6qBtBbYTc7CCEgil/fXEmXSs+UX8+10zIXfmseX9 qL4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4OQYxFBCXONbiG6AxXy9dYO5XcrX6u9dgMZf1tvq0b0=; b=1y/EedQ4FfmHb83HLBqptMxWZfpbmf0frmorXGkoULzQ+0S1ZseaAYwMNVF8ZoHLHi zQsVR3eIgWOepPTGODwgF8hmHMoqDg4DlekHzB+tSlCATTAQxMTmK5UmB56DKk7w1wGE yi85BQlmn7eHzY8IoA8OMd7k+b0VUDuBUw4GvAwThU+jQWCoQDbhakAoBVB1p9RqgDD4 RdiSKGvztmRFohmmPcddq0IId2ccdUg0NMgDfcZPSoGdze/hMsyVUXt0Hf6kWA11Gd/o elyjSd7QQUwHU8t3EAv9/ndcOIVcC3DnyWBRVaJWs2oxrymnp+i9/23pMsBJGPDZC0Yz 1d1g== X-Gm-Message-State: AOAM532zrmPEGzc9exWn0+BqXXlY8Sa/sXfQ6HuK6K5XLFDTDezoolYn y4qjmvDXB08B8zpkzNgIxtk= X-Google-Smtp-Source: ABdhPJwGCsTs4LgBRKTo/Engp0KP7hlXObsNKGR5MHa+FxRX/We8xEpHxu13u8Ch443BnNAvlAuIGg== X-Received: by 2002:a05:600c:4108:: with SMTP id j8mr4140098wmi.139.1637306272878; Thu, 18 Nov 2021 23:17:52 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:52 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 7/9] fanotify: record either old name new name or both for FAN_RENAME Date: Fri, 19 Nov 2021 09:17:36 +0200 Message-Id: <20211119071738.1348957-8-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We do not want to report the dirfid+name of a directory whose inode/sb are not watched, because watcher may not have permissions to see the directory content. The FAN_MOVED_FROM/TO flags are used internally to indicate to fanotify_alloc_event() if we need to record only the old parent+name, only the new parent+name or both. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 57 ++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 018b32a57702..c0a3fb1dd066 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -290,6 +290,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, __u32 marks_mask = 0, marks_ignored_mask = 0; __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS | FANOTIFY_EVENT_FLAGS; + __u32 moved_mask = 0; const struct path *path = fsnotify_data_path(data, data_type); unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); struct fsnotify_mark *mark; @@ -327,17 +328,44 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, continue; /* - * If the event is on a child and this mark is on a parent not - * watching children, don't send it! + * In the special case of FAN_RENAME event, inode mark is the + * mark on the old dir and parent mark is the mark on the new + * dir. We do not want to report the dirfid+name of a directory + * whose inode/sb are not watched. The FAN_MOVE flags + * are used internally to indicate if we need to report only + * the old parent+name, only the new parent+name or both. */ - if (type == FSNOTIFY_OBJ_TYPE_PARENT && - !(mark->mask & FS_EVENT_ON_CHILD)) + if (event_mask & FAN_RENAME) { + /* Old dir sb are watched - report old info */ + if (type != FSNOTIFY_OBJ_TYPE_PARENT && + (mark->mask & FAN_RENAME)) + moved_mask |= FAN_MOVED_FROM; + /* New dir sb are watched - report new info */ + if (type != FSNOTIFY_OBJ_TYPE_INODE && + (mark->mask & FAN_RENAME)) + moved_mask |= FAN_MOVED_TO; + } else if (type == FSNOTIFY_OBJ_TYPE_PARENT && + !(mark->mask & FS_EVENT_ON_CHILD)) { + /* + * If the event is on a child and this mark is on + * a parent not watching children, don't send it! + */ continue; + } marks_mask |= mark->mask; } test_mask = event_mask & marks_mask & ~marks_ignored_mask; + /* + * Add the internal FAN_MOVE flags to FAN_RENAME event. + * They will not be reported to user along with FAN_RENAME. + */ + if (test_mask & FAN_RENAME) { + if (WARN_ON_ONCE(test_mask & FAN_MOVE)) + return 0; + test_mask |= moved_mask; + } /* * For dirent modification events (create/delete/move) that do not carry @@ -753,13 +781,28 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, } /* - * In the special case of FAN_RENAME event, we record both - * old and new parent+name. + * In the special case of FAN_RENAME event, the FAN_MOVE flags + * are only used internally to indicate if we need to report + * only the old parent+name, only the new parent+name or both. * '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); + /* Either old and/or new info must be reported */ + if (WARN_ON_ONCE(!(mask & FAN_MOVE))) + return NULL; + + if (!(mask & FAN_MOVED_FROM)) { + /* Do not report old parent+name */ + dirid = NULL; + file_name = NULL; + } + if (mask & FAN_MOVED_TO) { + /* Report new parent+name */ + moved = fsnotify_data_dentry(data, data_type); + } + /* Clear internal flags */ + mask &= ~FAN_MOVE; name_event = true; } } From patchwork Fri Nov 19 07:17:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628403 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD25AC433EF for ; Fri, 19 Nov 2021 07:17:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9685861B04 for ; Fri, 19 Nov 2021 07:17:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233781AbhKSHU6 (ORCPT ); Fri, 19 Nov 2021 02:20:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233721AbhKSHU5 (ORCPT ); Fri, 19 Nov 2021 02:20:57 -0500 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C08C0C061574 for ; Thu, 18 Nov 2021 23:17:55 -0800 (PST) Received: by mail-wm1-x32d.google.com with SMTP id g191-20020a1c9dc8000000b0032fbf912885so6724529wme.4 for ; Thu, 18 Nov 2021 23:17:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OU8HHTRykLCD6sM7gHw1h3Vmry3Tv1Z13eRE57f+m9M=; b=DTFvyBN40JiwmX1TENllhxwgU2BMDPL/bU7IV6wrh+H9OTfxw9cVwmVGOw5vkD6pQY smRnkupNVxZyxapXxOsVUfO9e9P3owpIT7GQEgg12GfGMRusw0tUzPuBhpEW8PDFcL7l DIjRpbsKsduETcMW8jHXhFYia4iWnURf0jSBsNdKdZq7azxHqSWTYGyuLZ0ctH0VlRf/ 68jpf19JlMmOAGk4YA1y3WIt5bqp+kFjO90OQEczEOiW2/CYEp0I13fP/+9A0rG/2qDb 625qUc0iveVh9OEVlHWGkNYNiG/GOD7C14YXkDhQvS+Vesf9RuT6eFZDu9vt2awL3Qxe SOEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OU8HHTRykLCD6sM7gHw1h3Vmry3Tv1Z13eRE57f+m9M=; b=5T0jV4uYhgCWNuj8CRf3cegvsIgqRYWowScJ/ygbDVQDd0S2ONy8Dbf6iB8rKa+5IL bI02AX1Oyt0wXiE7cA68Vq7/RghaDLL0CQ8hSxH7eapC/RvDszs56+JEWpJZrp0onvFS PvBrVquyQwj+w12vsewOhVEa/Dn+TYFPD2fimyjfcPjuOaxOHMWrOA999Y/eDGvE5YK8 bnZcqMXo/mlwdp+nq/wx0Cgm2JZ8siYwHmAlWUt7aHUngUygzUSKy+0bh8s5cQ93jOQO 9/vHizO3FLldiWznEYR5Om0scRZStHtVXkLpT7WKM02d0I0hpPOfFsXiY8iK6sS7+nny CCHQ== X-Gm-Message-State: AOAM532FgWu5fzqAZDy8Rg/Bg0uH6xCFn9Xe+ia+Yk1XFbe4ndrlAlZV NG/5UjjII4MmbgSaGzE73Bs= X-Google-Smtp-Source: ABdhPJyyekg7B16QETIJjSNCXhFaAZzZYj93qh011Du02ksfaflIev+jYG8PERjyPlv7gkv/3FmckA== X-Received: by 2002:a7b:c764:: with SMTP id x4mr4212820wmk.78.1637306274361; Thu, 18 Nov 2021 23:17:54 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:53 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 8/9] fanotify: report old and/or new parent+name in FAN_RENAME event Date: Fri, 19 Nov 2021 09:17:37 +0200 Message-Id: <20211119071738.1348957-9-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In the special case of FAN_RENAME event, we report old or new or both old and new parent+name. A single info record will be reported if either the old or new dir is watched and two records will be reported if both old and new dir (or their filesystem) are watched. The old and new parent+name are reported using new info record types FAN_EVENT_INFO_TYPE_{OLD,NEW}_DFID_NAME, so if a single info record is reported, it is clear to the application, to which dir entry the fid+name info is referring to. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 7 ++++ fs/notify/fanotify/fanotify.h | 18 ++++++++++ fs/notify/fanotify/fanotify_user.c | 53 +++++++++++++++++++++++++++--- include/uapi/linux/fanotify.h | 6 ++++ 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index c0a3fb1dd066..4f06b17e209d 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -153,6 +153,13 @@ static bool fanotify_should_merge(struct fanotify_event *old, if ((old->mask & FS_ISDIR) != (new->mask & FS_ISDIR)) return false; + /* + * FAN_RENAME event is reported with special info record types, + * so we cannot merge it with other events. + */ + if ((old->mask & FAN_RENAME) != (new->mask & FAN_RENAME)) + return false; + switch (old->type) { case FANOTIFY_EVENT_TYPE_PATH: return fanotify_path_equal(fanotify_event_path(old), diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 8fa3bc0effd4..a3d5b751cac5 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -373,6 +373,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. */ @@ -386,6 +393,17 @@ static inline bool fanotify_event_has_dir_fh(struct fanotify_event *event) return fanotify_event_dir_fh_len(event) > 0; } +static inline bool fanotify_event_has_dir2_fh(struct fanotify_event *event) +{ + return fanotify_event_dir2_fh_len(event) > 0; +} + +static inline bool fanotify_event_has_any_dir_fh(struct fanotify_event *event) +{ + return fanotify_event_has_dir_fh(event) || + fanotify_event_has_dir2_fh(event); +} + 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 ba72e49819f1..5ec60db3cfbb 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -129,12 +129,29 @@ static int fanotify_fid_info_len(int fh_len, int name_len) FANOTIFY_EVENT_ALIGN); } +/* FAN_RENAME may have one or two dir+name info records */ +static int fanotify_dir_name_info_len(struct fanotify_event *event) +{ + struct fanotify_info *info = fanotify_event_info(event); + int dir_fh_len = fanotify_event_dir_fh_len(event); + int dir2_fh_len = fanotify_event_dir2_fh_len(event); + int info_len = 0; + + if (dir_fh_len) + info_len += fanotify_fid_info_len(dir_fh_len, + info->name_len); + if (dir2_fh_len) + info_len += fanotify_fid_info_len(dir2_fh_len, + info->name2_len); + + return info_len; +} + static size_t fanotify_event_len(unsigned int info_mode, struct fanotify_event *event) { size_t event_len = FAN_EVENT_METADATA_LEN; struct fanotify_info *info; - int dir_fh_len; int fh_len; int dot_len = 0; @@ -146,9 +163,8 @@ static size_t fanotify_event_len(unsigned int info_mode, info = fanotify_event_info(event); - 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_any_dir_fh(event)) { + event_len += fanotify_dir_name_info_len(event); } else if ((info_mode & FAN_REPORT_NAME) && (event->mask & FAN_ONDIR)) { /* @@ -163,6 +179,7 @@ static size_t fanotify_event_len(unsigned int info_mode, if (fanotify_event_has_object_fh(event)) { fh_len = fanotify_event_object_fh_len(event); + event_len += fanotify_fid_info_len(fh_len, dot_len); } @@ -379,6 +396,8 @@ 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_OLD_DFID_NAME: + case FAN_EVENT_INFO_TYPE_NEW_DFID_NAME: if (WARN_ON_ONCE(!name || !name_len)) return -EFAULT; break; @@ -478,11 +497,19 @@ 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 : FAN_EVENT_INFO_TYPE_DFID; + + /* FAN_RENAME uses special info types */ + if (event->mask & FAN_RENAME) + info_type = FAN_EVENT_INFO_TYPE_OLD_DFID_NAME; + ret = copy_fid_info_to_user(fanotify_event_fsid(event), fanotify_info_dir_fh(info), info_type, @@ -496,6 +523,22 @@ static int copy_info_records_to_user(struct fanotify_event *event, total_bytes += ret; } + /* New dir fid+name may be reported in addition to old dir fid+name */ + if (fanotify_event_has_dir2_fh(event)) { + info_type = FAN_EVENT_INFO_TYPE_NEW_DFID_NAME; + 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 9d0e2dc5767b..e8ac38cc2fd6 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -134,6 +134,12 @@ struct fanotify_event_metadata { #define FAN_EVENT_INFO_TYPE_PIDFD 4 #define FAN_EVENT_INFO_TYPE_ERROR 5 +/* Special info types for FAN_RENAME */ +#define FAN_EVENT_INFO_TYPE_OLD_DFID_NAME 10 +/* Reserved for FAN_EVENT_INFO_TYPE_OLD_DFID 11 */ +#define FAN_EVENT_INFO_TYPE_NEW_DFID_NAME 12 +/* Reserved for FAN_EVENT_INFO_TYPE_NEW_DFID 13 */ + /* Variable length info record following event metadata */ struct fanotify_event_info_header { __u8 info_type; From patchwork Fri Nov 19 07:17:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 12628405 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57D6BC433EF for ; Fri, 19 Nov 2021 07:18:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 41B5961AFB for ; Fri, 19 Nov 2021 07:18:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233852AbhKSHVC (ORCPT ); Fri, 19 Nov 2021 02:21:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233803AbhKSHU7 (ORCPT ); Fri, 19 Nov 2021 02:20:59 -0500 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BCFDC06173E for ; Thu, 18 Nov 2021 23:17:58 -0800 (PST) Received: by mail-wr1-x429.google.com with SMTP id b12so16413835wrh.4 for ; Thu, 18 Nov 2021 23:17:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nFGb18pBC9MBpjQaAVm5hqQdk6D4Ir2REv4FVUlaigw=; b=CJ7bKrQNzHwFOLCxyr6Eqedny+jYVFlV7e59I/83ia+MFeAx3GbonEE7TENZXok+c/ pRqYPYl0QEWuMVAL6oHmF7Khqlz+U/U5yZjI8LTXfZKg8gzRy/SV5MyFzmxDsgZxde4+ y3ey9UdRXqUVio6sOOFof1ehJTF1jXEiir+eh7xdg0Nj/2LooSVhRgQpI5HLTRtrGLuk 4yagv2rGL850wvQ83ZOdNWV9kN2E+lgw6Pfu+9XM8hNHt2LncZLbiBU3ic6FcE/egzxK 2NvGgCCBnvNQdFXQwXTBpVr/Rj62jvJLltzbm6LfFZORSA8LREIBaZmGdYkg/aQeWv92 qTBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nFGb18pBC9MBpjQaAVm5hqQdk6D4Ir2REv4FVUlaigw=; b=flXEaJ6l8Oj0YAI8xz4+0fSjl24jarR6/p7GpgFKQhdXGEji4LSp193qjFJwqELfSO 15Qq171thlCnk03M5l//Zd062egaCPTnwErbUFUZvqB/S97lWFFRvvSpvvSY2wGTEGyV IVAge8sYMluM2wnDKtApWtRfYBIItb8zisnAd4y6OKsOljKFTMapDKw9OV4ta/WS232d kjqwQxIXNSmi3dalH4Iy8NNI5lvCknn/QldKPX9nvhqIg9O8MXY2YFKgPBRCsTsDcMOT hKyBzSvnIfneuJpdApuYIS3S7AmY0Qw2sQ3lyIDAwSdarQNM7QGLdqw75vrinidQj2a6 LPHQ== X-Gm-Message-State: AOAM532FWEq6P1RieIacLjdPzFPZApjmsqVPWEGONLmX6CB8v7Z58Ge1 4zstBtLk6dHZ334MaV/M7KI= X-Google-Smtp-Source: ABdhPJzCDdWDi9I29AcfAP5Stctg0fjCL0rpB2As/qrT2SB5t60xKU+CxmhDuR7XNQPsudJFBDjLzA== X-Received: by 2002:a5d:548f:: with SMTP id h15mr4606923wrv.99.1637306276651; Thu, 18 Nov 2021 23:17:56 -0800 (PST) Received: from localhost.localdomain ([82.114.45.86]) by smtp.gmail.com with ESMTPSA id l22sm1905913wmp.34.2021.11.18.23.17.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Nov 2021 23:17:56 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v2 9/9] fanotify: wire up FAN_RENAME event Date: Fri, 19 Nov 2021 09:17:38 +0200 Message-Id: <20211119071738.1348957-10-amir73il@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211119071738.1348957-1-amir73il@gmail.com> References: <20211119071738.1348957-1-amir73il@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org FAN_RENAME is the successor of FAN_MOVED_FROM and FAN_MOVED_TO and can be used to get the old and new parent+name information in a single event. FAN_MOVED_FROM and FAN_MOVED_TO are still supported for backward compatibility, but it makes little sense to use them together with FAN_RENAME in the same group. FAN_RENAME uses special info type records to report the old and new parent+name, so reporting only old and new parent id is less useful and was not implemented. Therefore, FAN_REANAME requires a group with flag FAN_REPORT_NAME. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 2 +- fs/notify/fanotify/fanotify_user.c | 8 ++++++++ include/linux/fanotify.h | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 4f06b17e209d..072fb0f0c941 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -947,7 +947,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask, BUILD_BUG_ON(FAN_FS_ERROR != FS_ERROR); BUILD_BUG_ON(FAN_RENAME != FS_RENAME); - BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 20); + BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 21); mask = fanotify_group_event_mask(group, iter_info, mask, data, data_type, dir); diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 5ec60db3cfbb..02b5b63c6582 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1587,6 +1587,14 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, (!fid_mode || mark_type == FAN_MARK_MOUNT)) goto fput_and_out; + /* + * FAN_RENAME uses special info type records to report the old and + * new parent+name. Reporting only old and new parent id is less + * useful and was not implemented. + */ + if (mask & FAN_RENAME && !(fid_mode & FAN_REPORT_NAME)) + goto fput_and_out; + if (flags & FAN_MARK_FLUSH) { ret = 0; if (mark_type == FAN_MARK_MOUNT) diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 376e050e6f38..3afdf339d53c 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -82,7 +82,8 @@ extern struct ctl_table fanotify_table[]; /* for sysctl */ * Directory entry modification events - reported only to directory * where entry is modified and not to a watching parent. */ -#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE) +#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE | \ + FAN_RENAME) /* Events that can be reported with event->fd */ #define FANOTIFY_FD_EVENTS (FANOTIFY_PATH_EVENTS | FANOTIFY_PERM_EVENTS)