From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83DBCC43387 for ; Thu, 10 Jan 2019 17:05:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 51C8520685 for ; Thu, 10 Jan 2019 17:05:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jA70CR/m" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729307AbfAJRFS (ORCPT ); Thu, 10 Jan 2019 12:05:18 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:33510 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729294AbfAJRFS (ORCPT ); Thu, 10 Jan 2019 12:05:18 -0500 Received: by mail-wm1-f66.google.com with SMTP id r24so139421wmh.0; Thu, 10 Jan 2019 09:05:15 -0800 (PST) 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=Ue5b2S4IAmlJ1MNnfX/p6A9UJzyNCBhQ0I+YP2hbWKY=; b=jA70CR/mZYc7m6XGsQppprhL0ochBQhnuX96tnDiVyllAnE0/5oQ8KWPOqT8zEVBcY hypu0W1vH77UhJHNMslHABzF6+ddlgS+ILv68h1ejBeXsiKzDRFltOLZ+3aeu4gU4wsg iq8wVTdvpG8JcTwSIh8z51vUO4X1IOgpviTtb29b1FXvF0RnnfKinHMTPSP4K4lkrrrB NRb+fDy+smROJ+gs4Cixi3gvY5OCAki+4LyaKRfRLcZISOr7MtlgEw4Jec9y2Fe8bWar 2PZPd2Ey9slCMhrOWchuwwz8PlV4QcqYNJqjyC32zk2MYQHLvBxWdtYQ76pfvoIDvV2K kSBw== 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=Ue5b2S4IAmlJ1MNnfX/p6A9UJzyNCBhQ0I+YP2hbWKY=; b=ahLm7WcOGJeNhopFWSMkBE+NoE4B90klzVW8V5d8NBZe0i/54smgXeX9vIUml8LKpH D873VtiEDZo7xCF1JW2xjFkbehV/+nZVBY0sv8mEoEhoF4g0RxEb09ZLfMKEC6sdFPxi wBHF4G52c15ZM5QuaX4Ggc6TjCBvw4IPFk+xgHGuA70Kp2OxkNkWkrCwy++R83xwtMbj Jk+SCwkDRvBUN+9G/IJLzSvdN5aS2nWrQ+AhXaDM/BJMnCPLH2jqLze4BNzpRS09wSqf xP1taR5iySR+qbvyBha4HWo00ibRF/AvDgjsgG3bITZ/59bK16+5i6EDhym65bdPbN7n OSkg== X-Gm-Message-State: AJcUukcIlWSm5vft34Gd/982Erlj0VXzKQU2Tl8z68ahVfr13vyV55Z/ POPnkKERB46wFWDGR8bqxfU= X-Google-Smtp-Source: ALg8bN6B+frsOoYYgRqTY3w5qCUOy6Y6925aKWTVy2UdJvlcHU8c7nNrpVl8/Jo+JupTnKY8ioPgiA== X-Received: by 2002:a1c:1d8e:: with SMTP id d136mr10353718wmd.98.1547139915278; Thu, 10 Jan 2019 09:05:15 -0800 (PST) Received: from amir-VirtualBox.ctera.local ([188.120.129.201]) by smtp.gmail.com with ESMTPSA id m4sm5725868wmi.3.2019.01.10.09.05.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 10 Jan 2019 09:05:14 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v5 17/17] fanotify: report FAN_ONDIR to listener with FAN_REPORT_FID Date: Thu, 10 Jan 2019 19:04:44 +0200 Message-Id: <20190110170444.30616-18-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190110170444.30616-1-amir73il@gmail.com> References: <20190110170444.30616-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org dirent modification events (create/delete/move) do not carry the child entry name/inode information. Instead, we report FAN_ONDIR for mkdir/rmdir so user can differentiate them from creat/unlink. This is consistent with inotify reporting IN_ISDIR with dirent events and is useful for implementing recursive directory tree watcher. We avoid merging 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. 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. Cc: Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 34 +++++++++++++++++++++++++++++++--- include/linux/fanotify.h | 2 +- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 4ba9c2233965..8ccca3cd866a 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -34,7 +34,16 @@ static bool should_merge(struct fsnotify_event *old_fsn, return old->path.mnt == new->path.mnt && old->path.dentry == new->path.dentry; } else if (fanotify_event_has_fid(old)) { - return fanotify_fid_equal(&old->fid, &new->fid, old->fh_len); + /* + * 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. + */ + return (old->mask & FS_ISDIR) == (new->mask & FS_ISDIR) && + fanotify_fid_equal(&old->fid, &new->fid, old->fh_len); } /* Do not merge events if we failed to encode fid */ @@ -112,6 +121,7 @@ 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; const struct path *path = data; struct fsnotify_mark *mark; int type; @@ -145,12 +155,30 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, marks_ignored_mask |= mark->ignored_mask; } + test_mask = event_mask & marks_mask & ~marks_ignored_mask; + + /* + * dirent modification events (create/delete/move) do not carry the + * child entry name/inode information. Instead, we report FAN_ONDIR + * for mkdir/rmdir so user can differentiate them from creat/unlink. + * + * 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. + */ + if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + /* Do not report FAN_ONDIR without any event */ + if (!(test_mask & ~FAN_ONDIR)) + return 0; + } else { + user_mask &= ~FAN_ONDIR; + } + if (event_mask & FS_ISDIR && !(marks_mask & FS_ISDIR & ~marks_ignored_mask)) return 0; - return event_mask & FANOTIFY_OUTGOING_EVENTS & marks_mask & - ~marks_ignored_mask; + return test_mask & user_mask; } static int fanotify_encode_fid(struct fanotify_event *event, diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index e9d45387089f..b79fa9bb7359 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -67,7 +67,7 @@ /* Events that may be reported to user */ #define FANOTIFY_OUTGOING_EVENTS (FANOTIFY_EVENTS | \ FANOTIFY_PERM_EVENTS | \ - FAN_Q_OVERFLOW) + FAN_Q_OVERFLOW | FAN_ONDIR) #define ALL_FANOTIFY_EVENT_BITS (FANOTIFY_OUTGOING_EVENTS | \ FANOTIFY_EVENT_FLAGS) -- 2.17.1