From patchwork Thu Jul 16 08:42:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666897 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CFE4F138C for ; Thu, 16 Jul 2020 08:42:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B70CA20775 for ; Thu, 16 Jul 2020 08:42:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Q5Pv+QM9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727050AbgGPImk (ORCPT ); Thu, 16 Jul 2020 04:42:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50342 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726837AbgGPImj (ORCPT ); Thu, 16 Jul 2020 04:42:39 -0400 Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D3CCC061755 for ; Thu, 16 Jul 2020 01:42:39 -0700 (PDT) Received: by mail-wr1-x442.google.com with SMTP id o11so6128217wrv.9 for ; Thu, 16 Jul 2020 01:42:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Flp7T9WIc1w1ntsSPO17S0CWhuZufq9WH+smb2lBzBY=; b=Q5Pv+QM9KPPbO7YzDANxRunFZgq/FEuvoEebJW0kpKWhOVoBr8NN6E4NPv5s6SU7Pk WDuCGtLQ5VN2DhdWZAjg07e8azkwGC3yDQ4jTWHJQ/ILD58xBYFK6ASrn53nzWxmBffR aoOcoMWkKY+81RxBJ80hB26AcRO1jRMrgBOrXmE6rKwbeBHJWOLFdTW0kGaH0Gv1LN9Z HmjgJg7ZwbKoma0DQnnQMVh+kXIxcEV5OeUQ5LMXeCQw7YckmJyJzdNglm4mVHZICWHM vQ0WVXYJd/RhuG1KV3KejhhgbLgllkg9QX5iJVcaJLgSUb2340F84koqpah4qtimiOrv MRwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Flp7T9WIc1w1ntsSPO17S0CWhuZufq9WH+smb2lBzBY=; b=ZCWYHEHdp16nXiC28yMhS4y4JlkNEtV8/WQwZsryyWh0Ohf7uxgHb5ayTHD6YSYfnJ d9eD/GIAF8GGtMyPzUBqiNs1AVvAxBqejwUj45TGtczl1VA28HLskSzyYV2yO26x5W/I uY8m31oizefFrPnA3udy02L6rcy8Z0VqFtWNXDDbSttP2cgr5zRWkrbAU5K4or67s23z 9nXLyZKJM5TNgLZolY8QGTa2eU1gBfIOj/nUj5SEMYndc+sUWW4fNwsABfs9IEYkf5mT qDle1UHHlOSs/LF471QvVk/gireMkzoSXLO4HGopJMGlSimSwcz5m4RPvVmog4XMdA68 Carg== X-Gm-Message-State: AOAM5324aT7o+Vth+ZOIYRgnxQLUIdsNXqMDP0A0kGd5bYzZnvqCGlOz EqdveL7crWWMJn4IWUCP10/zMPvI X-Google-Smtp-Source: ABdhPJwz9HEkzHgc2krRblj0Z0tT18vzMttxcx9zZntPn1DV+qCUVtdZ1Qz/s0Gif2PU6qDpZIo78A== X-Received: by 2002:adf:f3cd:: with SMTP id g13mr3765162wrp.45.1594888958310; Thu, 16 Jul 2020 01:42:38 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:37 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 01/22] fanotify: generalize the handling of extra event flags Date: Thu, 16 Jul 2020 11:42:09 +0300 Message-Id: <20200716084230.30611-2-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In fanotify_group_event_mask() there is logic in place to make sure we are not going to handle an event with no type and just FAN_ONDIR flag. Generalize this logic to any FANOTIFY_EVENT_FLAGS. There is only one more flag in this group at the moment - FAN_EVENT_ON_CHILD. We never report it to user, but we do pass it in to fanotify_alloc_event() when group is reporting fid as indication that event happened on child. We will have use for this indication later on. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index e6ba605732d7..110835a9bf99 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -211,7 +211,8 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, int data_type) { __u32 marks_mask = 0, marks_ignored_mask = 0; - __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS; + __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS | + FANOTIFY_EVENT_FLAGS; const struct path *path = fsnotify_data_path(data, data_type); struct fsnotify_mark *mark; int type; @@ -264,14 +265,18 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, * * For backward compatibility and consistency, do not report FAN_ONDIR * to user in legacy fanotify mode (reporting fd) and report FAN_ONDIR - * to user in FAN_REPORT_FID mode for all event types. + * to user in fid mode for all event types. + * + * We never report FAN_EVENT_ON_CHILD to user, but we do pass it in to + * fanotify_alloc_event() when group is reporting fid as indication + * that event happened on child. */ if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { - /* Do not report FAN_ONDIR without any event */ - if (!(test_mask & ~FAN_ONDIR)) + /* Do not report event flags without any event */ + if (!(test_mask & ~FANOTIFY_EVENT_FLAGS)) return 0; } else { - user_mask &= ~FAN_ONDIR; + user_mask &= ~FANOTIFY_EVENT_FLAGS; } return test_mask & user_mask; From patchwork Thu Jul 16 08:42:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666911 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CB2C413B4 for ; Thu, 16 Jul 2020 08:42:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B239F20775 for ; Thu, 16 Jul 2020 08:42:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HTR7LqSa" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728018AbgGPImt (ORCPT ); Thu, 16 Jul 2020 04:42:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726837AbgGPIml (ORCPT ); Thu, 16 Jul 2020 04:42:41 -0400 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0E0EC061755 for ; Thu, 16 Jul 2020 01:42:40 -0700 (PDT) Received: by mail-wr1-x443.google.com with SMTP id a6so6158242wrm.4 for ; Thu, 16 Jul 2020 01:42:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Sd8X1Bqt/nvK6QEcN6uojROEKKEljO7OuTjR5GFnFy4=; b=HTR7LqSavH9O7suL0NSSEAX5iYznt++cOmZqdQeVA1QFks7tVGaAU8gKC5DOJwkW90 v1vHRpRujSJ8GN2JP3AldpvCtwUr36faXZwdOjw82VVSwc0JIi81jL/arhuf/vert+zD UzJ5U++RteYc22xLEMZ+8P1tphIsSCYLV2cNWBmZgBdedhMhGt1/l5y5u7WYzfU/u+7k 59IpRFrSjzWlB+I+vq86v0fcyqKYYRA4T9EhEHuYYrEJYYc4hQgQhvUE6y6VCzrgAa0i Cl21h2479Sjeu/9Z6PKKESALQ7IVC0rzLqQbiQDi82gTH/DPZuuh9n54pn04RvlaoiMX mVlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Sd8X1Bqt/nvK6QEcN6uojROEKKEljO7OuTjR5GFnFy4=; b=ixd0uzzl//7yaTQhI9MAjZPhHUunhc7SS/KGeiGL48kab1g6PQg2+EiAXRapzRNszg I2ofTWz/xO8uHJur2QBMoHlcrbllwNkM4OtKxW/oOQlfo1daL4ObmK/iud/9PFisrcPj yPKEN+u3M220IjWjptzCHVtXo6KtkSlrcWxmqURAXjyWaZ/B3iDbkMqZwAQwGM1mAHFp MUHNrqPLWguV/0tpQHN2tFlIhUdWM1nARGTrqFiZfvCKtzXk/vZBq0o9Cz0GNiupkZSl 6W/4eUyr6xJTQGe0KE6KlgerpT0lrNGPdJt+RK3oArUNdD7orhX65KitGJtrg5UqTzrq 61Wg== X-Gm-Message-State: AOAM531s7WWu5kMNDLFy7ru76dAIplLnvFGhvD1rei6qprpscyXM7448 Sf6Yp9gcvWa7tbHwhup4IK7EAUbv X-Google-Smtp-Source: ABdhPJyG4MlsxGMebAlG3SAi1JQgoDHv+DlhEnVsw2+eabjl+MdGKvRSijQ6h+IVJGZE+C/btNMtmA== X-Received: by 2002:adf:9283:: with SMTP id 3mr3834894wrn.231.1594888959582; Thu, 16 Jul 2020 01:42:39 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:39 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 02/22] fanotify: generalize merge logic of events on dir Date: Thu, 16 Jul 2020 11:42:10 +0300 Message-Id: <20200716084230.30611-3-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org An event on directory should never be merged with an event on non-directory regardless of the event struct type. This change has no visible effect, because currently, with struct fanotify_path_event, the relevant events will not be merged because event path of dir will be different than event path of non-dir. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 110835a9bf99..84c86a45874c 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -83,22 +83,22 @@ static bool fanotify_should_merge(struct fsnotify_event *old_fsn, old->type != new->type || old->pid != new->pid) return false; + /* + * We want to merge many dirent events in the same dir (i.e. + * creates/unlinks/renames), but we do not want to merge dirent + * events referring to subdirs with dirent events referring to + * non subdirs, otherwise, user won't be able to tell from a + * mask FAN_CREATE|FAN_DELETE|FAN_ONDIR if it describes mkdir+ + * unlink pair or rmdir+create pair of events. + */ + if ((old->mask & FS_ISDIR) != (new->mask & FS_ISDIR)) + return false; + switch (old->type) { case FANOTIFY_EVENT_TYPE_PATH: return fanotify_path_equal(fanotify_event_path(old), fanotify_event_path(new)); case FANOTIFY_EVENT_TYPE_FID: - /* - * We want to merge many dirent events in the same dir (i.e. - * creates/unlinks/renames), but we do not want to merge dirent - * events referring to subdirs with dirent events referring to - * non subdirs, otherwise, user won't be able to tell from a - * mask FAN_CREATE|FAN_DELETE|FAN_ONDIR if it describes mkdir+ - * unlink pair or rmdir+create pair of events. - */ - if ((old->mask & FS_ISDIR) != (new->mask & FS_ISDIR)) - return false; - return fanotify_fid_event_equal(FANOTIFY_FE(old), FANOTIFY_FE(new)); case FANOTIFY_EVENT_TYPE_FID_NAME: From patchwork Thu Jul 16 08:42:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666899 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4C262138C for ; Thu, 16 Jul 2020 08:42:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 338E420771 for ; Thu, 16 Jul 2020 08:42:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="R70H80X7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727935AbgGPImp (ORCPT ); Thu, 16 Jul 2020 04:42:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50350 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727833AbgGPImm (ORCPT ); Thu, 16 Jul 2020 04:42:42 -0400 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2393FC061755 for ; Thu, 16 Jul 2020 01:42:42 -0700 (PDT) Received: by mail-wm1-x341.google.com with SMTP id 22so9424723wmg.1 for ; Thu, 16 Jul 2020 01:42:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ISCio/c6BwtLabpK0j/QeY3rqxRy+P4irG+jRMX0SCE=; b=R70H80X76YCUI8O8zBj2KLnycxreVVpCGSJ8OfHzPohDBJrEbORQeDQOCzTykjxldc Juzz8KOiKjrp3T+8YRV8q/IlbvJv1n8D5bITlmzf3h2M65fzUJH2x69ZE7oVKvMrK+Ao 7uJcOBeXCL1Wo4x4N5auYTyKo2gpSYDKAiOQRsJ5XwtAFmhmV+ssMAL0t8j1eNQNfrTl pbPQ28lfxTifeD8QV1kdXOFNz7kwBqfKB4EwAi7u5sKEJQBKsBQpLdmSIPeUQSEzc0dz o+rb0rzmrLTUB5wkT/RisOsziOODauOF8QPivyvs2K4k0/geI/tbAZv95OYiWq7yvCQV Qvcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ISCio/c6BwtLabpK0j/QeY3rqxRy+P4irG+jRMX0SCE=; b=unYIde5KMlhHQj/E5GyHlevNiRBcGUBes3ZxJuvcntB/8J4o3acvCCPtLtWqYDnTno zfCiVYTyNAM3C3/rS2xlYC3oJi2hUJjWS4IeCKrrao6WxkLRYHp+KwP2y700CdM4LHNp U3f/stieaVKEuKiqSzhu04Y8abxBGYP5+/2vyJ02vzkyCN+kHv4yITeQVpn2qWSOxaO/ tYTyMUru7vZaolBO4/JOZXXtytXsqOz0jgz9WTs4qZ4exLYeZk/+6zABXQSU0HmHsjTr rpoaU1a2QGDAB1uHm+Xs5l+uGUUGYqGKjjPlL1cc48EtQsRIiseaPSeuN15/EaKwZugV A4Sg== X-Gm-Message-State: AOAM531aCfOlJFnmL33Ore4pScv/MU6s1wWA1JdievC1V5QNG/cYI12k /JHHbqLvfpQhklaJA2IEXOPGy9tv X-Google-Smtp-Source: ABdhPJyIbN0hCxYL//Ahzu+LEsYIIcmIf4Iy2fKmh7A/3LAK3FK2ns5zksDT0Zm7OmdKYnW3egBZNA== X-Received: by 2002:a1c:9d0c:: with SMTP id g12mr3426774wme.107.1594888960848; Thu, 16 Jul 2020 01:42:40 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:40 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 03/22] fanotify: distinguish between fid encode error and null fid Date: Thu, 16 Jul 2020 11:42:11 +0300 Message-Id: <20200716084230.30611-4-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In fanotify_encode_fh(), both cases of NULL inode and failure to encode ended up with fh type FILEID_INVALID. Distiguish the case of NULL inode, by setting fh type to FILEID_ROOT. This is just a semantic difference at this point. Remove stale comment and unneeded check from fid event compare helpers. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 84c86a45874c..3dc71a8e795a 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -34,10 +34,6 @@ static bool fanotify_fh_equal(struct fanotify_fh *fh1, if (fh1->type != fh2->type || fh1->len != fh2->len) return false; - /* Do not merge events if we failed to encode fh */ - if (fh1->type == FILEID_INVALID) - return false; - return !fh1->len || !memcmp(fanotify_fh_buf(fh1), fanotify_fh_buf(fh2), fh1->len); } @@ -56,10 +52,7 @@ static bool fanotify_fid_event_equal(struct fanotify_fid_event *ffe1, static bool fanotify_name_event_equal(struct fanotify_name_event *fne1, struct fanotify_name_event *fne2) { - /* - * Do not merge name events without dir fh. - * FAN_DIR_MODIFY does not encode object fh, so it may be empty. - */ + /* Do not merge name events without dir fh */ if (!fne1->dir_fh.len) return false; @@ -290,8 +283,10 @@ static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, void *buf = fh->buf; int err; + fh->type = FILEID_ROOT; + fh->len = 0; if (!inode) - goto out; + return; dwords = 0; err = -ENOENT; @@ -326,7 +321,6 @@ static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, type, bytes, err); kfree(ext_buf); *fanotify_fh_ext_buf_ptr(fh) = NULL; -out: /* Report the event without a file identifier on encode error */ fh->type = FILEID_INVALID; fh->len = 0; From patchwork Thu Jul 16 08:42:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666901 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3349C138C for ; Thu, 16 Jul 2020 08:42:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1560D20771 for ; Thu, 16 Jul 2020 08:42:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AVHEvT3I" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727938AbgGPImp (ORCPT ); Thu, 16 Jul 2020 04:42:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725950AbgGPImn (ORCPT ); Thu, 16 Jul 2020 04:42:43 -0400 Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 87C38C08C5C0 for ; Thu, 16 Jul 2020 01:42:43 -0700 (PDT) Received: by mail-wm1-x344.google.com with SMTP id l2so10658269wmf.0 for ; Thu, 16 Jul 2020 01:42:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=z74CEK0HPXcDnU1MUydtflR5ehndxH4DI7x/m7Gu52s=; b=AVHEvT3IC8SPOp0SpVWDeU/2EvVac0Eqq+09bBm2fl6iRFlbA1KuCyGHRg4h+WtyOd G57C8pAqmE1bZ0dIE267+N54176qMoPYkPSe8NRY8onhZ4Xt8Cw4W/8G9tuewmkNtdAH kooGMgqPmeB69r1EHlbfTE7qjzEnsAGbo6mPdnDsATk5nFL71DeXi68CSmFz1RhaDYud 2zxeXJy0Cpl7Pmbl+ZLcoP95W/Q740eeR0cB21j+LQZQ6gO8iqXL7IWXgRrH7CC6Oi/Y 0s3tlGDPKpXVmih/JDfq2W6bZbYyweTb0RA1UYZFn7NvLwlG9hAkNq/4NEq6ZIbO/dZX exqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=z74CEK0HPXcDnU1MUydtflR5ehndxH4DI7x/m7Gu52s=; b=G2xc9TAtp8AiFp4CUIvbI5vTm4eMuaaGh946uLilD5l/7l0bmOie11qoA9k35bu83k KUyhZx5PFoPirVICih5GJAzih+4a3I47iQl2IsIzTW0J5Yxe/6B7Y7TgpZ1z8QrMPa3v qKIfwiCIA8yT5n8qQqEKjR2SlTdd9troo9kgGLtVKpNSSgqYlrR7R1TJigXFNfhxYzXb cnaR6PX/bMIVlifAk8LqRN/MjqPn37ZITNF9oklyqKHHQ4zI/9T4l1L09CLiBec40jXu q5wmAfi0r7mm52DK4T5bQfyItAHflVYKpY16TkHGLi8niXDtcsXMWvPuPWwuh0/nCcaK LVfQ== X-Gm-Message-State: AOAM530gw6ULaqXXA75TXabWnpz1XVDmuVc1nxuGQnawWS4XsDAkVQ7H CzWU4W8eaVDVW5n/66agBkEEK0eG X-Google-Smtp-Source: ABdhPJyMdblUm+23gX7yTJc5SPG0VoKwQ+IOVb3MmZ3v/tW2epKWVtMEM54DXcUeozUe3skt0Ce5hg== X-Received: by 2002:a1c:e18a:: with SMTP id y132mr3298610wmg.27.1594888962214; Thu, 16 Jul 2020 01:42:42 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:41 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 04/22] fanotify: generalize test for FAN_REPORT_FID Date: Thu, 16 Jul 2020 11:42:12 +0300 Message-Id: <20200716084230.30611-5-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org As preparation to new flags that report fids, define a bit set of flags for a group reporting fids, currently containing the only bit FAN_REPORT_FID. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 10 ++++++---- fs/notify/fanotify/fanotify_user.c | 12 ++++++------ include/linux/fanotify.h | 6 ++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 3dc71a8e795a..b8c04a6f04c5 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -207,13 +207,14 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS | FANOTIFY_EVENT_FLAGS; 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; int type; pr_debug("%s: report_mask=%x mask=%x data=%p data_type=%d\n", __func__, iter_info->report_mask, event_mask, data, data_type); - if (!FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + if (!fid_mode) { /* Do we have path to open a file descriptor? */ if (!path) return 0; @@ -264,7 +265,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, * fanotify_alloc_event() when group is reporting fid as indication * that event happened on child. */ - if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + if (fid_mode) { /* Do not report event flags without any event */ if (!(test_mask & ~FANOTIFY_EVENT_FLAGS)) return 0; @@ -424,6 +425,7 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, gfp_t gfp = GFP_KERNEL_ACCOUNT; struct inode *id = fanotify_fid_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); bool name_event = false; /* @@ -444,7 +446,7 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, event = fanotify_alloc_perm_event(path, gfp); } else if (name_event && file_name) { event = fanotify_alloc_name_event(id, fsid, file_name, gfp); - } else if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + } else if (fid_mode) { event = fanotify_alloc_fid_event(id, fsid, gfp); } else { event = fanotify_alloc_path_event(path, gfp); @@ -551,7 +553,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask, return 0; } - if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS)) { fsid = fanotify_get_fsid(iter_info); /* Racing with mark destruction or creation? */ if (!fsid.val[0] && !fsid.val[1]) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index c9a824e5c045..1e04caf8d6ba 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -100,7 +100,7 @@ static struct fanotify_event *get_one_event(struct fsnotify_group *group, if (fsnotify_notify_queue_is_empty(group)) goto out; - if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS)) { event_size += fanotify_event_info_len( FANOTIFY_E(fsnotify_peek_first_event(group))); } @@ -882,7 +882,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) return -EINVAL; } - if ((flags & FAN_REPORT_FID) && + if ((flags & FANOTIFY_FID_BITS) && (flags & FANOTIFY_CLASS_BITS) != FAN_CLASS_NOTIF) return -EINVAL; @@ -1040,7 +1040,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, __kernel_fsid_t __fsid, *fsid = NULL; u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS; unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS; - unsigned int obj_type; + unsigned int obj_type, fid_mode; int ret; pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n", @@ -1113,9 +1113,9 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, * inode events are not supported on a mount mark, because they do not * carry enough information (i.e. path) to be filtered by mount point. */ + fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); if (mask & FANOTIFY_INODE_EVENTS && - (!FAN_GROUP_FLAG(group, FAN_REPORT_FID) || - mark_type == FAN_MARK_MOUNT)) + (!fid_mode || mark_type == FAN_MARK_MOUNT)) goto fput_and_out; if (flags & FAN_MARK_FLUSH) { @@ -1140,7 +1140,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, goto path_put_and_out; } - if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + if (fid_mode) { ret = fanotify_test_fid(&path, &__fsid); if (ret) goto path_put_and_out; diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index b79fa9bb7359..bbbee11d2521 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -18,8 +18,10 @@ #define FANOTIFY_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \ FAN_CLASS_PRE_CONTENT) -#define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | \ - FAN_REPORT_TID | FAN_REPORT_FID | \ +#define FANOTIFY_FID_BITS (FAN_REPORT_FID) + +#define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | FANOTIFY_FID_BITS | \ + FAN_REPORT_TID | \ FAN_CLOEXEC | FAN_NONBLOCK | \ FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS) From patchwork Thu Jul 16 08:42:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666905 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 99F2E13B4 for ; Thu, 16 Jul 2020 08:42:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7D5C720775 for ; Thu, 16 Jul 2020 08:42:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ClS/+M/u" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726425AbgGPImr (ORCPT ); Thu, 16 Jul 2020 04:42:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727913AbgGPImo (ORCPT ); Thu, 16 Jul 2020 04:42:44 -0400 Received: from mail-wm1-x343.google.com (mail-wm1-x343.google.com [IPv6:2a00:1450:4864:20::343]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CBCCC061755 for ; Thu, 16 Jul 2020 01:42:44 -0700 (PDT) Received: by mail-wm1-x343.google.com with SMTP id 17so10636631wmo.1 for ; Thu, 16 Jul 2020 01:42:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jUBJ04Tw/aomYNAZEeJ5HmXe1ePS3U6CnKoM422Oh4s=; b=ClS/+M/ukqvR2mDyd4modrHi2wBHcGHZI7pN5DjPVwz3sQrEacmBiqk2SUyNmUuGYF mJDYvUZeP4kq/SlU09Go4R666ipufSVWvdnz8ed2Aeo5nj9fLSfeIxvHONBbx4hZ7Wtw dp9cMPERYKHz6O99CRKE32uJnpkUOQ2S5SIO8KC8csWKkB7ydAt3UCQR97fn56f/wK0W SyGUzPhQ7cnxbfiQmPC4fuVlPlGkp3tNql+PgpVbCsTAWotJE117aiUafTxfDq1+dMYc V0uKZxK3EuQgFzTzrtEZ5QLUM6O+0VM9g6I19BEgKBwmyNPRa6n1fvFy8HUPyH+hvmMB rPQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jUBJ04Tw/aomYNAZEeJ5HmXe1ePS3U6CnKoM422Oh4s=; b=MO4/iyQPpaO7FionjtRuKXgvJiHhH9VtYT46sZ+qOr+oJbNGVFjZ9JwOji3SyRlsGP NtsrI/GrBKdsCwzLoxHGvLtmF0I69SNlKSYltrzK60O/IiJc5TWwCG+LjWjz61cFCxW9 6pInOMatqCTWlL46dxIQt3zoKVlGVjouZQnqQTaWbQZFfHkFAuo5uPk01cBRTtos7BSw GLTBNrDBsAFwi3Xgguz1LORRal5PsYnckuNk7wT1PlPwHL6OlHOTza6RywqYGjxJqTLQ eed9fakwgDEK7ETmhosuVoIzmmj+UVVbrgrJ6c2I30W4cXFsqi4/8uCvRpmNXvEE5RYl 0UBQ== X-Gm-Message-State: AOAM532uxmFC5hXE0F6y+3C46OiKSLNWYqg8R5R9KVtOiRdTa/7yWBbL BAxyquO/aFzLUj+jIvBZTf8ewXSx X-Google-Smtp-Source: ABdhPJw+1aiJPrPzQidaz+8krO8hFhFwv7tljJkIni1LvmAhppMDlFJHKrI2FIjcrOSS9Ipjjb9IBA== X-Received: by 2002:a1c:27c1:: with SMTP id n184mr3473078wmn.6.1594888963367; Thu, 16 Jul 2020 01:42:43 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:42 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 05/22] fanotify: mask out special event flags from ignored mask Date: Thu, 16 Jul 2020 11:42:13 +0300 Message-Id: <20200716084230.30611-6-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The special event flags (FAN_ONDIR, FAN_EVENT_ON_CHILD) never had any meaning in ignored mask. Mask them out explicitly. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify_user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 1e04caf8d6ba..6d30beb320f3 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1040,6 +1040,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, __kernel_fsid_t __fsid, *fsid = NULL; u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS; unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS; + bool ignored = flags & FAN_MARK_IGNORED_MASK; unsigned int obj_type, fid_mode; int ret; @@ -1087,6 +1088,10 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, if (mask & ~valid_mask) return -EINVAL; + /* Event flags (ONDIR, ON_CHILD) are meaningless in ignored mask */ + if (ignored) + mask &= ~FANOTIFY_EVENT_FLAGS; + f = fdget(fanotify_fd); if (unlikely(!f.file)) return -EBADF; From patchwork Thu Jul 16 08:42:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666907 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F5B71510 for ; Thu, 16 Jul 2020 08:42:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 06E3020771 for ; Thu, 16 Jul 2020 08:42:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dZqBkAzI" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727963AbgGPIms (ORCPT ); Thu, 16 Jul 2020 04:42:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725950AbgGPImq (ORCPT ); Thu, 16 Jul 2020 04:42:46 -0400 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D52B8C08C5C0 for ; Thu, 16 Jul 2020 01:42:45 -0700 (PDT) Received: by mail-wr1-x441.google.com with SMTP id f7so6176158wrw.1 for ; Thu, 16 Jul 2020 01:42:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dDy7ABfa4zJAwsOa+qQ/a/9U+UuUwp99kzTAOxVYBTs=; b=dZqBkAzIavPMlnyLPBhKu0YCe+sLS3TtFgKQ6k/Y/VtS0lKv9Y3ohDnVrP9fEz/nvX xdmyRPB1mUqWQksAwgUWIXq073N3YgkREwE4/t2AQf3wKirrM5eOP8vVpPzTQwblZQhe u6tTWcZT7kw7mrewpRe4/4gMNCxqpEXme3ZEpS4aMA9yeq4cVypkLjJiXXS3Ed6LFm6u ME/WQtkG4BqiIhdV3v1yrbmo2NJPKxdpCymsPWhoFG4ECaoLqvmQJmPSdrVhYTB2Hzpv rgXgpgO1lFud6Pf6ChXkvTLL/QatGZUTF34/eX01cZKQRcBw/xj6lvU8pyanoFajii56 AeyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dDy7ABfa4zJAwsOa+qQ/a/9U+UuUwp99kzTAOxVYBTs=; b=VZznoLRBz2aPuIUaN9s0KD6VLqU1L+izXrEXXdrGlKXTj8Nk7tFsozHo1mT1sVQQAA yOHUdbwX0/7p+0+sHUYeIbDg/OGGDi7vRSEbNc03/sR68asFbY0rzPPFxdQL2xTxOgaZ hgpeUMjVe2iFdL4TMmhLDYyUgR7XeIdzh5aT7330YKjMXjFKYCGGw2TepuzWJ67nPdQW UIINHCPpRUXGw7eMk9QGjmJ4fJK1+LW4pgbEI3nIztr2HpMdVo3R8CMXiuvVQj+fBWCV OxQD3h91x6qiqBWZ3nbyWXooMLJHYuA8ovUUbxZ2uID8lrFMDbByMi76rHU2M9DPnevG 9bZQ== X-Gm-Message-State: AOAM530dk8gGwcAFsmrwPHH/8D54iCS8iEaN1KIHb4hLVMUuLA/d0iaQ z6XD9iZuDJ4BJAjBj38Zp64= X-Google-Smtp-Source: ABdhPJx+/aQzB5MsL/jNZ+BpQZ37JERz2XUpeqRzR0a/JX3/1hvUAkd+yFLTrgTBe4zOc2eHJAn11g== X-Received: by 2002:adf:b312:: with SMTP id j18mr3718937wrd.195.1594888964656; Thu, 16 Jul 2020 01:42:44 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:44 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 06/22] fanotify: prepare for implicit event flags in mark mask Date: Thu, 16 Jul 2020 11:42:14 +0300 Message-Id: <20200716084230.30611-7-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org So far, all flags that can be set in an fanotify mark mask can be set explicitly by a call to fanotify_mark(2). Prepare for defining implicit event flags that cannot be set by user with fanotify_mark(2), similar to how inotify/dnotify implicitly set the FS_EVENT_ON_CHILD flag. Implicit event flags cannot be removed by user and mark gets destroyed when only implicit event flags remain in the mask. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify_user.c | 40 ++++++++++++++++++------------ 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 6d30beb320f3..ab974cd234f7 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -656,12 +656,13 @@ static int fanotify_find_path(int dfd, const char __user *filename, } static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, - __u32 mask, - unsigned int flags, - int *destroy) + __u32 mask, unsigned int flags, + __u32 umask, int *destroy) { __u32 oldmask = 0; + /* umask bits cannot be removed by user */ + mask &= ~umask; spin_lock(&fsn_mark->lock); if (!(flags & FAN_MARK_IGNORED_MASK)) { oldmask = fsn_mark->mask; @@ -669,7 +670,13 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, } else { fsn_mark->ignored_mask &= ~mask; } - *destroy = !(fsn_mark->mask | fsn_mark->ignored_mask); + /* + * We need to keep the mark around even if remaining mask cannot + * result in any events (e.g. mask == FAN_ONDIR) to support incremenal + * changes to the mask. + * Destroy mark when only umask bits remain. + */ + *destroy = !((fsn_mark->mask | fsn_mark->ignored_mask) & ~umask); spin_unlock(&fsn_mark->lock); return mask & oldmask; @@ -677,7 +684,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark, static int fanotify_remove_mark(struct fsnotify_group *group, fsnotify_connp_t *connp, __u32 mask, - unsigned int flags) + unsigned int flags, __u32 umask) { struct fsnotify_mark *fsn_mark = NULL; __u32 removed; @@ -691,7 +698,7 @@ static int fanotify_remove_mark(struct fsnotify_group *group, } removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, - &destroy_mark); + umask, &destroy_mark); if (removed & fsnotify_conn_mask(fsn_mark->connector)) fsnotify_recalc_mask(fsn_mark->connector); if (destroy_mark) @@ -707,25 +714,26 @@ static int fanotify_remove_mark(struct fsnotify_group *group, static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt, __u32 mask, - unsigned int flags) + unsigned int flags, __u32 umask) { return fanotify_remove_mark(group, &real_mount(mnt)->mnt_fsnotify_marks, - mask, flags); + mask, flags, umask); } static int fanotify_remove_sb_mark(struct fsnotify_group *group, - struct super_block *sb, __u32 mask, - unsigned int flags) + struct super_block *sb, __u32 mask, + unsigned int flags, __u32 umask) { - return fanotify_remove_mark(group, &sb->s_fsnotify_marks, mask, flags); + return fanotify_remove_mark(group, &sb->s_fsnotify_marks, mask, + flags, umask); } static int fanotify_remove_inode_mark(struct fsnotify_group *group, struct inode *inode, __u32 mask, - unsigned int flags) + unsigned int flags, __u32 umask) { return fanotify_remove_mark(group, &inode->i_fsnotify_marks, mask, - flags); + flags, umask); } static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, @@ -1175,13 +1183,13 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, case FAN_MARK_REMOVE: if (mark_type == FAN_MARK_MOUNT) ret = fanotify_remove_vfsmount_mark(group, mnt, mask, - flags); + flags, 0); else if (mark_type == FAN_MARK_FILESYSTEM) ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask, - flags); + flags, 0); else ret = fanotify_remove_inode_mark(group, inode, mask, - flags); + flags, 0); break; default: ret = -EINVAL; From patchwork Thu Jul 16 08:42:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666909 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C0BA8138C for ; Thu, 16 Jul 2020 08:42:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A577220771 for ; Thu, 16 Jul 2020 08:42:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZjXQolMJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727969AbgGPIms (ORCPT ); Thu, 16 Jul 2020 04:42:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727913AbgGPImr (ORCPT ); Thu, 16 Jul 2020 04:42:47 -0400 Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DC9AC061755 for ; Thu, 16 Jul 2020 01:42:47 -0700 (PDT) Received: by mail-wr1-x444.google.com with SMTP id z15so6125889wrl.8 for ; Thu, 16 Jul 2020 01:42:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VtSI19lVKcekdGv3+3h/X+blWNwMmlEfOOGXPLwnEho=; b=ZjXQolMJS/eua0B8JSN7k0Iwpv6evhn7V3taeX7qyO45siRkR5F6hkR1ywXwQIxrqv UPY6JXOMHTYfVubWgHDvsI9dY+YfaxGMAmidjiUpbhgPg1RHobNazzOFNWrTmWVKULbN 9pfIwXgu0srPYddXS+uhZaKSbn3XuKKw0HNW74/tsm2iEMFmZxOSDp99zp7PRoPdpV1i NtzevDNrcWbsa6CqBCQmB894ytx9ROe6Grs4M2Xp/o0tKPSvTR/tctnO992kQ85Ss56l l1b3XBP/lHekB2qbwrVxlR2qqajimoefUX4hcWFXqXr+TwWcSbIHoXns3udUT4acKdaK zRAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VtSI19lVKcekdGv3+3h/X+blWNwMmlEfOOGXPLwnEho=; b=FZKfhMYO0QVVwDq7yF1yRW5YXXnIFoZ6FvT6B6ofu4RZJUAkEXW6vceD2xeSG/d2z/ q3w09LpLtluMI5rQMgkF84JAh0/tT/I/sSffmFOmxwueLMVw+idXlATf8+QOXnjFRR7v FUNsuRahVTv3qRvEMZ4EIDuekd331cVOv4J8JJXDjIkMcZFA7Oa0cQOBNiO+uBl5kRl7 yOEpKyOwsWZgxT3+5NJ9QlsbcgK4vfKJWY8YuExr350iWWeLv5zijscKVYjunziHmbZL Pd4Iaz1FFce5IgAQWrTu7+JBN1iRals0KdAq6g6N3l4g4JQjvZ3vtb06buTlfxVMXZo/ OV4A== X-Gm-Message-State: AOAM531lZ6rkvt0zxB/4r6hN7pLcdOc1TAvfgIoucD4YHHh8hN1fYJE0 qzCbC4WS5f3Ejw+FYDhW21M= X-Google-Smtp-Source: ABdhPJx0JFM44ihHtkr77mBsDLKZZ9m6ovbb89Ey/ZLhZXBZybAMqQVN52iShcfPBa6eQjlQ6R/ZKw== X-Received: by 2002:adf:d842:: with SMTP id k2mr4057218wrl.239.1594888966109; Thu, 16 Jul 2020 01:42:46 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:45 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 07/22] fanotify: use FAN_EVENT_ON_CHILD as implicit flag on sb/mount/non-dir marks Date: Thu, 16 Jul 2020 11:42:15 +0300 Message-Id: <20200716084230.30611-8-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Up to now, fanotify allowed to set the FAN_EVENT_ON_CHILD flag on sb/mount marks and non-directory inode mask, but the flag was ignored. Mask out the flag if it is provided by user on sb/mount/non-dir marks and define it as an implicit flag that cannot be removed by user. This flag is going to be used internally to request for events with parent and name info. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify_user.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index ab974cd234f7..16d70a8e90f9 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1050,6 +1050,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS; bool ignored = flags & FAN_MARK_IGNORED_MASK; unsigned int obj_type, fid_mode; + u32 umask = 0; int ret; pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n", @@ -1167,6 +1168,12 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, else mnt = path.mnt; + /* Mask out FAN_EVENT_ON_CHILD flag for sb/mount/non-dir marks */ + if (mnt || !S_ISDIR(inode->i_mode)) { + mask &= ~FAN_EVENT_ON_CHILD; + umask = FAN_EVENT_ON_CHILD; + } + /* create/update an inode mark */ switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) { case FAN_MARK_ADD: @@ -1183,13 +1190,13 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, case FAN_MARK_REMOVE: if (mark_type == FAN_MARK_MOUNT) ret = fanotify_remove_vfsmount_mark(group, mnt, mask, - flags, 0); + flags, umask); else if (mark_type == FAN_MARK_FILESYSTEM) ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask, - flags, 0); + flags, umask); else ret = fanotify_remove_inode_mark(group, inode, mask, - flags, 0); + flags, umask); break; default: ret = -EINVAL; From patchwork Thu Jul 16 08:42:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666913 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 153D413B4 for ; Thu, 16 Jul 2020 08:42:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EF98820775 for ; Thu, 16 Jul 2020 08:42:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="tetOeu6P" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728082AbgGPImx (ORCPT ); Thu, 16 Jul 2020 04:42:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728024AbgGPImt (ORCPT ); Thu, 16 Jul 2020 04:42:49 -0400 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C083CC061755 for ; Thu, 16 Jul 2020 01:42:48 -0700 (PDT) Received: by mail-wr1-x441.google.com with SMTP id o11so6128676wrv.9 for ; Thu, 16 Jul 2020 01:42:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nyv2KtM2WO7usNbqtN+HqdiLWba1gwwl7ImOSY7fMcw=; b=tetOeu6P9HowxRpnSOCw/FAoB9VGZHFjyqzbpvS14Nf/WB3sxAg2PAHJ5iouHl1e4E PHZkYrzgDTEplr/GJ81UwMzoY05veVs06M35BQEskWwLwhwS7FD93gRLTQZy+ZW2bxmE HgJcwTCm0OgkwAjfiIAhB12PdSSWP+GBstBKAfuAYQBwWV0STRWjbxn2ov+9Mo5GN5DF 7o8HgeZ0aDOz79E9gQ5VOg85HHract6b4eUE4yDn9atsO8evqJCeIFxg/Pc7QPgyvBcw F1VikbeIOIlu2AGHCVqjkVkq1+NiPzngsuER1vKnXNGNtRusl3g5d1gPC7Un63YMe+B2 31gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nyv2KtM2WO7usNbqtN+HqdiLWba1gwwl7ImOSY7fMcw=; b=Mqw0SSW8rQTxPkRXBwsjX5zGVbKPmL/3SQqYcyksFTQlKrB0NacjG9cVOSjKCIgq9/ xvQcEajy3kuj5qtLHbRtqr0pSosAkhXFsN1VHHBaYg26xZqCAaItIsTN3h+fu9/bb7zz A9dgFEaQP0gUziZLX2HxrR4nOPcmgTcXdiGlYMaJs1frf2z8obZ+qTJcq5TN3YNhWAST nUhefdaexOcDdyZcSaXxTMmtCSy3ITxNjKf7kmDmOXc1osi2LkITJuFPDWro+/GoytXI QVYZlzoGVlEDGwj5FEQwx32WrFdFnlNDE76y4yRvAeagopBdQHR5CQ1a5cX6bC/JNOGl JjfQ== X-Gm-Message-State: AOAM533h7tXvMg1kvH4mjsuQ7UcTgSldQP1JIRm5ltKAZ08joNscBN2V ERy5huELFCSISfd4L0V8B/aKS8tT X-Google-Smtp-Source: ABdhPJwi6vbtTUVUjq7VLtvvXVN3JEq6TruXUyGmYRVzWpNGthqkyCEEIn5euq8bxKqtGJwdgXm7pw== X-Received: by 2002:adf:ec8c:: with SMTP id z12mr3755434wrn.281.1594888967520; Thu, 16 Jul 2020 01:42:47 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:46 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 08/22] fsnotify: add object type "child" to object type iterator Date: Thu, 16 Jul 2020 11:42:16 +0300 Message-Id: <20200716084230.30611-9-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The object type iterator is used to collect all the marks of a specific group that have interest in an event. It is used by fanotify to get a single handle_event callback when an event has a match to either of inode/sb/mount marks of the group. The nature of fsnotify events is that they are associated with at most one sb at most one mount and at most one inode. When a parent and child are both watching, two events are sent to backend, one associated to parent inode and one associated to the child inode. This results in duplicate events in fanotify, which usually get merged before user reads them, but this is sub-optimal. It would be better if the same event is sent to backend with an object type iterator that has both the child inode and its parent, and let the backend decide if the event should be reported once (fanotify) or twice (inotify). Signed-off-by: Amir Goldstein --- include/linux/fsnotify_backend.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 860c847c5bfa..2c62628566c5 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -255,6 +255,7 @@ static inline const struct path *fsnotify_data_path(const void *data, enum fsnotify_obj_type { FSNOTIFY_OBJ_TYPE_INODE, + FSNOTIFY_OBJ_TYPE_CHILD, FSNOTIFY_OBJ_TYPE_VFSMOUNT, FSNOTIFY_OBJ_TYPE_SB, FSNOTIFY_OBJ_TYPE_COUNT, @@ -262,6 +263,7 @@ enum fsnotify_obj_type { }; #define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE) +#define FSNOTIFY_OBJ_TYPE_CHILD_FL (1U << FSNOTIFY_OBJ_TYPE_CHILD) #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) #define FSNOTIFY_OBJ_TYPE_SB_FL (1U << FSNOTIFY_OBJ_TYPE_SB) #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) @@ -306,6 +308,7 @@ static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \ } FSNOTIFY_ITER_FUNCS(inode, INODE) +FSNOTIFY_ITER_FUNCS(child, CHILD) FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) FSNOTIFY_ITER_FUNCS(sb, SB) From patchwork Thu Jul 16 08:42:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666915 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 667F9138C for ; Thu, 16 Jul 2020 08:42:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 479E320760 for ; Thu, 16 Jul 2020 08:42:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="o4IadOc3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728028AbgGPImy (ORCPT ); Thu, 16 Jul 2020 04:42:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728061AbgGPImu (ORCPT ); Thu, 16 Jul 2020 04:42:50 -0400 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F82EC08C5C0 for ; Thu, 16 Jul 2020 01:42:50 -0700 (PDT) Received: by mail-wr1-x441.google.com with SMTP id q5so6137630wru.6 for ; Thu, 16 Jul 2020 01:42:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PcQCQ8ZVAw8iWoOpOmbwJneQ1tuu/dom3Io5HKecdIs=; b=o4IadOc3gZ74ePdrfQhaO/smxfAWuHBOx7efM7GT2OJytkTakaYQZioBWkWlk7re4U vsEvX9qzBtvfTDi290bQE0jLR6g7QmIm8EBs+rdUEuNabTQgnqcDY1UuRttMFtXuYAgq No3+cU4v9n4SXPtBupz4/BZQitZtCMXWE6joo99hqUaswvZ5jtA6X8LiQfFbllNQN6dX PVaPBgcAkU6NBfBwbcnosYlAAgmu8VubYptAKO+uCOVwdxEwXDtvJZfyCLZH95oSNcaa hJNKNvpnxTt6B0Hyz4OSItG0Z+Y+NBb8ya1fCnov0Da1/Fkybf7UOi6lLn/PRjKGJlJc 0hzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PcQCQ8ZVAw8iWoOpOmbwJneQ1tuu/dom3Io5HKecdIs=; b=Q6Cvwgk94PdHKUvg5RPFzH7W/k9apfegiz/HJ2RVQgOnXxWJiZRdTutfB+xSb47xvE Ifhc13GZtWj1N7FAJbhk7vub0hOvQnhq8mKZMQ25eLftYz6LAdyq50ttSSUMK6T4aP8l o5/fmGh2IpD+Vg65/9SAUYFDn22/DIC52YCgdiypooG12U+22hZbKvAXHB1oU3/YPfub wwTdqajuex3mslc5hRnN5+UqIljUIXmEzKqDRaP+8QNAsDxSyKkoJz5mgv5EHhBXukds sPQvedsqzkQAyGgiXljaLpuz5ajVK3CynZ1+Fic54LvKKmuCpK+is5OA6jszshh6U1OY roDw== X-Gm-Message-State: AOAM532GI+tfut2WMf9gc/nXbmh5JhWXjqrInwYe9DmJtY7cpIIz9D1f 0NiTmmOEre52ryvLS/GNVRMBy7bW X-Google-Smtp-Source: ABdhPJxH5TN3XfAlPb+OosYaGvSaYsD2FfkYVLsf6M6DSA/i9rh43s6wfwnKdzpVtWTHXUy/WB4ZHw== X-Received: by 2002:adf:fa8f:: with SMTP id h15mr3940293wrr.211.1594888968953; Thu, 16 Jul 2020 01:42:48 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:48 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 09/22] fanotify: use struct fanotify_info to parcel the variable size buffer Date: Thu, 16 Jul 2020 11:42:17 +0300 Message-Id: <20200716084230.30611-10-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org An fanotify event name is always recorded relative to a dir fh. Encapsulate the name_len member of fanotify_name_event in a new struct fanotify_info, which describes the parceling of the variable size buffer of an fanotify_name_event. The dir_fh member of fanotify_name_event is renamed to _dir_fh and is not accessed directly, but via the fanotify_info_dir_fh() accessor. Although the dir_fh len information is already available in struct fanotify_fh, we store it also in dif_fh_totlen member of fanotify_info, including the size of fanotify_fh header, so we know the offset of the name in the buffer without looking inside the dir_fh. We also add a file_fh_totlen member to allow packing another file handle in the variable size buffer after the dir_fh and before the name. We are going to use that space to store the child fid. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 66 ++++++++++++++++------ fs/notify/fanotify/fanotify.h | 91 +++++++++++++++++++++++++----- fs/notify/fanotify/fanotify_user.c | 25 ++++---- 3 files changed, 139 insertions(+), 43 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b8c04a6f04c5..31fd41e91575 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -49,22 +49,44 @@ static bool fanotify_fid_event_equal(struct fanotify_fid_event *ffe1, fanotify_fh_equal(&ffe1->object_fh, &ffe2->object_fh); } +static bool fanotify_info_equal(struct fanotify_info *info1, + struct fanotify_info *info2) +{ + if (info1->dir_fh_totlen != info2->dir_fh_totlen || + info1->file_fh_totlen != info2->file_fh_totlen || + info1->name_len != info2->name_len) + return false; + + if (info1->dir_fh_totlen && + !fanotify_fh_equal(fanotify_info_dir_fh(info1), + fanotify_info_dir_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); +} + static bool fanotify_name_event_equal(struct fanotify_name_event *fne1, struct fanotify_name_event *fne2) { - /* Do not merge name events without dir fh */ - if (!fne1->dir_fh.len) - return false; + struct fanotify_info *info1 = &fne1->info; + struct fanotify_info *info2 = &fne2->info; - if (fne1->name_len != fne2->name_len || - !fanotify_fh_equal(&fne1->dir_fh, &fne2->dir_fh)) + /* Do not merge name events without dir fh */ + if (!info1->dir_fh_totlen) return false; - return !memcmp(fne1->name, fne2->name, fne1->name_len); + return fanotify_info_equal(info1, info2); } static bool fanotify_should_merge(struct fsnotify_event *old_fsn, - struct fsnotify_event *new_fsn) + struct fsnotify_event *new_fsn) { struct fanotify_event *old, *new; @@ -276,8 +298,14 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, return test_mask & user_mask; } -static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, - gfp_t gfp) +/* + * Encode fanotify_fh. + * + * Return total size of encoded fh including fanotify_fh header. + * Return 0 on failure to encode. + */ +static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, + gfp_t gfp) { int dwords, type, bytes = 0; char *ext_buf = NULL; @@ -287,7 +315,7 @@ static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, fh->type = FILEID_ROOT; fh->len = 0; if (!inode) - return; + return 0; dwords = 0; err = -ENOENT; @@ -315,7 +343,7 @@ static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, fh->type = type; fh->len = bytes; - return; + return FANOTIFY_FH_HDR_LEN + bytes; out_err: pr_warn_ratelimited("fanotify: failed to encode fid (type=%d, len=%d, err=%i)\n", @@ -325,6 +353,7 @@ static void fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, /* Report the event without a file identifier on encode error */ fh->type = FILEID_INVALID; fh->len = 0; + return 0; } /* @@ -401,6 +430,8 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, gfp_t gfp) { struct fanotify_name_event *fne; + struct fanotify_info *info; + struct fanotify_fh *dfh; fne = kmalloc(sizeof(*fne) + file_name->len + 1, gfp); if (!fne) @@ -408,9 +439,11 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, fne->fae.type = FANOTIFY_EVENT_TYPE_FID_NAME; fne->fsid = *fsid; - fanotify_encode_fh(&fne->dir_fh, id, gfp); - fne->name_len = file_name->len; - strcpy(fne->name, file_name->name); + info = &fne->info; + fanotify_info_init(info); + dfh = fanotify_info_dir_fh(info); + info->dir_fh_totlen = fanotify_encode_fh(dfh, id, gfp); + fanotify_info_copy_name(info, file_name); return &fne->fae; } @@ -626,9 +659,10 @@ static void fanotify_free_fid_event(struct fanotify_event *event) static void fanotify_free_name_event(struct fanotify_event *event) { struct fanotify_name_event *fne = FANOTIFY_NE(event); + struct fanotify_fh *dfh = fanotify_info_dir_fh(&fne->info); - if (fanotify_fh_has_ext_buf(&fne->dir_fh)) - kfree(fanotify_fh_ext_buf(&fne->dir_fh)); + if (fanotify_fh_has_ext_buf(dfh)) + kfree(fanotify_fh_ext_buf(dfh)); kfree(fne); } diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 1b2a3bbe6008..5e104fc56abb 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -23,11 +23,29 @@ enum { * stored in either the first or last 2 dwords. */ #define FANOTIFY_INLINE_FH_LEN (3 << 2) +#define FANOTIFY_FH_HDR_LEN offsetof(struct fanotify_fh, buf) +/* Fixed size struct for file handle */ struct fanotify_fh { - unsigned char buf[FANOTIFY_INLINE_FH_LEN]; u8 type; u8 len; + u8 pad[2]; + unsigned char buf[FANOTIFY_INLINE_FH_LEN]; +} __aligned(4); + +/* Variable size struct for dir file handle + child file handle + name */ +struct fanotify_info { + /* size of dir_fh/file_fh including fanotify_fh hdr size */ + u8 dir_fh_totlen; + u8 file_fh_totlen; + u8 name_len; + u8 pad; + 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] + */ } __aligned(4); static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) @@ -37,6 +55,7 @@ static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) static inline char **fanotify_fh_ext_buf_ptr(struct fanotify_fh *fh) { + BUILD_BUG_ON(FANOTIFY_FH_HDR_LEN % 4); BUILD_BUG_ON(__alignof__(char *) - 4 + sizeof(char *) > FANOTIFY_INLINE_FH_LEN); return (char **)ALIGN((unsigned long)(fh->buf), __alignof__(char *)); @@ -52,6 +71,56 @@ static inline void *fanotify_fh_buf(struct fanotify_fh *fh) return fanotify_fh_has_ext_buf(fh) ? fanotify_fh_ext_buf(fh) : fh->buf; } +static inline int fanotify_info_dir_fh_len(struct fanotify_info *info) +{ + if (!info->dir_fh_totlen || + WARN_ON_ONCE(info->dir_fh_totlen < FANOTIFY_FH_HDR_LEN)) + return 0; + + return info->dir_fh_totlen - FANOTIFY_FH_HDR_LEN; +} + +static inline struct fanotify_fh *fanotify_info_dir_fh(struct fanotify_info *info) +{ + BUILD_BUG_ON(offsetof(struct fanotify_info, buf) % 4); + + return (struct fanotify_fh *)info->buf; +} + +static inline int fanotify_info_file_fh_len(struct fanotify_info *info) +{ + if (!info->file_fh_totlen || + WARN_ON_ONCE(info->file_fh_totlen < FANOTIFY_FH_HDR_LEN)) + return 0; + + return info->file_fh_totlen - FANOTIFY_FH_HDR_LEN; +} + +static inline struct fanotify_fh *fanotify_info_file_fh(struct fanotify_info *info) +{ + return (struct fanotify_fh *)(info->buf + info->dir_fh_totlen); +} + +static inline const char *fanotify_info_name(struct fanotify_info *info) +{ + return info->buf + info->dir_fh_totlen + info->file_fh_totlen; +} + +static inline void fanotify_info_init(struct fanotify_info *info) +{ + info->dir_fh_totlen = 0; + info->file_fh_totlen = 0; + info->name_len = 0; +} + +static inline void fanotify_info_copy_name(struct fanotify_info *info, + const struct qstr *name) +{ + info->name_len = name->len; + strcpy(info->buf + info->dir_fh_totlen + info->file_fh_totlen, + name->name); +} + /* * Common structure for fanotify events. Concrete structs are allocated in * fanotify_handle_event() and freed when the information is retrieved by @@ -96,9 +165,9 @@ FANOTIFY_FE(struct fanotify_event *event) struct fanotify_name_event { struct fanotify_event fae; __kernel_fsid_t fsid; - struct fanotify_fh dir_fh; - u8 name_len; - char name[]; + struct fanotify_info info; + /* Reserve space in info.buf[] - access with fanotify_info_dir_fh() */ + struct fanotify_fh _dir_fh; }; static inline struct fanotify_name_event * @@ -126,11 +195,11 @@ static inline struct fanotify_fh *fanotify_event_object_fh( return NULL; } -static inline struct fanotify_fh *fanotify_event_dir_fh( +static inline struct fanotify_info *fanotify_event_info( struct fanotify_event *event) { if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) - return &FANOTIFY_NE(event)->dir_fh; + return &FANOTIFY_NE(event)->info; else return NULL; } @@ -142,15 +211,11 @@ static inline int fanotify_event_object_fh_len(struct fanotify_event *event) return fh ? fh->len : 0; } -static inline bool fanotify_event_has_name(struct fanotify_event *event) +static inline int fanotify_event_dir_fh_len(struct fanotify_event *event) { - return event->type == FANOTIFY_EVENT_TYPE_FID_NAME; -} + struct fanotify_info *info = fanotify_event_info(event); -static inline int fanotify_event_name_len(struct fanotify_event *event) -{ - return fanotify_event_has_name(event) ? - FANOTIFY_NE(event)->name_len : 0; + return info ? fanotify_info_dir_fh_len(info) : 0; } struct fanotify_path_event { diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 16d70a8e90f9..3842ef00b52e 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -66,19 +66,17 @@ static int fanotify_fid_info_len(int fh_len, int name_len) static int fanotify_event_info_len(struct fanotify_event *event) { - int info_len = 0; + struct fanotify_info *info = fanotify_event_info(event); + int dir_fh_len = fanotify_event_dir_fh_len(event); int fh_len = fanotify_event_object_fh_len(event); + int info_len = 0; + + if (dir_fh_len) + info_len += fanotify_fid_info_len(dir_fh_len, info->name_len); if (fh_len) info_len += fanotify_fid_info_len(fh_len, 0); - if (fanotify_event_name_len(event)) { - struct fanotify_name_event *fne = FANOTIFY_NE(event); - - info_len += fanotify_fid_info_len(fne->dir_fh.len, - fne->name_len); - } - return info_len; } @@ -305,6 +303,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, { struct fanotify_event_metadata metadata; struct path *path = fanotify_event_path(event); + struct fanotify_info *info = fanotify_event_info(event); struct file *f = NULL; int ret, fd = FAN_NOFD; @@ -346,13 +345,11 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, fd_install(fd, f); /* Event info records order is: dir fid + name, child fid */ - if (fanotify_event_name_len(event)) { - struct fanotify_name_event *fne = FANOTIFY_NE(event); - + if (fanotify_event_dir_fh_len(event)) { ret = copy_info_to_user(fanotify_event_fsid(event), - fanotify_event_dir_fh(event), - fne->name, fne->name_len, - buf, count); + fanotify_info_dir_fh(info), + fanotify_info_name(info), + info->name_len, buf, count); if (ret < 0) return ret; From patchwork Thu Jul 16 08:42:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666917 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C21201510 for ; Thu, 16 Jul 2020 08:42:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A90F220775 for ; Thu, 16 Jul 2020 08:42:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="F4gCElBj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728094AbgGPImy (ORCPT ); Thu, 16 Jul 2020 04:42:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726837AbgGPImv (ORCPT ); Thu, 16 Jul 2020 04:42:51 -0400 Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DAC1C08C5CE for ; Thu, 16 Jul 2020 01:42:51 -0700 (PDT) Received: by mail-wr1-x444.google.com with SMTP id s10so6088775wrw.12 for ; Thu, 16 Jul 2020 01:42:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JEQcOibaqvI55n2tcy+nfezv63AfmNX98ijh+JKKZbg=; b=F4gCElBjhnclzBBNHWJShjFh8huF8NaN0St8V5H1XQduj7seBTWSCDOrAQxuIzrn0b 006vwSm9hqzt8Wi8SKsM8U+WvFUA1ovBzlAAu2BQO+gPdicx8pB46BgXBemIi7uE5leS sKKfW34y3bRdZ+YjPWm9YCxngYTGrq8quNuKm1PF1jOb6KwhVMzCS8Wr+XptWlJSnZui k+coS8nTAw+FIxNG5/u1HVvMim1OQXjWy6yFH4syj3vZ53+qFVt5LdCqPHrsTmdkIpO9 RSVT3ntFWOGAq8z44Yt3CFjybFdu6oqhyPlM0gUkP+7lhn/H6VMSEXewh9mXDeXdHDNy +psw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JEQcOibaqvI55n2tcy+nfezv63AfmNX98ijh+JKKZbg=; b=a7LldIsQtWX8E/AbLOHxH/rMKx5nIRvf2sayAJBBofdBfBPhtTGraJRxcTBTVvE6Pu mJbf/WSj2LGp+H83H0/A/aXYGokJh7j6+u+VzospcA+bSOA85AyNR6jXWUzeIDs/j8p6 7aXMp/aWVaiwwONT5QWJCUwMUYUwXcbM8fW6tg26iIKivvWOGf2V6GRlztCxaZNYMfxa aFpsRsnT2MFF48qF8cOnBvX8iroe7PlO9t8tuR+WzTfNr3CV0COK1oyiYrs2hsaQ5gSi Rf6Wl6HF5Lz4YwsoeyOu+B566ZAROhWzHjs0uPsIvrJOjQ4evPhVG7/teKH0HzVnnZL1 vj8g== X-Gm-Message-State: AOAM530mzbGAtp+YX8ABgTKzrhNrtG/vRTSSbw+xynT3WyMwDclcL7J5 C5QkvPbbhIVhmNBFmCN5Bc8= X-Google-Smtp-Source: ABdhPJyzXCU/eVGp7GHulXwHQW/qQUspVumBr6H+LT+Dkbjvn7e3QwVb8hFV9O2lR/brkahmXqVKKg== X-Received: by 2002:adf:9283:: with SMTP id 3mr3835601wrn.231.1594888970354; Thu, 16 Jul 2020 01:42:50 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:49 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 10/22] fanotify: no external fh buffer in fanotify_name_event Date: Thu, 16 Jul 2020 11:42:18 +0300 Message-Id: <20200716084230.30611-11-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The fanotify_fh struct has an inline buffer of size 12 which is enough to store the most common local filesystem file handles (e.g. ext4, xfs). For file handles that do not fit in the inline buffer (e.g. btrfs), an external buffer is allocated to store the file handle. When allocating a variable size fanotify_name_event, there is no point in allocating also an external fh buffer when file handle does not fit in the inline buffer. Check required size for encoding fh, preallocate an event buffer sufficient to contain both file handle and name and store the name after the file handle. At this time, when not reporting name in event, we still allocate the fixed size fanotify_fid_event and an external buffer for large file handles, but fanotify_alloc_name_event() has already been prepared to accept a NULL file_name. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 75 ++++++++++++++++++++++++----------- fs/notify/fanotify/fanotify.h | 12 +++--- 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 31fd41e91575..c107974d6830 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -298,6 +298,24 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, return test_mask & user_mask; } +/* + * Check size needed to encode fanotify_fh. + * + * Return size of encoded fh without fanotify_fh header. + * Return 0 on failure to encode. + */ +static int fanotify_encode_fh_len(struct inode *inode) +{ + int dwords = 0; + + if (!inode) + return 0; + + exportfs_encode_inode_fh(inode, NULL, &dwords, NULL); + + return dwords << 2; +} + /* * Encode fanotify_fh. * @@ -305,49 +323,54 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, * Return 0 on failure to encode. */ static int fanotify_encode_fh(struct fanotify_fh *fh, struct inode *inode, - gfp_t gfp) + unsigned int fh_len, gfp_t gfp) { - int dwords, type, bytes = 0; + int dwords, type = 0; char *ext_buf = NULL; void *buf = fh->buf; int err; fh->type = FILEID_ROOT; fh->len = 0; + fh->flags = 0; if (!inode) return 0; - dwords = 0; + /* + * !gpf means preallocated variable size fh, but fh_len could + * be zero in that case if encoding fh len failed. + */ err = -ENOENT; - type = exportfs_encode_inode_fh(inode, NULL, &dwords, NULL); - if (!dwords) + if (fh_len < 4 || WARN_ON_ONCE(fh_len % 4)) goto out_err; - bytes = dwords << 2; - if (bytes > FANOTIFY_INLINE_FH_LEN) { - /* Treat failure to allocate fh as failure to allocate event */ + /* No external buffer in a variable size allocated fh */ + if (gfp && fh_len > FANOTIFY_INLINE_FH_LEN) { + /* Treat failure to allocate fh as failure to encode fh */ err = -ENOMEM; - ext_buf = kmalloc(bytes, gfp); + ext_buf = kmalloc(fh_len, gfp); if (!ext_buf) goto out_err; *fanotify_fh_ext_buf_ptr(fh) = ext_buf; buf = ext_buf; + fh->flags |= FANOTIFY_FH_FLAG_EXT_BUF; } + dwords = fh_len >> 2; type = exportfs_encode_inode_fh(inode, buf, &dwords, NULL); err = -EINVAL; - if (!type || type == FILEID_INVALID || bytes != dwords << 2) + if (!type || type == FILEID_INVALID || fh_len != dwords << 2) goto out_err; fh->type = type; - fh->len = bytes; + fh->len = fh_len; - return FANOTIFY_FH_HDR_LEN + bytes; + return FANOTIFY_FH_HDR_LEN + fh_len; out_err: pr_warn_ratelimited("fanotify: failed to encode fid (type=%d, len=%d, err=%i)\n", - type, bytes, err); + type, fh_len, err); kfree(ext_buf); *fanotify_fh_ext_buf_ptr(fh) = NULL; /* Report the event without a file identifier on encode error */ @@ -419,7 +442,8 @@ static struct fanotify_event *fanotify_alloc_fid_event(struct inode *id, ffe->fae.type = FANOTIFY_EVENT_TYPE_FID; ffe->fsid = *fsid; - fanotify_encode_fh(&ffe->object_fh, id, gfp); + fanotify_encode_fh(&ffe->object_fh, id, fanotify_encode_fh_len(id), + gfp); return &ffe->fae; } @@ -432,8 +456,13 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, struct fanotify_name_event *fne; struct fanotify_info *info; struct fanotify_fh *dfh; + unsigned int dir_fh_len = fanotify_encode_fh_len(id); + unsigned int size; - fne = kmalloc(sizeof(*fne) + file_name->len + 1, gfp); + size = sizeof(*fne) + FANOTIFY_FH_HDR_LEN + dir_fh_len; + if (file_name) + size += file_name->len + 1; + fne = kmalloc(size, gfp); if (!fne) return NULL; @@ -442,8 +471,13 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, info = &fne->info; fanotify_info_init(info); dfh = fanotify_info_dir_fh(info); - info->dir_fh_totlen = fanotify_encode_fh(dfh, id, gfp); - fanotify_info_copy_name(info, file_name); + info->dir_fh_totlen = fanotify_encode_fh(dfh, id, dir_fh_len, 0); + if (file_name) + fanotify_info_copy_name(info, file_name); + + pr_debug("%s: ino=%lu size=%u dir_fh_len=%u name_len=%u name='%.*s'\n", + __func__, id->i_ino, size, dir_fh_len, + info->name_len, info->name_len, fanotify_info_name(info)); return &fne->fae; } @@ -658,12 +692,7 @@ static void fanotify_free_fid_event(struct fanotify_event *event) static void fanotify_free_name_event(struct fanotify_event *event) { - struct fanotify_name_event *fne = FANOTIFY_NE(event); - struct fanotify_fh *dfh = fanotify_info_dir_fh(&fne->info); - - if (fanotify_fh_has_ext_buf(dfh)) - kfree(fanotify_fh_ext_buf(dfh)); - kfree(fne); + kfree(FANOTIFY_NE(event)); } static void fanotify_free_event(struct fsnotify_event *fsn_event) diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 5e104fc56abb..12c204b1489f 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -29,8 +29,10 @@ enum { struct fanotify_fh { u8 type; u8 len; - u8 pad[2]; - unsigned char buf[FANOTIFY_INLINE_FH_LEN]; +#define FANOTIFY_FH_FLAG_EXT_BUF 1 + u8 flags; + u8 pad; + unsigned char buf[]; } __aligned(4); /* Variable size struct for dir file handle + child file handle + name */ @@ -50,7 +52,7 @@ struct fanotify_info { static inline bool fanotify_fh_has_ext_buf(struct fanotify_fh *fh) { - return fh->len > FANOTIFY_INLINE_FH_LEN; + return (fh->flags & FANOTIFY_FH_FLAG_EXT_BUF); } static inline char **fanotify_fh_ext_buf_ptr(struct fanotify_fh *fh) @@ -154,6 +156,8 @@ struct fanotify_fid_event { struct fanotify_event fae; __kernel_fsid_t fsid; struct fanotify_fh object_fh; + /* Reserve space in object_fh.buf[] - access with fanotify_fh_buf() */ + unsigned char _inline_fh_buf[FANOTIFY_INLINE_FH_LEN]; }; static inline struct fanotify_fid_event * @@ -166,8 +170,6 @@ struct fanotify_name_event { struct fanotify_event fae; __kernel_fsid_t fsid; struct fanotify_info info; - /* Reserve space in info.buf[] - access with fanotify_info_dir_fh() */ - struct fanotify_fh _dir_fh; }; static inline struct fanotify_name_event * From patchwork Thu Jul 16 08:42:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666921 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 63A9813B4 for ; Thu, 16 Jul 2020 08:42:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 490232078C for ; Thu, 16 Jul 2020 08:42:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nLhawUtg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728110AbgGPIm4 (ORCPT ); Thu, 16 Jul 2020 04:42:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728092AbgGPImx (ORCPT ); Thu, 16 Jul 2020 04:42:53 -0400 Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C9D2C08C5DB for ; Thu, 16 Jul 2020 01:42:53 -0700 (PDT) Received: by mail-wr1-x442.google.com with SMTP id r12so6060079wrj.13 for ; Thu, 16 Jul 2020 01:42:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QGqAhMrMuoujNT2ORyROwugO3M+lp0SIzz7RA0iePck=; b=nLhawUtgFbqiZMYsbbM1NINnP0eFsdyiVYysudTEhGS+g5WI2/dBumw0flt7De+TYI 6CWJ2sydHB3yWuSyTbJAUdyljMo3ClE8innHNQAo7LDXrKmawDGPeN463CvuJqA2FAnc UWnVEDtV2GIXApobF+yzsK+585FYDe/qxrGwE+hkQRRKrpUcsX7ynUoZH0PybXInBLDh 27Xy3Gtv/3ROHS9M56mzZIK/rI5A4VIfJwWJ+J2c/816WlgL+S/J4+3+zIyv41kBM2JT pkLDnrLFuFC45yq45sJu4DllL7u+dfP+SQwubXbRT+1PEv29hWFEfJKdXGyhZqeIoA/H UaEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QGqAhMrMuoujNT2ORyROwugO3M+lp0SIzz7RA0iePck=; b=eXc5vKbLM5fsAzrCGSnZIZvWcyVlY6aa/PhD924M7fP8ez9NgtlWPggKaxMeHt8WFw DJpASe+epP6Lh/IqISBbXqtdX4+cYvwLs+SW4WklqQPMQJNOJAz2L0ebwzGk3VL5DgeR KQUmSe+qkiF9iARJOIT85EwK1S/bo76tEk7ZAZV3CnXyN2scajd6hIvar4s1h6us96LM 8MiwT6nJE2gI9n1iR4xx/1iLtr9haNiQQVA+Z6upLf0g0POUFLIprhZdicYB7T0avIfr F0ORGho3TUhi6/bsfj5mvCstVCXcJQIcVN7mEikuzILTNF0NAybDodZHoN66B3VN6vKk 5BOg== X-Gm-Message-State: AOAM5326moRjlMlVK+984+Fni0ESZl+ADlgTmJ/8kYJaTEKnYmj49bNb wTRDdKiMakjsU2hbS0GEwasXuDRU X-Google-Smtp-Source: ABdhPJzhR4F8zJLsXUlNjpZKHNS6QbEcftOdpVQvozBMtma05szazu+qLbuP/vmnJP3CakCNwQFGgQ== X-Received: by 2002:adf:f74f:: with SMTP id z15mr3759455wrp.233.1594888971908; Thu, 16 Jul 2020 01:42:51 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:51 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 11/22] dnotify: report both events on parent and child with single callback Date: Thu, 16 Jul 2020 11:42:19 +0300 Message-Id: <20200716084230.30611-12-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org For some events (e.g. DN_ATTRIB on sub-directory) fsnotify may call dnotify_handle_event() once for watching parent and once again for the watching sub-directory. Do the same thing with a single callback instead of two callbacks when marks iterator contains both inode and child entries. Signed-off-by: Amir Goldstein --- fs/notify/dnotify/dnotify.c | 42 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 608c3e70e81f..305e5559560a 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -70,26 +70,15 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) * destroy the dnotify struct if it was not registered to receive multiple * events. */ -static int dnotify_handle_event(struct fsnotify_group *group, u32 mask, - const void *data, int data_type, - struct inode *dir, - const struct qstr *file_name, u32 cookie, - struct fsnotify_iter_info *iter_info) +static void dnotify_one_event(struct fsnotify_group *group, u32 mask, + struct fsnotify_mark *inode_mark) { - struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); struct dnotify_mark *dn_mark; struct dnotify_struct *dn; struct dnotify_struct **prev; struct fown_struct *fown; __u32 test_mask = mask & ~FS_EVENT_ON_CHILD; - /* not a dir, dnotify doesn't care */ - if (!dir) - return 0; - - if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info))) - return 0; - dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark); spin_lock(&inode_mark->lock); @@ -111,6 +100,33 @@ static int dnotify_handle_event(struct fsnotify_group *group, u32 mask, } spin_unlock(&inode_mark->lock); +} + +static int dnotify_handle_event(struct fsnotify_group *group, u32 mask, + const void *data, int data_type, + struct inode *dir, + const struct qstr *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ + struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); + struct fsnotify_mark *child_mark = fsnotify_iter_child_mark(iter_info); + + /* not a dir, dnotify doesn't care */ + if (!dir) + return 0; + + if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info))) + return 0; + + /* + * Some events can be sent on both parent dir and subdir marks + * (e.g. DN_ATTRIB). If both parent dir and subdir are watching, + * report the event once to parent dir and once to subdir. + */ + if (inode_mark) + dnotify_one_event(group, mask, inode_mark); + if (child_mark) + dnotify_one_event(group, mask, child_mark); return 0; } From patchwork Thu Jul 16 08:42:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666919 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EF7D9138C for ; Thu, 16 Jul 2020 08:42:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D5D0320775 for ; Thu, 16 Jul 2020 08:42:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="arh52T5x" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728109AbgGPIm4 (ORCPT ); Thu, 16 Jul 2020 04:42:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728097AbgGPImy (ORCPT ); Thu, 16 Jul 2020 04:42:54 -0400 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 730E8C061755 for ; Thu, 16 Jul 2020 01:42:54 -0700 (PDT) Received: by mail-wr1-x441.google.com with SMTP id f7so6176529wrw.1 for ; Thu, 16 Jul 2020 01:42:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FjhxQsP4iRuo8yocbgE+QaUb6CJxRl5+WUn5Ln9Tepo=; b=arh52T5xxFUL6kuLdV14VTOkI4bm7XAhF7xbAFoL18EESJelP0Gnewg/i4J/fSCs7e dcLmU1GNDOiUSCvSfsKywexB3kY/Z560gJjmoiMAfLfJDiV4jY9LOoBp3Y7wCjr7pGeP 1J6v2tPFXUogTPQHqOUadkW+8Bk12rroR3F/D2Nph/axp0ViyMAFmt4wgoLaTJxLIAsm vpREzYU1/r2MMFjmsGjBeLCwvG/rXMJc31Vph5hMhW856bLuJcgk+YEEugPispJfCbv1 Y47PenwMKwkaMF9xNyvRCfReKhqhpzTukLl1n9kP0KrbiaIpjKayI1T+JW9+isBDp2Co t+Yg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FjhxQsP4iRuo8yocbgE+QaUb6CJxRl5+WUn5Ln9Tepo=; b=XGIVPsSqC6aAJj+XZ1GiN+kUkEnYAHDsiHFM894hJxPOYj+UQxltCP7zE3dbG8J7xD Mq+SALCms4xoZA3EqDXSSummbJ5VhhKyDacHC4i6qldfETi2EWFZsWccYkD+7MSXPUTs 0Hp3r62m/AszZdGccqMkRYGb58XCc3hAmLtyx2wSWXgzch2HJMXTJcn7UNmvzUSVHgTx kRar9q2asnAgULsNSiN43gyd67EtLGg7PDjSQSrUuJgxbPc3zEUvy5704ZzQBy+l4f+o ngXQkSxqIGgP7rnCadNqUhXTRC/4+OiQ//0bD9hvdzfIeNqZWvrG428gqv+Hzc6hhHyg Ul4A== X-Gm-Message-State: AOAM531WzL88RGOGgwe/kFG6io9kK1zqR8+7iqIS2EtRc8WASY2LvFpn BUxXMaeKX3K66k2EPrLzc7R9jktE X-Google-Smtp-Source: ABdhPJzuwQQiN3LvxzMLTBZnYyndanWScCV263b63sceTXVWt3I6S/uKS41g+CawvitSyq6x3NBEpQ== X-Received: by 2002:adf:ef8a:: with SMTP id d10mr3936098wro.126.1594888973241; Thu, 16 Jul 2020 01:42:53 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:52 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 12/22] inotify: report both events on parent and child with single callback Date: Thu, 16 Jul 2020 11:42:20 +0300 Message-Id: <20200716084230.30611-13-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org fsnotify usually calls inotify_handle_event() once for watching parent to report event with child's name and once for watching child to report event without child's name. Do the same thing with a single callback instead of two callbacks when marks iterator contains both inode and child entries. Signed-off-by: Amir Goldstein --- fs/notify/inotify/inotify_fsnotify.c | 44 ++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index dfd455798a1b..a65cf8c9f600 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -55,13 +55,11 @@ static int inotify_merge(struct list_head *list, return event_compare(last_event, event); } -int inotify_handle_event(struct fsnotify_group *group, u32 mask, - const void *data, int data_type, struct inode *dir, - const struct qstr *file_name, u32 cookie, - struct fsnotify_iter_info *iter_info) +static int inotify_one_event(struct fsnotify_group *group, u32 mask, + struct fsnotify_mark *inode_mark, + const struct path *path, + const struct qstr *file_name, u32 cookie) { - const struct path *path = fsnotify_data_path(data, data_type); - struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); struct inotify_inode_mark *i_mark; struct inotify_event_info *event; struct fsnotify_event *fsn_event; @@ -69,9 +67,6 @@ int inotify_handle_event(struct fsnotify_group *group, u32 mask, int len = 0; int alloc_len = sizeof(struct inotify_event_info); - if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info))) - return 0; - if ((inode_mark->mask & FS_EXCL_UNLINK) && path && d_unlinked(path->dentry)) return 0; @@ -135,6 +130,37 @@ int inotify_handle_event(struct fsnotify_group *group, u32 mask, return 0; } +int inotify_handle_event(struct fsnotify_group *group, u32 mask, + const void *data, int data_type, struct inode *dir, + const struct qstr *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) +{ + const struct path *path = fsnotify_data_path(data, data_type); + struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); + struct fsnotify_mark *child_mark = fsnotify_iter_child_mark(iter_info); + int ret = 0; + + if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info))) + return 0; + + /* + * Some events cannot be sent on both parent and child marks + * (e.g. IN_CREATE). Those events are always sent on inode_mark. + * For events that are possible on both parent and child (e.g. IN_OPEN), + * event is sent on inode_mark with name if the parent is watching and + * is sent on child_mark without name if child is watching. + * If both parent and child are watching, report the event with child's + * name here and report another event without child's name below. + */ + if (inode_mark) + ret = inotify_one_event(group, mask, inode_mark, path, + file_name, cookie); + if (ret || !child_mark) + return ret; + + return inotify_one_event(group, mask, child_mark, path, NULL, 0); +} + static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group) { inotify_ignored_and_remove_idr(fsn_mark, group); From patchwork Thu Jul 16 08:42:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666923 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E47EC13B4 for ; Thu, 16 Jul 2020 08:42:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CC2F12078C for ; Thu, 16 Jul 2020 08:42:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A81p28HG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728117AbgGPIm7 (ORCPT ); Thu, 16 Jul 2020 04:42:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728103AbgGPIm4 (ORCPT ); Thu, 16 Jul 2020 04:42:56 -0400 Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02213C061755 for ; Thu, 16 Jul 2020 01:42:56 -0700 (PDT) Received: by mail-wm1-x344.google.com with SMTP id o2so10665009wmh.2 for ; Thu, 16 Jul 2020 01:42:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=E55Apwgwfx/i5D8M/LsB/9auaV2S5aV6GN5wmekte2M=; b=A81p28HGPxqZ9+xpPNls7IMgz6IuSA6tlFo7YHgRjKzKfhSmGoWfN/lj1TZhti/h00 DHuItFeC5IictpPULbaz7nwA5I341Mh27oew8ifHPQ9/Ak/N7Q/xYLebGbFsU9w6hD8r ukS9mazYt4jyf7LaW3lAIOr2WrHNyc9NGKx+MCHaUXl6dfFsmQQMXHyddSj8Db0lk8f9 Bp15TGCFc6DfJuaimh/e3ptgQCpXt0FeMdPDOJt7YnjWP7wd3NgefGu9rgPdAOTE0GEJ 3t3LXnK3+OOAZ31QKz9fNSl4N11OhDEk8UQ6Eic40OpEMI2Cw8WLuNW9j5Gvg5wdfl1L 39AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=E55Apwgwfx/i5D8M/LsB/9auaV2S5aV6GN5wmekte2M=; b=s8Zi5XvN2ndJGMQrgo7+yoFvQmMqMjc1SRIim3uDTKTAVdctTGlXVUy7JWuGbaszSF 8y9FWUJtVaJB8R+8TnE52/ENlDsFPeerhPzDcOhG7pE9aDKVaQLynAvkaFjenJwc4Y8d Kmppc8pvKjPytERkPctMHruFzgNAzBJ1iqFkBdyC1Or6o62MDun7Hl3ZpOIuhgj1TeDC XNW+h5ytav+jdhhPpmjwrrq41O3fT+NRgyv2ZZFjnA9ndbJfxaY+qzjkaQO90rbhW4qM 1m8Md/v8km2qlLNtf9iWR2yEGaTSFyIR8E9vMhyFyS97q3uc7fI6nFkgD7aVPJnY8DN/ QBsg== X-Gm-Message-State: AOAM5333zLvtWthCVFC8JWSsOwMv6E7+31SwaVcRkMStEValuFkzIucQ RzEiI4UHnwnSgnKzky2ISEs= X-Google-Smtp-Source: ABdhPJyPwRSrADb2NMEhDfU/aI3N3jJCM8n0Dy2IuGBSzwaSgP8zosDuKI0ACnsNjcuaGB0zvkXr3A== X-Received: by 2002:a05:600c:2317:: with SMTP id 23mr3469800wmo.72.1594888974768; Thu, 16 Jul 2020 01:42:54 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:54 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 13/22] fanotify: report both events on parent and child with single callback Date: Thu, 16 Jul 2020 11:42:21 +0300 Message-Id: <20200716084230.30611-14-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org fsnotify usually calls fanotify_handle_event() once for watching parent and once for watching child, even though both events are exactly the same and will most likely get merged before user reads them. Add support for handling both event flavors with a single callback instead of two callbacks when marks iterator contains both inode and child entries. fanotify will queue a single event in that case and the unneeded merge will be avoided. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index c107974d6830..1ec760960c93 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -263,8 +263,11 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, /* * If the event is for a child and this mark doesn't care about * events on a child, don't send it! + * The special object type "child" always cares about events on + * a child, because it refers to the child inode itself. */ if (event_mask & FS_EVENT_ON_CHILD && + type != FSNOTIFY_OBJ_TYPE_CHILD && (type != FSNOTIFY_OBJ_TYPE_INODE || !(mark->mask & FS_EVENT_ON_CHILD))) continue; From patchwork Thu Jul 16 08:42:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666925 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A3093138C for ; Thu, 16 Jul 2020 08:43:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 820B62078C for ; Thu, 16 Jul 2020 08:43:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XIRYvUJT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728113AbgGPIm7 (ORCPT ); Thu, 16 Jul 2020 04:42:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728092AbgGPIm5 (ORCPT ); Thu, 16 Jul 2020 04:42:57 -0400 Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 91B84C08C5C0 for ; Thu, 16 Jul 2020 01:42:57 -0700 (PDT) Received: by mail-wm1-x342.google.com with SMTP id q15so9439568wmj.2 for ; Thu, 16 Jul 2020 01:42:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ryWTy56nYN5vBtgba5aR4ZZLUrWs457fZRBboLlVPZg=; b=XIRYvUJTB1obQ70tszU7lVIh/oSMjMD5ZGIRRmJh5km3do38zfLFlD2xk75Qv8D/73 coymZYx8tueR/UETMPj9ggUQAfPbq6eWXGuYpso70zUlPDrV2oiHspPC4WlWRYGCF//0 Q2gQmEIqzTHzT4qJKPtEzLeq3KyQgifHPHgrugTf97zZ+5wvRSbjQxkW0iZS81ttj6Z3 oD0MWhLDl3AIEooTFyzKtQW4EcT8sLQvWVfPcEFxKnSAPFNSw0CK80ZODnMA3o51zKdn 976o7t7p2UVbCjROS7uqpVStXyfD09NzFaIWOmnW5x8gIGSlhLgnpIUhUlAcd0PVztEs jRVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ryWTy56nYN5vBtgba5aR4ZZLUrWs457fZRBboLlVPZg=; b=dIl/r16syNSTGX+N4yWLLYOEtMLKFC1qFTJ+lRCVyqsvulkje/Mw91wUJrGHu8KmBn YB1hSwyCQFrJyz5yBOLYwyC4bzxdKyJUYlYRk9SA92zZ8gHzFJ1w9urcb2ZKeuydHMUi 9VTUVZWRL2MoXI+fzJsk0Iq1ezwuQvryDpt5KUdjNf/+aiLnPfxPtidTiHFftukMT33b 0HIItvLXkiY3QkP6LBjlG6yxroIFPoN5ufsa8zCmmj2w/AsnSnKXUwH4rDb4Bdwbmgr0 eOzqGst00BaooMiZrclj16f3XMiMAlR9UzchCQEDXGdjQGJhMkw+z5ngZUjEfTO974iJ Ow7A== X-Gm-Message-State: AOAM531qJSA9LazfUE1k/X2/CKrXSoEf4DV5MTEp3KXFfSDbVQavs52B 66Ytz6SPJswvQnMJKd9Qiwetoe4Q X-Google-Smtp-Source: ABdhPJzoi+DKQG38jmIfCEbdwg8dnHsOf4VOEKU/RCTKj6+R4YCjdK8hULqiRP9xHR9/Z9I8XxpCeQ== X-Received: by 2002:a7b:c2f7:: with SMTP id e23mr3264965wmk.175.1594888976210; Thu, 16 Jul 2020 01:42:56 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:55 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 14/22] fsnotify: send event to parent and child with single callback Date: Thu, 16 Jul 2020 11:42:22 +0300 Message-Id: <20200716084230.30611-15-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Instead of calling fsnotify() twice, once with parent inode and once with child inode, if event should be sent to parent inode, send it with both parent and child inodes marks in object type iterator and call the backend handle_event() callback only once. The parent inode is assigned to the standard "inode" iterator type and the child inode is assigned to the special "child" iterator type. In that case, the bit FS_EVENT_ON_CHILD will be set in the event mask, the dir argment to handle_event will be the parent inode, the file_name argument to handle_event is non NULL and refers to the name of the child and the child inode can be accessed with fsnotify_data_inode(). This will allow fanotify to make decisions based on child or parent's ignored mask. For example, when a parent is interested in a specific event on its children, but a specific child wishes to ignore this event, the event will not be reported. This is not what happens with current code, but according to man page, it is the expected behavior. Signed-off-by: Amir Goldstein --- fs/kernfs/file.c | 10 +++++--- fs/notify/fsnotify.c | 60 ++++++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index e23b3f62483c..5b1468bc509e 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -883,6 +883,7 @@ static void kernfs_notify_workfn(struct work_struct *work) list_for_each_entry(info, &kernfs_root(kn)->supers, node) { struct kernfs_node *parent; + struct inode *p_inode = NULL; struct inode *inode; struct qstr name; @@ -899,8 +900,6 @@ static void kernfs_notify_workfn(struct work_struct *work) name = (struct qstr)QSTR_INIT(kn->name, strlen(kn->name)); parent = kernfs_get_parent(kn); if (parent) { - struct inode *p_inode; - p_inode = ilookup(info->sb, kernfs_ino(parent)); if (p_inode) { fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD, @@ -911,8 +910,11 @@ static void kernfs_notify_workfn(struct work_struct *work) kernfs_put(parent); } - fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, - NULL, 0); + if (!p_inode) { + fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE, + NULL, 0); + } + iput(inode); } diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 51ada3cfd2ff..7120c675e9a6 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -145,17 +145,21 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) /* * Notify this dentry's parent about a child's events with child name info * if parent is watching. - * Notify also the child without name info if child inode is watching. + * Notify only the child without name info if parent is not watching. */ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, int data_type) { + struct inode *inode = d_inode(dentry); struct dentry *parent; struct inode *p_inode; + struct name_snapshot name; + struct qstr *file_name = NULL; int ret = 0; + parent = NULL; if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) - goto notify_child; + goto notify; parent = dget_parent(dentry); p_inode = parent->d_inode; @@ -163,25 +167,24 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, if (unlikely(!fsnotify_inode_watches_children(p_inode))) { __fsnotify_update_child_dentry_flags(p_inode); } else if (p_inode->i_fsnotify_mask & mask & ALL_FSNOTIFY_EVENTS) { - struct name_snapshot name; + /* When notifying parent, child should be passed as data */ + WARN_ON_ONCE(inode != fsnotify_data_inode(data, data_type)); - /* - * We are notifying a parent, so set a flag in mask to inform - * backend that event has information about a child entry. - */ + /* Notify both parent and child with child name info */ + inode = p_inode; take_dentry_name_snapshot(&name, dentry); - ret = fsnotify(p_inode, mask | FS_EVENT_ON_CHILD, data, - data_type, &name.name, 0); - release_dentry_name_snapshot(&name); + file_name = &name.name; + mask |= FS_EVENT_ON_CHILD; } - dput(parent); +notify: + ret = fsnotify(inode, mask, data, data_type, file_name, 0); - if (ret) - return ret; + if (file_name) + release_dentry_name_snapshot(&name); + dput(parent); -notify_child: - return fsnotify(d_inode(dentry), mask, data, data_type, NULL, 0); + return ret; } EXPORT_SYMBOL_GPL(__fsnotify_parent); @@ -322,12 +325,16 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, struct super_block *sb = to_tell->i_sb; struct inode *dir = S_ISDIR(to_tell->i_mode) ? to_tell : NULL; struct mount *mnt = NULL; + struct inode *child = NULL; int ret = 0; __u32 test_mask, marks_mask; if (path) mnt = real_mount(path->mnt); + if (mask & FS_EVENT_ON_CHILD) + child = fsnotify_data_inode(data, data_type); + /* * Optimization: srcu_read_lock() has a memory barrier which can * be expensive. It protects walking the *_fsnotify_marks lists. @@ -336,21 +343,20 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, * need SRCU to keep them "alive". */ if (!to_tell->i_fsnotify_marks && !sb->s_fsnotify_marks && - (!mnt || !mnt->mnt_fsnotify_marks)) + (!mnt || !mnt->mnt_fsnotify_marks) && + (!child || !child->i_fsnotify_marks)) return 0; - /* An event "on child" is not intended for a mount/sb mark */ - marks_mask = to_tell->i_fsnotify_mask; - if (!(mask & FS_EVENT_ON_CHILD)) { - marks_mask |= sb->s_fsnotify_mask; - if (mnt) - marks_mask |= mnt->mnt_fsnotify_mask; - } + marks_mask = to_tell->i_fsnotify_mask | sb->s_fsnotify_mask; + if (mnt) + marks_mask |= mnt->mnt_fsnotify_mask; + if (child) + marks_mask |= child->i_fsnotify_mask; + /* * if this is a modify event we may need to clear the ignored masks - * otherwise return if neither the inode nor the vfsmount/sb care about - * this type of event. + * otherwise return if none of the marks care about this type of event. */ test_mask = (mask & ALL_FSNOTIFY_EVENTS); if (!(mask & FS_MODIFY) && !(test_mask & marks_mask)) @@ -366,6 +372,10 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] = fsnotify_first_mark(&mnt->mnt_fsnotify_marks); } + if (child) { + iter_info.marks[FSNOTIFY_OBJ_TYPE_CHILD] = + fsnotify_first_mark(&child->i_fsnotify_marks); + } /* * We need to merge inode/vfsmount/sb mark lists so that e.g. inode mark From patchwork Thu Jul 16 08:42:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666927 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F1F21510 for ; Thu, 16 Jul 2020 08:43:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 10BD02078C for ; Thu, 16 Jul 2020 08:43:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="pMmDMKZ3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728124AbgGPInA (ORCPT ); Thu, 16 Jul 2020 04:43:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727870AbgGPIm7 (ORCPT ); Thu, 16 Jul 2020 04:42:59 -0400 Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBAE7C08C5CE for ; Thu, 16 Jul 2020 01:42:58 -0700 (PDT) Received: by mail-wm1-x344.google.com with SMTP id c80so9439149wme.0 for ; Thu, 16 Jul 2020 01:42:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iS8h8xcgbsn5E7yVxWKMHYCGwIn2hPpcQCv3Ur50qR0=; b=pMmDMKZ3QmL/VJsVT6fsgLp5kY6/ADYa10g2cKbATF8grNxZffYdLExT2VWuYE7PHR wG5mVloLgJblWKcgYSMm2BI46ZnOj4WUWopTLXYcAcowxRae74ag1yl3/1kACi/Rt/kh JCfWYffXjDvhz8wH9oQA+Y0pb0/ZmgT5/GMRhu+0qifDuvNCEkg1hldwEKhOL42v4lJS U2c3cfTlNrlqM3AjqrlMXjUtjbjNyMM8qNOZLCPWjvL+onKj2wwAmLr2xpxQEmkHAz+1 2HP89B3zI9hlkdOcqDOxkFRit1dFWjCnTD6XgZwlLCAyyWfKgquKd+LpTeJtZp/NV4q/ 6QVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iS8h8xcgbsn5E7yVxWKMHYCGwIn2hPpcQCv3Ur50qR0=; b=DkYPdN3If55FtO4wtdedUs5fl18xtmBGfv9di6Z8yyRYdr8U3SUtXoT4STBQ1kFvgz peULU8Fr5sQW61E5VZc9oP0nqCkoGwZlLCWqEZLV3tTgZdlv0r3CYg2PJiY1J8LHpjmF rogmGMWR9lw2XpqwkZxlcHSYnymRA6+0kNm9mVWNxGUNb4zDBj80jeTc7SERyvSsa9q9 x+uolfUvL5SSQJSP5v7flnUxjR1FLmnKKTj5duTMUPHHzh1G6LAUXC0Ahkig2T3cwxyj o2lYl3p6W8FAROKwEQlevzcAy4iZ7k8wMgBVl2EzHJdkDDlJtZjWluooMDdj0Zd00/oe bCVA== X-Gm-Message-State: AOAM533XoC0/0MlkhXvTEukH4+CFbwsnTe3OPytdGSSlefz1yT9i2OU7 IpyWAUTM6BJEqnhXMSz5A53qFFXB X-Google-Smtp-Source: ABdhPJwyjLcCIVz++LdGAnlB0/2UjrB4DAUkkx+n/6seQuQV/FqNzSvUMx+GkWZwS5j3sKsZgCkLEQ== X-Received: by 2002:a1c:9e84:: with SMTP id h126mr3189104wme.61.1594888977324; Thu, 16 Jul 2020 01:42:57 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:56 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 15/22] fsnotify: send event with parent/name info to sb/mount/non-dir marks Date: Thu, 16 Jul 2020 11:42:23 +0300 Message-Id: <20200716084230.30611-16-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Similar to events "on child" to watching directory, send event "on child" with parent/name info if sb/mount/non-dir marks are interested in parent/name info. The FS_EVENT_ON_CHILD flag can be set on sb/mount/non-dir marks to specify interest in parent/name info for events on non-directory inodes. Events on "orphan" children (disconnected dentries) are sent without parent/name info. Events on direcories are send with parent/name info only if the parent directory is watching. Signed-off-by: Amir Goldstein --- fs/notify/fsnotify.c | 54 ++++++++++++++++++++++++++++---- include/linux/fsnotify.h | 10 ++++-- include/linux/fsnotify_backend.h | 32 ++++++++++++++++--- 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 7120c675e9a6..efa5c1c4908a 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -142,31 +142,73 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) spin_unlock(&inode->i_lock); } +/* Are inode/sb/mount interested in parent and name info with this event? */ +static bool fsnotify_event_needs_parent(struct inode *inode, struct mount *mnt, + __u32 mask) +{ + __u32 marks_mask = 0; + + /* We only send parent/name to inode/sb/mount for events on non-dir */ + if (mask & FS_ISDIR) + return false; + + /* Did either inode/sb/mount subscribe for events with parent/name? */ + marks_mask |= fsnotify_parent_needed_mask(inode->i_fsnotify_mask); + marks_mask |= fsnotify_parent_needed_mask(inode->i_sb->s_fsnotify_mask); + if (mnt) + marks_mask |= fsnotify_parent_needed_mask(mnt->mnt_fsnotify_mask); + + /* Did they subscribe for this event with parent/name info? */ + return mask & marks_mask; +} + /* * Notify this dentry's parent about a child's events with child name info - * if parent is watching. - * Notify only the child without name info if parent is not watching. + * if parent is watching or if inode/sb/mount are interested in events with + * parent and name info. + * + * Notify only the child without name info if parent is not watching and + * inode/sb/mount are not interested in events with parent and name info. */ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, int data_type) { + const struct path *path = fsnotify_data_path(data, data_type); + struct mount *mnt = path ? real_mount(path->mnt) : NULL; struct inode *inode = d_inode(dentry); struct dentry *parent; + bool parent_watched = dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED; + __u32 p_mask; struct inode *p_inode; struct name_snapshot name; struct qstr *file_name = NULL; int ret = 0; + /* + * Do inode/sb/mount care about parent and name info on non-dir? + * Do they care about any event at all? + */ + if (!inode->i_fsnotify_marks && !inode->i_sb->s_fsnotify_marks && + (!mnt || !mnt->mnt_fsnotify_marks) && !parent_watched) + return 0; + parent = NULL; - if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) + if (!parent_watched && !fsnotify_event_needs_parent(inode, mnt, mask)) goto notify; + /* Does parent inode care about events on children? */ parent = dget_parent(dentry); p_inode = parent->d_inode; - - if (unlikely(!fsnotify_inode_watches_children(p_inode))) { + p_mask = fsnotify_inode_watches_children(p_inode); + if (unlikely(parent_watched && !p_mask)) __fsnotify_update_child_dentry_flags(p_inode); - } else if (p_inode->i_fsnotify_mask & mask & ALL_FSNOTIFY_EVENTS) { + + /* + * Include parent/name in notification either if some notification + * groups require parent info (!parent_watched case) or the parent is + * interested in this event. + */ + if (!parent_watched || (mask & p_mask & ALL_FSNOTIFY_EVENTS)) { /* When notifying parent, child should be passed as data */ WARN_ON_ONCE(inode != fsnotify_data_inode(data, data_type)); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 9b2566d273a9..044cae3a0628 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -44,10 +44,16 @@ static inline int fsnotify_parent(struct dentry *dentry, __u32 mask, { struct inode *inode = d_inode(dentry); - if (S_ISDIR(inode->i_mode)) + if (S_ISDIR(inode->i_mode)) { mask |= FS_ISDIR; - if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) + /* sb/mount marks are not interested in name of directory */ + if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) + goto notify_child; + } + + /* disconnected dentry cannot notify parent */ + if (IS_ROOT(dentry)) goto notify_child; return __fsnotify_parent(dentry, mask, data, data_type); diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 2c62628566c5..6f0df110e9f8 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -49,8 +49,11 @@ #define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */ #define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */ -/* This inode cares about things that happen to its children. Always set for - * dnotify and inotify. */ +/* + * Set on inode mark that cares about things that happen to its children. + * Always set for dnotify and inotify. + * Set on inode/sb/mount marks that care about parenet/name info. + */ #define FS_EVENT_ON_CHILD 0x08000000 #define FS_DN_RENAME 0x10000000 /* file renamed */ @@ -72,14 +75,22 @@ FS_OPEN_EXEC_PERM) /* - * This is a list of all events that may get sent to a parent based on fs event - * happening to inodes inside that directory. + * This is a list of all events that may get sent to a parent that is watching + * with flag FS_EVENT_ON_CHILD based on fs event on a child of that directory. */ #define FS_EVENTS_POSS_ON_CHILD (ALL_FSNOTIFY_PERM_EVENTS | \ FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | \ FS_OPEN | FS_OPEN_EXEC) +/* + * This is a list of all events that may get sent with the parent inode as the + * @to_tell argument of fsnotify(). + * It may include events that can be sent to an inode/sb/mount mark, but cannot + * be sent to a parent watching children. + */ +#define FS_EVENTS_POSS_TO_PARENT (FS_EVENTS_POSS_ON_CHILD) + /* Events that can be reported to backends */ #define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \ FS_EVENTS_POSS_ON_CHILD | \ @@ -398,6 +409,19 @@ extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); extern void fsnotify_sb_delete(struct super_block *sb); extern u32 fsnotify_get_cookie(void); +static inline __u32 fsnotify_parent_needed_mask(__u32 mask) +{ + /* FS_EVENT_ON_CHILD is set on marks that want parent/name info */ + if (!(mask & FS_EVENT_ON_CHILD)) + return 0; + /* + * This object might be watched by a mark that cares about parent/name + * info, does it care about the specific set of events that can be + * reported with parent/name info? + */ + return mask & FS_EVENTS_POSS_TO_PARENT; +} + static inline int fsnotify_inode_watches_children(struct inode *inode) { /* FS_EVENT_ON_CHILD is set if the inode may care */ From patchwork Thu Jul 16 08:42:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666929 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 47BBB138C for ; Thu, 16 Jul 2020 08:43:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2E2C120771 for ; Thu, 16 Jul 2020 08:43:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KwFaMThX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728133AbgGPInD (ORCPT ); Thu, 16 Jul 2020 04:43:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728123AbgGPInA (ORCPT ); Thu, 16 Jul 2020 04:43:00 -0400 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09D7BC061755 for ; Thu, 16 Jul 2020 01:43:00 -0700 (PDT) Received: by mail-wr1-x443.google.com with SMTP id f18so6190457wrs.0 for ; Thu, 16 Jul 2020 01:42:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=t8HX3T30YFpWehvlFQBIGM0mnagKMhXY8ru6f3KVWCQ=; b=KwFaMThXXg/rbRioI8k4lKUxhorsCqwBFU7GiLVg3N4xUslggWxjRCvKjPNdx2i99a wHF+6J0fldOoBXs6pyJsH9mM7O+JpyesTLjbgTarE7Qt6Oa7rVNoMB/LNOIiSzXhYmNk +HmogQJjYJC9yIjr4sqiIawkorsaTbCuySnLOKf3oLwOkCPJRrj+UXwQQTQWDpXrJvcU WKa+BOZXuo2f3AH8Ph0xrhWP1Nk87SsOLmUwUrnX1zRhFVok96v2JJjixel5/H7mtUJH gu1pf6kkBhzGxqPrTlCUd7gttvgOI/yfZmRy9h1QW2iKNqg+kJopW1J7VwKgHZJ1w284 ZAyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=t8HX3T30YFpWehvlFQBIGM0mnagKMhXY8ru6f3KVWCQ=; b=ODQUb1UCdD/9Z1sYRLwC0Ch/JdA/sowyb1rTpb41PI0Ed+VP3pIYCAcR90hxeOz6p/ bYxK6IUzmEejkq9wfloA3UMgaTKk+xUchOmZwsEON+SLUxA3dmWN0hnsVI30vUM4T+p9 MeyBG3vInJ+88dkP6J5ShbJxiUpMyRii3uhlqr4uNMHXHZyiaF/5LUqYLEDfdH4LsVS3 F+v4tM4cTZ9pJZZV4w+qbjUxlvl0monjvXzjq6L+MeGraru6iR7kyyA3YbgiDll1WK7w 2LU+7r/aoKTiE0VCypfocfDxp0lb5h3y4TiSvQZt12pPNyQGaT6XfpwT/g1E387buOdw wdKA== X-Gm-Message-State: AOAM531qGznJerKnskR5Ezs41nqQYvWrJzm3xlXm5QYKrz8lLbDnm6af B5h3NQQoxND2rAlrYJI4lpE= X-Google-Smtp-Source: ABdhPJzbrvGeGH0q7/t7ITQRejZ0yH/iP69AHGl0WCKt64D8bHCER85w11oL5sBzFXk6FrpHVGn89g== X-Received: by 2002:a5d:4bc4:: with SMTP id l4mr3783848wrt.97.1594888978673; Thu, 16 Jul 2020 01:42:58 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:57 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 16/22] fsnotify: remove check that source dentry is positive Date: Thu, 16 Jul 2020 11:42:24 +0300 Message-Id: <20200716084230.30611-17-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Remove the unneeded check for positive source dentry in fsnotify_move(). fsnotify_move() hook is mostly called from vfs_rename() under lock_rename() and vfs_rename() starts with may_delete() test that verifies positive source dentry. The only other caller of fsnotify_move() - debugfs_rename() also verifies positive source. Signed-off-by: Amir Goldstein --- include/linux/fsnotify.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 044cae3a0628..fe4f2bc5b4c2 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -149,8 +149,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, if (target) fsnotify_link_count(target); - if (source) - fsnotify(source, mask, source, FSNOTIFY_EVENT_INODE, NULL, 0); + fsnotify(source, mask, source, FSNOTIFY_EVENT_INODE, NULL, 0); audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE); } From patchwork Thu Jul 16 08:42:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666931 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E13EE1510 for ; Thu, 16 Jul 2020 08:43:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C881220775 for ; Thu, 16 Jul 2020 08:43:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="U1vLx49u" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728123AbgGPInE (ORCPT ); Thu, 16 Jul 2020 04:43:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727870AbgGPInB (ORCPT ); Thu, 16 Jul 2020 04:43:01 -0400 Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A4CFC08C5C0 for ; Thu, 16 Jul 2020 01:43:01 -0700 (PDT) Received: by mail-wr1-x444.google.com with SMTP id f2so6131174wrp.7 for ; Thu, 16 Jul 2020 01:43:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=z1FPrhMQPtYqvY1liMDVg4wL8CDzPV9+9nLoS7Y7SrQ=; b=U1vLx49uVdIPgI5loAaJwytuFdlonq+ODqzYXc62mWeQ7OLuOiPhRvd+97jzbYTv05 /Z038nm1ZdH9I4JNXCmWb3aWUZqVgrWqNIiwNHfxeRHiY4B/eayfrhjctSZk//lVzxyC MCTgesK/cHFdFG7jkv7tplTqj6JLsRBFcGq8vScwX6YvSTR8K439OBXyYAZJ/zY8IIV0 XXRlrmAYdVj1M046Slkq+iAg6z2sgj+oXyz05DNu4wKq9fWC2EKJ9096hDF8I0wqHwh8 w1X87bgzkx8n3N8PS0MNfj8r7BFOjS+fgXY4SQxY2jkf4VV3DErZ74bJe8MhIUulNDwL pxGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=z1FPrhMQPtYqvY1liMDVg4wL8CDzPV9+9nLoS7Y7SrQ=; b=rsF3y55rOr5lkglwAGCI9lb0PnnAPWmkpfEdWjF3rGs0Rk56WFodmAqMoWy7I0Nxix E27OdChW73MYfXvBRnWt/JCJW7sPGFUvzaYg+6Zev4vba0qnHEAvJZTRI7nW1fE2Z4nn D9QOlT0QEXXpiSRhDFRa+xMxY0y8dpuclh+Gp5s32GQMdp1WjNUSXyY98HMisfPy51Y+ bK1ZppW56pAaPbpjOEmFuhNHmQkhMCrYww8kRItntYvCHbElA1xkD6yFiSxQJmHRDeXr ZELOpaKPteRN+0uaSfXYkNKwlujYJKHwU2C3kZ5WEAgDGHp0Vx0uSmt76gFWloszJJ8N rdLg== X-Gm-Message-State: AOAM530Dd/wCQlMRdRHtg+4r9H7Xug8U7Zv+J6zgrZ8mmdaOVQk5bo74 f/P1xkLBbmtfoujavZRIq8Q= X-Google-Smtp-Source: ABdhPJzXpeaxcnEvTWzn1gzYPk+3ai784EFKfhxaacwemnvKl1pBqGFPOdjiTBVXeuNMej94rXkoRw== X-Received: by 2002:adf:ec8c:: with SMTP id z12mr3756216wrn.281.1594888980079; Thu, 16 Jul 2020 01:43:00 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.42.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:42:59 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 17/22] fsnotify: send MOVE_SELF event with parent/name info Date: Thu, 16 Jul 2020 11:42:25 +0300 Message-Id: <20200716084230.30611-18-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org MOVE_SELF event does not get reported to a parent watching children when a child is moved, but it can be reported to sb/mount mark or to the moved inode itself with parent/name info if group is interested in parent/name info. Use the fsnotify_parent() helper to send a MOVE_SELF event and adjust fsnotify() to handle the case of an event "on child" that should not be sent to the watching parent's inode mark. Signed-off-by: Amir Goldstein --- fs/notify/fsnotify.c | 22 ++++++++++++++++++---- include/linux/fsnotify.h | 4 +--- include/linux/fsnotify_backend.h | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index efa5c1c4908a..fa84aea47b20 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -367,6 +367,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, struct super_block *sb = to_tell->i_sb; struct inode *dir = S_ISDIR(to_tell->i_mode) ? to_tell : NULL; struct mount *mnt = NULL; + struct inode *inode = NULL; struct inode *child = NULL; int ret = 0; __u32 test_mask, marks_mask; @@ -377,6 +378,14 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, if (mask & FS_EVENT_ON_CHILD) child = fsnotify_data_inode(data, data_type); + /* + * If event is "on child" then to_tell is a watching parent. + * An event "on child" may be sent to mount/sb mark with parent/name + * info, but not appropriate for watching parent (e.g. FS_MOVE_SELF). + */ + if (!child || (mask & FS_EVENTS_POSS_ON_CHILD)) + inode = to_tell; + /* * Optimization: srcu_read_lock() has a memory barrier which can * be expensive. It protects walking the *_fsnotify_marks lists. @@ -384,14 +393,17 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, * SRCU because we have no references to any objects and do not * need SRCU to keep them "alive". */ - if (!to_tell->i_fsnotify_marks && !sb->s_fsnotify_marks && + if (!sb->s_fsnotify_marks && (!mnt || !mnt->mnt_fsnotify_marks) && + (!inode || !inode->i_fsnotify_marks) && (!child || !child->i_fsnotify_marks)) return 0; - marks_mask = to_tell->i_fsnotify_mask | sb->s_fsnotify_mask; + marks_mask = sb->s_fsnotify_mask; if (mnt) marks_mask |= mnt->mnt_fsnotify_mask; + if (inode) + marks_mask |= inode->i_fsnotify_mask; if (child) marks_mask |= child->i_fsnotify_mask; @@ -406,14 +418,16 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_type, iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); - iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] = - fsnotify_first_mark(&to_tell->i_fsnotify_marks); iter_info.marks[FSNOTIFY_OBJ_TYPE_SB] = fsnotify_first_mark(&sb->s_fsnotify_marks); if (mnt) { iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] = fsnotify_first_mark(&mnt->mnt_fsnotify_marks); } + if (inode) { + iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] = + fsnotify_first_mark(&inode->i_fsnotify_marks); + } if (child) { iter_info.marks[FSNOTIFY_OBJ_TYPE_CHILD] = fsnotify_first_mark(&child->i_fsnotify_marks); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index fe4f2bc5b4c2..61dccaf21e7b 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -131,7 +131,6 @@ 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 mask = FS_MOVE_SELF; const struct qstr *new_name = &moved->d_name; if (old_dir == new_dir) @@ -140,7 +139,6 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, if (isdir) { old_dir_mask |= FS_ISDIR; new_dir_mask |= FS_ISDIR; - mask |= FS_ISDIR; } fsnotify_name(old_dir, old_dir_mask, source, old_name, fs_cookie); @@ -149,7 +147,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, if (target) fsnotify_link_count(target); - fsnotify(source, mask, source, FSNOTIFY_EVENT_INODE, NULL, 0); + fsnotify_dentry(moved, FS_MOVE_SELF); audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE); } diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 6f0df110e9f8..acce2ec17edf 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -89,7 +89,7 @@ * It may include events that can be sent to an inode/sb/mount mark, but cannot * be sent to a parent watching children. */ -#define FS_EVENTS_POSS_TO_PARENT (FS_EVENTS_POSS_ON_CHILD) +#define FS_EVENTS_POSS_TO_PARENT (FS_EVENTS_POSS_ON_CHILD | FS_MOVE_SELF) /* Events that can be reported to backends */ #define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \ From patchwork Thu Jul 16 08:42:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666933 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1DED513B4 for ; Thu, 16 Jul 2020 08:43:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F280E20771 for ; Thu, 16 Jul 2020 08:43:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jF1vnyS8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728149AbgGPInF (ORCPT ); Thu, 16 Jul 2020 04:43:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728129AbgGPInD (ORCPT ); Thu, 16 Jul 2020 04:43:03 -0400 Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3E69C061755 for ; Thu, 16 Jul 2020 01:43:02 -0700 (PDT) Received: by mail-wm1-x342.google.com with SMTP id o8so9422027wmh.4 for ; Thu, 16 Jul 2020 01:43:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dnud4Xl7WkQXgoOhZ/+QvdEzXuyAhadoSpKQk8BvgHA=; b=jF1vnyS8k3C3Ab+lgsKPTqAQdLGvp0t002ysPZYJoTt72zmRazMxPTJiNKLYDoKV8E 3xY27msVu7FAFk4ilJ8Jl0c2pYQTktlAuSuC1XjYnVNS0hySnfkLuMHjrV4MXPfh0Use KlW7ij+XeuyBX1dvmFF5AYItZ9acJmDs1J0Pv/81py+163O7f5T4dRKsBr/WirP7nto7 fOjaXx1o5XU/RxoMvtJ2vAHsstttfK/q7rWC1t8g8NPiejOw/J/OPWfO6bq1Hmnd8SEy PLVG9QEyWfLTbiQnaoxnfDcwGRTL2ncDghgVaBpxxnmH3gbuQ+yRO9dP15/HWPlC5VzO M35Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dnud4Xl7WkQXgoOhZ/+QvdEzXuyAhadoSpKQk8BvgHA=; b=LlDajYlN3vqIDblBiLWJSBfXJszhqsdl8m5zthl4ayfphSPNhYYsy3rb65E8eyhsAm AhSYznW88i37iMTwc6NX4vIYit9ILrcQL05JAqLUdAUjtUYZXVZIKbnmcklHUOYZB1VK 0yukFlMy7A2uQResQJGLM9iqbL4UFi/DDAXWUJKNy7/fR+VNZaTYEFUyUfsHjYHTfVTl YYgmZGgktnK++nkez0TIXPWZSpCUqiM6mFpH4gh88HALeGBb3UQ1moYYDsKyW51nm/zY 0VHwJ8VRquAEkscsFOkIpEPIRzmb6WES0mkd1+EW/XHZTY1V9t1hHMBx8XgVNSBh0pZN mlug== X-Gm-Message-State: AOAM532gHlORd8JYZ1NKmnfuaQl+r772b6ZxAq8vx2ukNRTYLC4v3AYY dL3i3rit3QbcfUmNtj/BcQU= X-Google-Smtp-Source: ABdhPJwo/ShUiEFsysHbAiFvqGP0lfq2ahNhAkMCke8oJlCSSHDGvXdUIcDjnPRj8sDyxXNfRGVl7A== X-Received: by 2002:a1c:bcd4:: with SMTP id m203mr3300677wmf.124.1594888981377; Thu, 16 Jul 2020 01:43:01 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.43.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:43:00 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 18/22] fanotify: add basic support for FAN_REPORT_DIR_FID Date: Thu, 16 Jul 2020 11:42:26 +0300 Message-Id: <20200716084230.30611-19-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org For now, the flag is mutually exclusive with FAN_REPORT_FID. Events include a single info record of type FAN_EVENT_INFO_TYPE_DFID with a directory file handle. For now, events are only reported for: - Directory modification events - Events on children of a watching directory - Events on directory objects Soon, we will add support for reporting the parent directory fid for events on non-directories with filesystem/mount mark and support for reporting both parent directory fid and child fid. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 33 +++++++++++++- fs/notify/fanotify/fanotify_user.c | 71 +++++++++++++++++++++++++----- include/linux/fanotify.h | 2 +- include/uapi/linux/fanotify.h | 11 +++-- 4 files changed, 100 insertions(+), 17 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 1ec760960c93..4cbdb40e0d54 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -223,7 +223,7 @@ static int fanotify_get_response(struct fsnotify_group *group, static u32 fanotify_group_event_mask(struct fsnotify_group *group, struct fsnotify_iter_info *iter_info, u32 event_mask, const void *data, - int data_type) + int data_type, struct inode *dir) { __u32 marks_mask = 0, marks_ignored_mask = 0; __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS | @@ -243,6 +243,10 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, /* Path type events are only relevant for files and dirs */ if (!d_is_reg(path->dentry) && !d_can_lookup(path->dentry)) return 0; + } else if (!(fid_mode & FAN_REPORT_FID)) { + /* Do we have a directory inode to report? */ + if (!dir) + return 0; } fsnotify_foreach_obj_type(type) { @@ -399,6 +403,28 @@ static struct inode *fanotify_fid_inode(u32 event_mask, const void *data, return fsnotify_data_inode(data, data_type); } +/* + * The inode to use as identifier when reporting dir fid depends on the event. + * Report the modified directory inode on dirent modification events. + * Report the "victim" inode if "victim" is a directory. + * Report the parent inode if "victim" is not a directory and event is + * reported to parent. + * Otherwise, do not report dir fid. + */ +static struct inode *fanotify_dfid_inode(u32 event_mask, const void *data, + int data_type, struct inode *dir) +{ + struct inode *inode = fsnotify_data_inode(data, data_type); + + if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS) + return dir; + + if (S_ISDIR(inode->i_mode)) + return inode; + + return dir; +} + static struct fanotify_event *fanotify_alloc_path_event(const struct path *path, gfp_t gfp) { @@ -498,6 +524,9 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); bool name_event = false; + if ((fid_mode & FAN_REPORT_DIR_FID) && dir) + id = fanotify_dfid_inode(mask, data, data_type, dir); + /* * For queues with unlimited length lost events are not expected and * can possibly have security implications. Avoid losing events when @@ -608,7 +637,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask, BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 19); mask = fanotify_group_event_mask(group, iter_info, mask, data, - data_type); + data_type, dir); if (!mask) return 0; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 3842ef00b52e..e494400711c9 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -216,7 +216,7 @@ static int process_access_response(struct fsnotify_group *group, } static int copy_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh, - const char *name, size_t name_len, + int info_type, const char *name, size_t name_len, char __user *buf, size_t count) { struct fanotify_event_info_fid info = { }; @@ -229,7 +229,7 @@ static int copy_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh, pr_debug("%s: fh_len=%zu name_len=%zu, info_len=%zu, count=%zu\n", __func__, fh_len, name_len, info_len, count); - if (!fh_len || (name && !name_len)) + if (!fh_len) return 0; if (WARN_ON_ONCE(len < sizeof(info) || len > count)) @@ -239,8 +239,21 @@ static int copy_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh, * Copy event info fid header followed by variable sized file handle * and optionally followed by variable sized filename. */ - info.hdr.info_type = name_len ? FAN_EVENT_INFO_TYPE_DFID_NAME : - FAN_EVENT_INFO_TYPE_FID; + switch (info_type) { + case FAN_EVENT_INFO_TYPE_FID: + case FAN_EVENT_INFO_TYPE_DFID: + if (WARN_ON_ONCE(name_len)) + return -EFAULT; + break; + case FAN_EVENT_INFO_TYPE_DFID_NAME: + if (WARN_ON_ONCE(!name || !name_len)) + return -EFAULT; + break; + default: + return -EFAULT; + } + + info.hdr.info_type = info_type; info.hdr.len = len; info.fsid = *fsid; if (copy_to_user(buf, &info, sizeof(info))) @@ -304,8 +317,10 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, struct fanotify_event_metadata metadata; struct path *path = fanotify_event_path(event); struct fanotify_info *info = fanotify_event_info(event); + unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); struct file *f = NULL; int ret, fd = FAN_NOFD; + int info_type = 0; pr_debug("%s: group=%p event=%p\n", __func__, group, event); @@ -346,9 +361,10 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, /* Event info records order is: dir fid + name, child fid */ if (fanotify_event_dir_fh_len(event)) { + info_type = FAN_EVENT_INFO_TYPE_DFID_NAME; ret = copy_info_to_user(fanotify_event_fsid(event), fanotify_info_dir_fh(info), - fanotify_info_name(info), + info_type, fanotify_info_name(info), info->name_len, buf, count); if (ret < 0) return ret; @@ -358,9 +374,33 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, } if (fanotify_event_object_fh_len(event)) { + if (fid_mode == FAN_REPORT_FID || info_type) { + /* + * With only group flag FAN_REPORT_FID only type FID is + * reported. Second info record type is always FID. + */ + info_type = FAN_EVENT_INFO_TYPE_FID; + } else if ((event->mask & ALL_FSNOTIFY_DIRENT_EVENTS) || + (event->mask & FAN_ONDIR)) { + /* + * With group flag FAN_REPORT_DIR_FID, a single info + * record has type DFID for directory entry modification + * event and for event on a directory. + */ + info_type = FAN_EVENT_INFO_TYPE_DFID; + } else { + /* + * With group flags FAN_REPORT_DIR_FID|FAN_REPORT_FID, + * a single info record has type FID for event on a + * non-directory, when there is no directory to report. + * For example, on FAN_DELETE_SELF event. + */ + info_type = FAN_EVENT_INFO_TYPE_FID; + } + ret = copy_info_to_user(fanotify_event_fsid(event), fanotify_event_object_fh(event), - NULL, 0, buf, count); + info_type, NULL, 0, buf, count); if (ret < 0) return ret; @@ -861,6 +901,8 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) struct fsnotify_group *group; int f_flags, fd; struct user_struct *user; + unsigned int fid_mode = flags & FANOTIFY_FID_BITS; + unsigned int class = flags & FANOTIFY_CLASS_BITS; pr_debug("%s: flags=%x event_f_flags=%x\n", __func__, flags, event_f_flags); @@ -887,10 +929,19 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) return -EINVAL; } - if ((flags & FANOTIFY_FID_BITS) && - (flags & FANOTIFY_CLASS_BITS) != FAN_CLASS_NOTIF) + if (fid_mode && class != FAN_CLASS_NOTIF) return -EINVAL; + /* Reporting either object fid or dir fid */ + switch (fid_mode) { + case 0: + case FAN_REPORT_FID: + case FAN_REPORT_DIR_FID: + break; + default: + return -EINVAL; + } + user = get_current_user(); if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) { free_uid(user); @@ -926,7 +977,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) group->fanotify_data.f_flags = event_f_flags; init_waitqueue_head(&group->fanotify_data.access_waitq); INIT_LIST_HEAD(&group->fanotify_data.access_list); - switch (flags & FANOTIFY_CLASS_BITS) { + switch (class) { case FAN_CLASS_NOTIF: group->priority = FS_PRIO_0; break; @@ -1236,7 +1287,7 @@ COMPAT_SYSCALL_DEFINE6(fanotify_mark, */ static int __init fanotify_user_setup(void) { - BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 8); + BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 9); 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 bbbee11d2521..4ddac97b2bf7 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -18,7 +18,7 @@ #define FANOTIFY_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \ FAN_CLASS_PRE_CONTENT) -#define FANOTIFY_FID_BITS (FAN_REPORT_FID) +#define FANOTIFY_FID_BITS (FAN_REPORT_FID | FAN_REPORT_DIR_FID) #define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | FANOTIFY_FID_BITS | \ FAN_REPORT_TID | \ diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 7f2f17eacbf9..21afebf77fd7 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -53,6 +53,7 @@ /* Flags to determine fanotify event format */ #define FAN_REPORT_TID 0x00000100 /* event->pid is thread id */ #define FAN_REPORT_FID 0x00000200 /* Report unique file id */ +#define FAN_REPORT_DIR_FID 0x00000400 /* Report unique directory id */ /* Deprecated - do not use this in programs and do not add new flags here! */ #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \ @@ -117,6 +118,7 @@ struct fanotify_event_metadata { #define FAN_EVENT_INFO_TYPE_FID 1 #define FAN_EVENT_INFO_TYPE_DFID_NAME 2 +#define FAN_EVENT_INFO_TYPE_DFID 3 /* Variable length info record following event metadata */ struct fanotify_event_info_header { @@ -126,10 +128,11 @@ struct fanotify_event_info_header { }; /* - * Unique file identifier info record. This is used both for - * FAN_EVENT_INFO_TYPE_FID records and for FAN_EVENT_INFO_TYPE_DFID_NAME - * records. For FAN_EVENT_INFO_TYPE_DFID_NAME there is additionally a null - * terminated name immediately after the file handle. + * Unique file identifier info record. + * This structure is used for records of types FAN_EVENT_INFO_TYPE_FID, + * FAN_EVENT_INFO_TYPE_DFID and FAN_EVENT_INFO_TYPE_DFID_NAME. + * For FAN_EVENT_INFO_TYPE_DFID_NAME there is additionally a null terminated + * name immediately after the file handle. */ struct fanotify_event_info_fid { struct fanotify_event_info_header hdr; From patchwork Thu Jul 16 08:42:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666935 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 00EA613B4 for ; Thu, 16 Jul 2020 08:43:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DB36B20771 for ; Thu, 16 Jul 2020 08:43:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GMqFLXpM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728194AbgGPInF (ORCPT ); Thu, 16 Jul 2020 04:43:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727870AbgGPInE (ORCPT ); Thu, 16 Jul 2020 04:43:04 -0400 Received: from mail-wr1-x441.google.com (mail-wr1-x441.google.com [IPv6:2a00:1450:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1508CC08C5C0 for ; Thu, 16 Jul 2020 01:43:04 -0700 (PDT) Received: by mail-wr1-x441.google.com with SMTP id q5so6138342wru.6 for ; Thu, 16 Jul 2020 01:43:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vhDNObLrXWXob7tK3FGK11dk0qSJrpvMIDyeT/vJCcI=; b=GMqFLXpMta79hTvj2k6adCiOtAM9G510c9tTRzXV2xI6I9uS7b3tkPSHdL4RRP/hEK Nmh3wdjKE19PeP6VcjIdRFbQhBvVGh4r9fNBIYtMlZh2gAFcMMAiRnSztawJLCvtj+9E LW4gWXv6IZCpd6wJ6BFCHshLdzv7M3FxHP5iUV696hyMTpvw5s91vHgwXrYzmQa6zcdG lgeFdI23FG6qJPO5tS56P85rMqAaPtWYb0yCB5xJmQNq48Y3HmZJxcV7faDQiL2+i/IC JsePsv3C17VOczGp/iiTO4GzBwYqo1K4xq5Y/5iP82Qk5HpyejxBtikeJJVCU0gdWRNo rj2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vhDNObLrXWXob7tK3FGK11dk0qSJrpvMIDyeT/vJCcI=; b=qQgpduFXZSwbJ+DFWCKN3xbkhfGN286favUmO1/Q78WVrlToKDtDseeddvNNrNQ+IN 72Btw11jCsCxa9L8tvhIKpq7ffzNxe3tzbPleStgfpq+sojX4FTXf8eoCNB7ng5Ukvwz 9FxOscJQiUGDZFwb9YZzoqkBdNvb137rVR8mMkUBNbqUnV/u01J4wBY/w7yVtT5AgSFb exF0TG4g/AkMwfRJkgeh+eV43aEogtjhfHXAcpGVLE0W+9R7wsChK0YotpT1ptia7N/F 9cD68mpMg0ZVJdyv4vhVLR7piptih3Js6BukaQWbGab+dAzBeOH+W6anl4nOcoae1A9x 4ChA== X-Gm-Message-State: AOAM532vX3ytC2jmD9HTD/txX/bu+d+SetldaMCcPD6JYLihigSpRxZ0 tekK+nujdsgGzzqq1BmYs6O7iYaf X-Google-Smtp-Source: ABdhPJzk6cen8OSBr+tI9FlOjPb8QVu6VY0AaRDJOEhbOmFL4/62AZzh/haOxXNuUbYjmhp+TMb0hQ== X-Received: by 2002:a5d:400b:: with SMTP id n11mr3932255wrp.74.1594888982867; Thu, 16 Jul 2020 01:43:02 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.43.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:43:02 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 19/22] fanotify: report events with parent dir fid to sb/mount/non-dir marks Date: Thu, 16 Jul 2020 11:42:27 +0300 Message-Id: <20200716084230.30611-20-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In a group with flag FAN_REPORT_DIR_FID, when adding an inode mark with FAN_EVENT_ON_CHILD, events on non-directory children are reported with the fid of the parent. When adding a filesystem or mount mark or mark on a non-dir inode, we want to report events that are "possible on child" (e.g. open/close) also with fid of the parent, as if the victim inode's parent is interested in events "on child". Some events, currently only FAN_MOVE_SELF, should be reported to a sb/mount/non-dir mark with parent fid even though they are not reported to a watching parent. To get the desired behavior we set the flag FAN_EVENT_ON_CHILD on all the sb/mount/non-dir mark masks in a group with FAN_REPORT_DIR_FID. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 3 +-- fs/notify/fanotify/fanotify_user.c | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 4cbdb40e0d54..09331b0acaf2 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -272,8 +272,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, */ if (event_mask & FS_EVENT_ON_CHILD && type != FSNOTIFY_OBJ_TYPE_CHILD && - (type != FSNOTIFY_OBJ_TYPE_INODE || - !(mark->mask & FS_EVENT_ON_CHILD))) + !(mark->mask & FS_EVENT_ON_CHILD)) continue; marks_mask |= mark->mask; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index e494400711c9..7caa64d028ba 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1220,6 +1220,13 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, if (mnt || !S_ISDIR(inode->i_mode)) { mask &= ~FAN_EVENT_ON_CHILD; umask = FAN_EVENT_ON_CHILD; + /* + * If group needs to report parent fid, register for getting + * events with parent/name info for non-directory. + */ + if ((fid_mode & FAN_REPORT_DIR_FID) && + (flags & FAN_MARK_ADD) && !ignored) + mask |= FAN_EVENT_ON_CHILD; } /* create/update an inode mark */ From patchwork Thu Jul 16 08:42:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666937 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 58DAE138C for ; Thu, 16 Jul 2020 08:43:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A6DD20771 for ; Thu, 16 Jul 2020 08:43:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="POfKevVX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727898AbgGPInK (ORCPT ); Thu, 16 Jul 2020 04:43:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728183AbgGPInF (ORCPT ); Thu, 16 Jul 2020 04:43:05 -0400 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AEF9C061755 for ; Thu, 16 Jul 2020 01:43:05 -0700 (PDT) Received: by mail-wm1-x341.google.com with SMTP id w3so10624436wmi.4 for ; Thu, 16 Jul 2020 01:43:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=r2qIPpe5/tmuFWIi0AmxdIUWuXImXcUu5bhQigOj0Tk=; b=POfKevVXqdOqFQWrr/izQHSv4Da/sFPQ6M2emHjCdRj2qHOh02vIaGvPgXPgwjibBi AOSSr6otsQJVGqxWPLKT+To+OWKebapC2gnwBGThIzHbJdJ7yd75s5Q+KKRpVPi7v3qY Sc+aWCA6n8thVSgpCCTaeP03kb0HyiSWUY2hT0PSeJvxJtMk0CaaBIMO7NxSRbVol/gP jLOgtMe/f9N2y1FG1FwN1SkDTO06QPvecipvwyXT7x2hck8b2F26oxOscH/jS5mrfI0P UE6y+G1daajpM6V+1O9wssVYje+wJ07B07counC6WPOmulbwfUoAup51LLvviAYvSZFB oOjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=r2qIPpe5/tmuFWIi0AmxdIUWuXImXcUu5bhQigOj0Tk=; b=nlu7c4OAJdNdjXmpQgIstdx8kuic9QdTBOlyyLc1DyUBwpYyyxUb0JUxnM/CYgJifT Kj9iyrbBYhw1fWUC647dKStgVelvmAeO2fvGtII0ja+QMUrtQfIjEQjpt6Cau8MDgNEa caQKCgZqOpDpzB1ufNtIb4QqS/2CycmgV00Ba0i9D73fYIGI73/kTp3lYG8FXIWH8VLK 2OXm/gTdBP24s//4ybtXf8Dcfu2K8mQwLy0TK76eeAg4cpvEnoXgrinxvL0s7weGjhIx rCWNjDEjsQinmgu5Y7g+6OzMCrwkxXnfELmst93V4EEheuASg0kU7tGXN9OMEH8GtIy6 U2zg== X-Gm-Message-State: AOAM532pzkrwy5/gQZWHLta8bveAegZcZ+rRDxUmmTIEjCIQW89fTN8q s4w/NzPRYLe6D448dt586ZEgS0N2 X-Google-Smtp-Source: ABdhPJxB6gLuFJTC2BSWuqOLl3W6LPjbeUC586TbZ5HIr9eck59yyuKO6OA0I7d/UzvIQzea1odH/g== X-Received: by 2002:a1c:6246:: with SMTP id w67mr3275188wmb.42.1594888984110; Thu, 16 Jul 2020 01:43:04 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.43.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:43:03 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 20/22] fanotify: add support for FAN_REPORT_NAME Date: Thu, 16 Jul 2020 11:42:28 +0300 Message-Id: <20200716084230.30611-21-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Introduce a new fanotify_init() flag FAN_REPORT_NAME. It requires the flag FAN_REPORT_DIR_FID and there is a constant for setting both flags named FAN_REPORT_DFID_NAME. For a group with flag FAN_REPORT_NAME, the parent fid and name are reported for directory entry modification events (create/detete/move) and for events on non-directory objects. Events on directories themselves are reported with their own fid and "." as the name. The parent fid and name are reported with an info record of type FAN_EVENT_INFO_TYPE_DFID_NAME, similar to the way that parent fid is reported with into type FAN_EVENT_INFO_TYPE_DFID, but with an appended null terminated name string. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 18 +++++++++++- fs/notify/fanotify/fanotify_user.c | 45 ++++++++++++++++++++++++------ include/linux/fanotify.h | 2 +- include/uapi/linux/fanotify.h | 4 +++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 09331b0acaf2..c77b37eb33a9 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -523,9 +523,25 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); bool name_event = false; - if ((fid_mode & FAN_REPORT_DIR_FID) && dir) + if ((fid_mode & FAN_REPORT_DIR_FID) && dir) { id = fanotify_dfid_inode(mask, data, data_type, dir); + /* + * We record file name only in a group with FAN_REPORT_NAME + * and when we have a directory inode to report. + * + * For directory entry modification event, we record the fid of + * the directory and the name of the modified entry. + * + * For event on non-directory that is reported to parent, we + * record the fid of the parent and the name of the child. + */ + if ((fid_mode & FAN_REPORT_NAME) && + ((mask & ALL_FSNOTIFY_DIRENT_EVENTS) || + !(mask & FAN_ONDIR))) + name_event = true; + } + /* * For queues with unlimited length lost events are not expected and * can possibly have security implications. Avoid losing events when diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 7caa64d028ba..6b839790cb42 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -64,18 +64,27 @@ static int fanotify_fid_info_len(int fh_len, int name_len) return roundup(FANOTIFY_INFO_HDR_LEN + info_len, FANOTIFY_EVENT_ALIGN); } -static int fanotify_event_info_len(struct fanotify_event *event) +static int fanotify_event_info_len(unsigned int fid_mode, + struct fanotify_event *event) { struct fanotify_info *info = fanotify_event_info(event); int dir_fh_len = fanotify_event_dir_fh_len(event); int fh_len = fanotify_event_object_fh_len(event); int info_len = 0; + int dot_len = 0; - if (dir_fh_len) + if (dir_fh_len) { info_len += fanotify_fid_info_len(dir_fh_len, info->name_len); + } else if ((fid_mode & FAN_REPORT_NAME) && (event->mask & FAN_ONDIR)) { + /* + * With group flag FAN_REPORT_NAME, if name was not recorded in + * event on a directory, we will report the name ".". + */ + dot_len = 1; + } if (fh_len) - info_len += fanotify_fid_info_len(fh_len, 0); + info_len += fanotify_fid_info_len(fh_len, dot_len); return info_len; } @@ -91,6 +100,7 @@ static struct fanotify_event *get_one_event(struct fsnotify_group *group, { size_t event_size = FAN_EVENT_METADATA_LEN; struct fanotify_event *event = NULL; + unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS); pr_debug("%s: group=%p count=%zd\n", __func__, group, count); @@ -98,8 +108,8 @@ static struct fanotify_event *get_one_event(struct fsnotify_group *group, if (fsnotify_notify_queue_is_empty(group)) goto out; - if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS)) { - event_size += fanotify_event_info_len( + if (fid_mode) { + event_size += fanotify_event_info_len(fid_mode, FANOTIFY_E(fsnotify_peek_first_event(group))); } @@ -325,7 +335,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, pr_debug("%s: group=%p event=%p\n", __func__, group, event); metadata.event_len = FAN_EVENT_METADATA_LEN + - fanotify_event_info_len(event); + fanotify_event_info_len(fid_mode, event); metadata.metadata_len = FAN_EVENT_METADATA_LEN; metadata.vers = FANOTIFY_METADATA_VERSION; metadata.reserved = 0; @@ -374,12 +384,25 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, } if (fanotify_event_object_fh_len(event)) { + const char *dot = NULL; + int dot_len = 0; + if (fid_mode == FAN_REPORT_FID || info_type) { /* * With only group flag FAN_REPORT_FID only type FID is * reported. Second info record type is always FID. */ info_type = FAN_EVENT_INFO_TYPE_FID; + } else if ((fid_mode & FAN_REPORT_NAME) && + (event->mask & FAN_ONDIR)) { + /* + * With group flag FAN_REPORT_NAME, if name was not + * recorded in an event on a directory, report the + * name "." with info type DFID_NAME. + */ + info_type = FAN_EVENT_INFO_TYPE_DFID_NAME; + dot = "."; + dot_len = 1; } else if ((event->mask & ALL_FSNOTIFY_DIRENT_EVENTS) || (event->mask & FAN_ONDIR)) { /* @@ -400,7 +423,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, ret = copy_info_to_user(fanotify_event_fsid(event), fanotify_event_object_fh(event), - info_type, NULL, 0, buf, count); + info_type, dot, dot_len, buf, count); if (ret < 0) return ret; @@ -932,11 +955,15 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) if (fid_mode && class != FAN_CLASS_NOTIF) return -EINVAL; - /* Reporting either object fid or dir fid */ + /* + * Reporting either object fid or dir fid. + * Child name is reported with parent fid so requires dir fid. + */ switch (fid_mode) { case 0: case FAN_REPORT_FID: case FAN_REPORT_DIR_FID: + case FAN_REPORT_DFID_NAME: break; default: return -EINVAL; @@ -1294,7 +1321,7 @@ COMPAT_SYSCALL_DEFINE6(fanotify_mark, */ static int __init fanotify_user_setup(void) { - BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 9); + BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 10); 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 4ddac97b2bf7..3e9c56ee651f 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -18,7 +18,7 @@ #define FANOTIFY_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \ FAN_CLASS_PRE_CONTENT) -#define FANOTIFY_FID_BITS (FAN_REPORT_FID | FAN_REPORT_DIR_FID) +#define FANOTIFY_FID_BITS (FAN_REPORT_FID | FAN_REPORT_DFID_NAME) #define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | FANOTIFY_FID_BITS | \ FAN_REPORT_TID | \ diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 21afebf77fd7..fbf9c5c7dd59 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -54,6 +54,10 @@ #define FAN_REPORT_TID 0x00000100 /* event->pid is thread id */ #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 */ + +/* Convenience macro - FAN_REPORT_NAME requires FAN_REPORT_DIR_FID */ +#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME) /* 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 Thu Jul 16 08:42:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666941 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B3C59138C for ; Thu, 16 Jul 2020 08:43:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 95FF520775 for ; Thu, 16 Jul 2020 08:43:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="culh9SIT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728207AbgGPInL (ORCPT ); Thu, 16 Jul 2020 04:43:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727870AbgGPInI (ORCPT ); Thu, 16 Jul 2020 04:43:08 -0400 Received: from mail-wm1-x341.google.com (mail-wm1-x341.google.com [IPv6:2a00:1450:4864:20::341]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3286C08C5C0 for ; Thu, 16 Jul 2020 01:43:06 -0700 (PDT) Received: by mail-wm1-x341.google.com with SMTP id j18so9428767wmi.3 for ; Thu, 16 Jul 2020 01:43:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iad1S2lFhDhoRYQbO5m1a69RfmaoOh0Vt4HIwiGJtvE=; b=culh9SIT8vaBAQzI+0OUictpGk0I06cJFwrqGfpYUT2uePJehV0epbc2FHHoQYE6VV ofPhQMOBpdGcVmopSuv1GFZl3InjhNZtAR732kanxniJK8PpH756L323WarHEsyaqNmH K7PuOmSL95lgbVAvV0f/lK1HaVaVzJcpefMi/9gjljq49LLpgawdX971jLV2/hTX3B7v 4Y/46IPeNIiivLxTH6pWs6mt2EpwDQbstvkHI9oBnMvxaA0397bc79ytt3b4FBlzBRxK 9MgJy1a72G5HjzQm5bLXoNapS3wOJwB5T4m4d+ilB94SDXuiDlYIqI8tOQgFJo0kWqRR A/ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iad1S2lFhDhoRYQbO5m1a69RfmaoOh0Vt4HIwiGJtvE=; b=i/ljRUxYsOg1HUY3v+rPjRm4BKUYDp4Q7ZwAoiz0ZPC/G32knVQF+e4JkSrUSlmYJQ uhSj12vBNiykIxPtlqtDOG9qYG6ksJ16uGaXqto3RQnKxh1hoK+Q/f2LHwlga6tKP78V 4bcbnlWOa3FpgflqiDyv3ow/g2/KJEB3+cYiw46r+94f6qT+IUKxePHrQcwvhH/4go2G CtWFRtI1wwAUqYbCf/1RkYugWmBT1Ro6zYL0TqPPsAa/PNQWBUcZ7HgVzo/hOJd0HFad ld3qFfPO6X9dsP6BnBEwp/q7sQkWXvYZ77DWyUGnBu0gMRViSGhO/XINb1nIn800jGDn 8Low== X-Gm-Message-State: AOAM533sQk9wLJXYVhNFukEehKQuKchxKdbXdIkOzTSopj2YwtYO47nG xJZuelFpcGsw2IrYjidjy04= X-Google-Smtp-Source: ABdhPJwBq3ariwY8bMkJcPlkE22CHnHzz78WUPG0IY6q4iI7R4CFmOJjjS/ouxiC3cfIhcsOc1TvNQ== X-Received: by 2002:a7b:c403:: with SMTP id k3mr3311839wmi.35.1594888985506; Thu, 16 Jul 2020 01:43:05 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.43.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:43:04 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 21/22] fanotify: report parent fid + name + child fid Date: Thu, 16 Jul 2020 11:42:29 +0300 Message-Id: <20200716084230.30611-22-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org For a group with fanotify_init() flag FAN_REPORT_DFID_NAME, the parent fid and name are reported for events on non-directory objects with an info record of type FAN_EVENT_INFO_TYPE_DFID_NAME. If the group also has the init flag FAN_REPORT_FID, the child fid is also reported with another info record that follows the first info record. The second info record is the same info record that would have been reported to a group with only FAN_REPORT_FID flag. When the child fid needs to be recorded, the variable size struct fanotify_name_event is preallocated with enough space to store the child fh between the dir fh and the name. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 30 ++++++++++++++++++++++++++---- fs/notify/fanotify/fanotify.h | 8 +++++++- fs/notify/fanotify/fanotify_user.c | 3 ++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index c77b37eb33a9..1d8eb886fe08 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -479,15 +479,22 @@ static struct fanotify_event *fanotify_alloc_fid_event(struct inode *id, static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, __kernel_fsid_t *fsid, const struct qstr *file_name, + struct inode *child, gfp_t gfp) { struct fanotify_name_event *fne; struct fanotify_info *info; - struct fanotify_fh *dfh; + struct fanotify_fh *dfh, *ffh; unsigned int dir_fh_len = fanotify_encode_fh_len(id); + unsigned int child_fh_len = fanotify_encode_fh_len(child); unsigned int size; + if (WARN_ON_ONCE(dir_fh_len % FANOTIFY_FH_HDR_LEN)) + child_fh_len = 0; + size = sizeof(*fne) + FANOTIFY_FH_HDR_LEN + dir_fh_len; + if (child_fh_len) + size += FANOTIFY_FH_HDR_LEN + child_fh_len; if (file_name) size += file_name->len + 1; fne = kmalloc(size, gfp); @@ -500,11 +507,15 @@ static struct fanotify_event *fanotify_alloc_name_event(struct inode *id, fanotify_info_init(info); dfh = fanotify_info_dir_fh(info); info->dir_fh_totlen = fanotify_encode_fh(dfh, id, dir_fh_len, 0); + if (child_fh_len) { + ffh = fanotify_info_file_fh(info); + info->file_fh_totlen = fanotify_encode_fh(ffh, child, child_fh_len, 0); + } if (file_name) fanotify_info_copy_name(info, file_name); - pr_debug("%s: ino=%lu size=%u dir_fh_len=%u name_len=%u name='%.*s'\n", - __func__, id->i_ino, size, dir_fh_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, info->name_len, info->name_len, fanotify_info_name(info)); return &fne->fae; @@ -521,9 +532,19 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, struct inode *id = fanotify_fid_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 inode *child = NULL; bool name_event = false; if ((fid_mode & FAN_REPORT_DIR_FID) && dir) { + /* + * With both flags FAN_REPORT_DIR_FID and FAN_REPORT_FID, we + * report the child fid for events reported on a non-dir child + * in addition to reporting the parent fid and child name. + */ + if ((fid_mode & FAN_REPORT_FID) && + (mask & FAN_EVENT_ON_CHILD) && !(mask & FAN_ONDIR)) + child = id; + id = fanotify_dfid_inode(mask, data, data_type, dir); /* @@ -559,7 +580,8 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, if (fanotify_is_perm_event(mask)) { event = fanotify_alloc_perm_event(path, gfp); } else if (name_event && file_name) { - event = fanotify_alloc_name_event(id, fsid, file_name, gfp); + event = fanotify_alloc_name_event(id, fsid, file_name, child, + gfp); } else if (fid_mode) { event = fanotify_alloc_fid_event(id, fsid, gfp); } else { diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 12c204b1489f..896c819a1786 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -193,6 +193,8 @@ static inline struct fanotify_fh *fanotify_event_object_fh( { if (event->type == FANOTIFY_EVENT_TYPE_FID) return &FANOTIFY_FE(event)->object_fh; + else if (event->type == FANOTIFY_EVENT_TYPE_FID_NAME) + return fanotify_info_file_fh(&FANOTIFY_NE(event)->info); else return NULL; } @@ -208,9 +210,13 @@ static inline struct fanotify_info *fanotify_event_info( static inline int fanotify_event_object_fh_len(struct fanotify_event *event) { + struct fanotify_info *info = fanotify_event_info(event); struct fanotify_fh *fh = fanotify_event_object_fh(event); - return fh ? fh->len : 0; + if (info) + return info->file_fh_totlen ? fh->len : 0; + else + return fh ? fh->len : 0; } static inline int fanotify_event_dir_fh_len(struct fanotify_event *event) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 6b839790cb42..be328d7ee283 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -956,14 +956,15 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) return -EINVAL; /* - * Reporting either object fid or dir fid. * Child name is reported with parent fid so requires dir fid. + * If reporting child name, we can report both child fid and dir fid. */ switch (fid_mode) { case 0: case FAN_REPORT_FID: case FAN_REPORT_DIR_FID: case FAN_REPORT_DFID_NAME: + case FAN_REPORT_DFID_NAME | FAN_REPORT_FID: break; default: return -EINVAL; From patchwork Thu Jul 16 08:42:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11666939 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 13C0C1510 for ; Thu, 16 Jul 2020 08:43:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EC94720771 for ; Thu, 16 Jul 2020 08:43:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SG7jEahs" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728183AbgGPInL (ORCPT ); Thu, 16 Jul 2020 04:43:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727883AbgGPInI (ORCPT ); Thu, 16 Jul 2020 04:43:08 -0400 Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F38FAC08C5CE for ; Thu, 16 Jul 2020 01:43:07 -0700 (PDT) Received: by mail-wm1-x342.google.com with SMTP id l2so10660478wmf.0 for ; Thu, 16 Jul 2020 01:43:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yhHqDPQ8gq54q6YqOZYEa8VhIz78YcgAJGkNbv5c3ps=; b=SG7jEahsULDXup5dXHQe2M0SsJEyvUjwn3oUWDcdIUE1A/5KTKJMbh1RmBcXwNGeMW nug0PLCXQrHeFNSddxtoidSk7ZlDWwShFHuPcaatQcnGf3vfV8DZKyMtB1aRZzMVENm5 2cIuEl4i+e3o1ST2SOu/TbJLdwi4PkDWYNRLcUml/VC2Tgvng4cx5bu9aKwYI+W1C+g8 Patl4cmAl4I6avCOPVTqXVJdLky9ev5TtVA2NIU3Hkmko6ezCapAfcVzrn1UxEYnmHlM eOhAQQGP9hySkgQudZpbgMza0SMcHX+c3u8DIL3Lv1xTwjSOVrd6hdZ3vDt0a9GtcgN7 d1rQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yhHqDPQ8gq54q6YqOZYEa8VhIz78YcgAJGkNbv5c3ps=; b=BCIbsJIyAL8ia5i0VguO2SKv6YdbHpZgjZJ61R3u91lsdVIkF+EOeLbm/4xZV485vx PP4n/PsDOR62zuM3qpRlWltK8y2+tPiDIjxzdxY21JMc0VAszlvuxgjZWTNtNihnZeU1 D39DYkZc8dUzQ8jsDej/mamnL0XddcfHCF6oZLMs1f4ALJq1PRP3vdrA2aIKQi6511Qs ErQZbroSpG2I6wxL28XHzkWi5qAD7dr85WjEl8Jb4Czd55s7umb0ZqEnIPh1/1Wj3xys wEmzlXSxDAPjPbOjyT9QKIfLCahVWcSlpmxhQ8HSJJC7OjWD4kL3kbh9Suge8bO3OUlu MNgQ== X-Gm-Message-State: AOAM532dXKD3I7jPu6YJK7xG2tZza/RnP8scBSGGeu+JDoFExvW9n4hw O4Xv19Hb6Ic0E8c0JyBVtlk= X-Google-Smtp-Source: ABdhPJyLpg1MBTuLrj3FRTvgJyW0DoxEcMwXiqPpgeSypY3HFavm+dztaJauqlw4DLj7MK24BPlU/w== X-Received: by 2002:a1c:8117:: with SMTP id c23mr3153655wmd.157.1594888986672; Thu, 16 Jul 2020 01:43:06 -0700 (PDT) Received: from localhost.localdomain ([141.226.183.23]) by smtp.gmail.com with ESMTPSA id j75sm8509977wrj.22.2020.07.16.01.43.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2020 01:43:06 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v5 22/22] fanotify: report parent fid + child fid Date: Thu, 16 Jul 2020 11:42:30 +0300 Message-Id: <20200716084230.30611-23-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200716084230.30611-1-amir73il@gmail.com> References: <20200716084230.30611-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add support for FAN_REPORT_FID | FAN_REPORT_DIR_FID. Internally, it is implemented as a private case of reporting both parent and child fids and name, the parent and child fids are recorded in a variable length fanotify_name_event, but there is no name. It should be noted that directory modification events are recorded in fixed size fanotify_fid_event when not reporting name, just like with group flags FAN_REPORT_FID. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 16 +++++++++++----- fs/notify/fanotify/fanotify_user.c | 15 ++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 1d8eb886fe08..8cb4fdeb567a 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -539,7 +539,7 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, /* * With both flags FAN_REPORT_DIR_FID and FAN_REPORT_FID, we * report the child fid for events reported on a non-dir child - * in addition to reporting the parent fid and child name. + * in addition to reporting the parent fid and maybe child name. */ if ((fid_mode & FAN_REPORT_FID) && (mask & FAN_EVENT_ON_CHILD) && !(mask & FAN_ONDIR)) @@ -556,11 +556,17 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, * * For event on non-directory that is reported to parent, we * record the fid of the parent and the name of the child. + * + * Even if not reporting name, we need a variable length + * fanotify_name_event if reporting both parent and child fids. */ - if ((fid_mode & FAN_REPORT_NAME) && - ((mask & ALL_FSNOTIFY_DIRENT_EVENTS) || - !(mask & FAN_ONDIR))) + if (!(fid_mode & FAN_REPORT_NAME)) { + name_event = !!child; + file_name = NULL; + } else if ((mask & ALL_FSNOTIFY_DIRENT_EVENTS) || + !(mask & FAN_ONDIR)) { name_event = true; + } } /* @@ -579,7 +585,7 @@ static struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, if (fanotify_is_perm_event(mask)) { event = fanotify_alloc_perm_event(path, gfp); - } else if (name_event && file_name) { + } else if (name_event && (file_name || child)) { event = fanotify_alloc_name_event(id, fsid, file_name, child, gfp); } else if (fid_mode) { diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index be328d7ee283..559de311deca 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -371,7 +371,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, /* Event info records order is: dir fid + name, child fid */ if (fanotify_event_dir_fh_len(event)) { - info_type = FAN_EVENT_INFO_TYPE_DFID_NAME; + info_type = info->name_len ? FAN_EVENT_INFO_TYPE_DFID_NAME : + FAN_EVENT_INFO_TYPE_DFID; ret = copy_info_to_user(fanotify_event_fsid(event), fanotify_info_dir_fh(info), info_type, fanotify_info_name(info), @@ -957,18 +958,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) /* * Child name is reported with parent fid so requires dir fid. - * If reporting child name, we can report both child fid and dir fid. + * We can report both child fid and dir fid with or without name. */ - switch (fid_mode) { - case 0: - case FAN_REPORT_FID: - case FAN_REPORT_DIR_FID: - case FAN_REPORT_DFID_NAME: - case FAN_REPORT_DFID_NAME | FAN_REPORT_FID: - break; - default: + if ((fid_mode & FAN_REPORT_NAME) && !(fid_mode & FAN_REPORT_DIR_FID)) return -EINVAL; - } user = get_current_user(); if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) {