From patchwork Mon Feb 17 13:14:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386401 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 82B5814E3 for ; Mon, 17 Feb 2020 13:15:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 62F90207FD for ; Mon, 17 Feb 2020 13:15:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dsyHnhC1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729034AbgBQNPL (ORCPT ); Mon, 17 Feb 2020 08:15:11 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:36139 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729018AbgBQNPK (ORCPT ); Mon, 17 Feb 2020 08:15:10 -0500 Received: by mail-wm1-f67.google.com with SMTP id p17so18419087wma.1 for ; Mon, 17 Feb 2020 05:15:09 -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=LxZjALu8+JdM1LNMX2SUCsKVBqP/y1yL79+aF6PkR+s=; b=dsyHnhC1dEZSEVfdJunhTgYT6RpfFBKlVB8FAqSmut9LvXMU4yLJv1aJsiZy/oj828 6wASZhFWriGkUlM9HdFvnMHC7UM8HAIbZAZ3MYQUBCUb8jt9tADIRZ10f8cbV7BFI5sy 6iUBqOJEzS2OMDVZDd3Wfk03bQ4v+Qz4Oxcy3MIYtLXyu10f7/y8WtGu8yq5Wv2ToKPh NgWyFp6Kg4RJoM5CpeWQR0dS8ryoCtFKw3hR+pJEy0xaf1/HtbQ4v7tYs+PdaX84/3Tw X+SQuGPeZJSwWXrN0dX4r3SZ9d1D3INaD6jSQkNhqUrGatQfyvzRj1SW3aVACLHC0uGV tnXA== 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=LxZjALu8+JdM1LNMX2SUCsKVBqP/y1yL79+aF6PkR+s=; b=aD8mZxkCiPd0VJdw18Wyha0QY/D8Bztt75L0rMlFzS5e9CkZLEXcCc/pOgMFupQa7E Hrt6l671vpL49w9yqR+lpBPOAgCGCiGCN664+PzsYQZiKzmRaTb7RTJunNEYVYajk7Af oy7jX0AVmfJONSyeoXHwAmyS2c3IgiQxyYIH2g0FrSC0NXzzgWvKNxEUWUQMYgSRcPr/ ewShI3kADbfl1y6mkO+KVSfvmkhoFn80tzSym/pNTezKg9tFRyhJmAa0OCyHlftxgt2D bXYzTA8nhkWaSKB6Y0rGg4iafakqjSZcjM6ab+MFddpBCoQNRToieFL1gbSi5L5pgyDt KX7w== X-Gm-Message-State: APjAAAU40Ei3HutZK+3WBN2fYj43QIlHcx0mo3HEY1KO/qaqfqIz8J7Z UD5ojL7OnnmGlPcHZex8dCGrnZXT X-Google-Smtp-Source: APXvYqzxTJWdq8oRIU1Q+saM4dS/HZ5f+IFDG73EYLZD/5bk1x9GrYFOw3oCbYuVv+x5FQhTfKgdCg== X-Received: by 2002:a7b:c216:: with SMTP id x22mr22977938wmi.51.1581945308365; Mon, 17 Feb 2020 05:15:08 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:07 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 01/16] fsnotify: tidy up FS_ and FAN_ constants Date: Mon, 17 Feb 2020 15:14:40 +0200 Message-Id: <20200217131455.31107-2-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Order by value, so the free value ranges are easier to find. Signed-off-by: Amir Goldstein --- include/linux/fsnotify_backend.h | 11 +++++------ include/uapi/linux/fanotify.h | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 1915bdba2fad..db3cabb4600e 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -49,16 +49,15 @@ #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 */ -#define FS_ISDIR 0x40000000 /* event occurred against dir */ -#define FS_IN_ONESHOT 0x80000000 /* only send event once */ - -#define FS_DN_RENAME 0x10000000 /* file renamed */ -#define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */ - /* This inode cares about things that happen to its children. Always set for * dnotify and inotify. */ #define FS_EVENT_ON_CHILD 0x08000000 +#define FS_DN_RENAME 0x10000000 /* file renamed */ +#define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */ +#define FS_ISDIR 0x40000000 /* event occurred against dir */ +#define FS_IN_ONESHOT 0x80000000 /* only send event once */ + #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) /* diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index b9effa6f8503..2a1844edda47 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -25,9 +25,9 @@ #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ #define FAN_OPEN_EXEC_PERM 0x00040000 /* File open/exec in perm check */ -#define FAN_ONDIR 0x40000000 /* event occurred against dir */ +#define FAN_EVENT_ON_CHILD 0x08000000 /* Interested in child events */ -#define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ +#define FAN_ONDIR 0x40000000 /* Event occurred against dir */ /* helper events */ #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ From patchwork Mon Feb 17 13:14:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386399 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 6B08314E3 for ; Mon, 17 Feb 2020 13:15:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 42F30207FD for ; Mon, 17 Feb 2020 13:15:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZE09DfMr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729158AbgBQNPX (ORCPT ); Mon, 17 Feb 2020 08:15:23 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:54259 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729062AbgBQNPN (ORCPT ); Mon, 17 Feb 2020 08:15:13 -0500 Received: by mail-wm1-f67.google.com with SMTP id s10so17114155wmh.3 for ; Mon, 17 Feb 2020 05:15:11 -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=OWzfkGCr9PabkdnGvHygX5uWAudDgb/h4qPwf2CBTII=; b=ZE09DfMrf3qs8HBz6k/1g698JKrsxpTC5SQcfOsV0rZBypdM0nFYs7dQfapbhgoMyd FvCpNKJMF58rD9pr2X6y0RGQi6ncEr2qwp2uYWykDGRXJ+xt+vhw/51hrq2MThA6hN9I /2Nm8kvxe/SPibuYx+XP2EudF2D9kgpjYe9wDDa0ByYFkmdfNd5vb//cS0fv17fxs/46 1UhJb5B1AmCEpu8fEjIMTPZclSQ9VRogooEN0EA9E+zs6ulLn0iEJtVZCBfNM30gc19S aqxIJJ8H7KU8RjXDZUVhcPR8sqBcCEaAqbX8iy5eEXR5ObHuQSqH2v2TpFZ3nhArmvQV 5GQQ== 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=OWzfkGCr9PabkdnGvHygX5uWAudDgb/h4qPwf2CBTII=; b=Ilbc6rQYdIZPcN/II3e2VATgZV+n9xI0K8xSnwMWHQ7KLQiaIlXGLDknzAh9Ys3CDx OdXMR0BtGMQgAqgHBSp0irjf087u8nbJOVfM4Q0V96Yw5oauj/BTPOegM6IMVvykURDY dvxlVwHzdBW27GiIWz/Kldvdwxsqx9hjBjqAoavTQuen9NeOCroll6LggajGOHe89z9R cRTEyEk5Q0L/mkEtFTmme8KzJ5hWZzoTeOIbI5zfGOcq1Rl0c5soCf/Q9U5RFm/jsAEE WLBoT/m4mKeHxacyE02xbZ1+8J+taTr2tbuG9VmJxpx6LxQO+rRX4aMh6AKdcWViA5KX t1ZA== X-Gm-Message-State: APjAAAVozPUtTkO0ZbrvYtyXw0fuBTCtI8Qkv9hu1nVu2NnsO8lRj9/I SeiyScrVwl3bEDbseyUCjeA= X-Google-Smtp-Source: APXvYqzVGHPN1W/8dWacRgeXa+WSaKbWHwTAbylHj9uUhpB5XBFfuGjHuAwsLdjYVK81zV+1B2c2hg== X-Received: by 2002:a1c:5419:: with SMTP id i25mr22567290wmb.150.1581945309607; Mon, 17 Feb 2020 05:15:09 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:09 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 02/16] fsnotify: factor helpers fsnotify_dentry() and fsnotify_file() Date: Mon, 17 Feb 2020 15:14:41 +0200 Message-Id: <20200217131455.31107-3-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Most of the code in fsnotify hooks is boiler plate of one or the other. Signed-off-by: Amir Goldstein --- include/linux/fsnotify.h | 96 +++++++++++++++------------------------- 1 file changed, 36 insertions(+), 60 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a2d5d175d3c1..a87d4ab98da7 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -41,16 +41,36 @@ static inline int fsnotify_parent(const struct path *path, } /* - * Simple wrapper to consolidate calls fsnotify_parent()/fsnotify() when - * an event is on a path. + * Simple wrappers to consolidate calls fsnotify_parent()/fsnotify() when + * an event is on a file/dentry. */ -static inline int fsnotify_path(struct inode *inode, const struct path *path, - __u32 mask) +static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask) { - int ret = fsnotify_parent(path, NULL, mask); + struct inode *inode = d_inode(dentry); + if (S_ISDIR(inode->i_mode)) + mask |= FS_ISDIR; + + fsnotify_parent(NULL, dentry, mask); + fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); +} + +static inline int fsnotify_file(struct file *file, __u32 mask) +{ + const struct path *path = &file->f_path; + struct inode *inode = file_inode(file); + int ret; + + if (file->f_mode & FMODE_NONOTIFY) + return 0; + + if (S_ISDIR(inode->i_mode)) + mask |= FS_ISDIR; + + ret = fsnotify_parent(path, NULL, mask); if (ret) return ret; + return fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } @@ -58,8 +78,6 @@ static inline int fsnotify_path(struct inode *inode, const struct path *path, static inline int fsnotify_perm(struct file *file, int mask) { int ret; - const struct path *path = &file->f_path; - struct inode *inode = file_inode(file); __u32 fsnotify_mask = 0; if (file->f_mode & FMODE_NONOTIFY) @@ -70,7 +88,7 @@ static inline int fsnotify_perm(struct file *file, int mask) fsnotify_mask = FS_OPEN_PERM; if (file->f_flags & __FMODE_EXEC) { - ret = fsnotify_path(inode, path, FS_OPEN_EXEC_PERM); + ret = fsnotify_file(file, FS_OPEN_EXEC_PERM); if (ret) return ret; @@ -79,10 +97,7 @@ static inline int fsnotify_perm(struct file *file, int mask) fsnotify_mask = FS_ACCESS_PERM; } - if (S_ISDIR(inode->i_mode)) - fsnotify_mask |= FS_ISDIR; - - return fsnotify_path(inode, path, fsnotify_mask); + return fsnotify_file(file, fsnotify_mask); } /* @@ -229,15 +244,7 @@ static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry) */ static inline void fsnotify_access(struct file *file) { - const struct path *path = &file->f_path; - struct inode *inode = file_inode(file); - __u32 mask = FS_ACCESS; - - if (S_ISDIR(inode->i_mode)) - mask |= FS_ISDIR; - - if (!(file->f_mode & FMODE_NONOTIFY)) - fsnotify_path(inode, path, mask); + fsnotify_file(file, FS_ACCESS); } /* @@ -245,15 +252,7 @@ static inline void fsnotify_access(struct file *file) */ static inline void fsnotify_modify(struct file *file) { - const struct path *path = &file->f_path; - struct inode *inode = file_inode(file); - __u32 mask = FS_MODIFY; - - if (S_ISDIR(inode->i_mode)) - mask |= FS_ISDIR; - - if (!(file->f_mode & FMODE_NONOTIFY)) - fsnotify_path(inode, path, mask); + fsnotify_file(file, FS_MODIFY); } /* @@ -261,16 +260,12 @@ static inline void fsnotify_modify(struct file *file) */ static inline void fsnotify_open(struct file *file) { - const struct path *path = &file->f_path; - struct inode *inode = file_inode(file); __u32 mask = FS_OPEN; - if (S_ISDIR(inode->i_mode)) - mask |= FS_ISDIR; if (file->f_flags & __FMODE_EXEC) mask |= FS_OPEN_EXEC; - fsnotify_path(inode, path, mask); + fsnotify_file(file, mask); } /* @@ -278,16 +273,10 @@ static inline void fsnotify_open(struct file *file) */ static inline void fsnotify_close(struct file *file) { - const struct path *path = &file->f_path; - struct inode *inode = file_inode(file); - fmode_t mode = file->f_mode; - __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; - - if (S_ISDIR(inode->i_mode)) - mask |= FS_ISDIR; + __u32 mask = (file->f_mode & FMODE_WRITE) ? FS_CLOSE_WRITE : + FS_CLOSE_NOWRITE; - if (!(file->f_mode & FMODE_NONOTIFY)) - fsnotify_path(inode, path, mask); + fsnotify_file(file, mask); } /* @@ -295,14 +284,7 @@ static inline void fsnotify_close(struct file *file) */ static inline void fsnotify_xattr(struct dentry *dentry) { - struct inode *inode = dentry->d_inode; - __u32 mask = FS_ATTRIB; - - if (S_ISDIR(inode->i_mode)) - mask |= FS_ISDIR; - - fsnotify_parent(NULL, dentry, mask); - fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); + fsnotify_dentry(dentry, FS_ATTRIB); } /* @@ -311,7 +293,6 @@ static inline void fsnotify_xattr(struct dentry *dentry) */ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) { - struct inode *inode = dentry->d_inode; __u32 mask = 0; if (ia_valid & ATTR_UID) @@ -332,13 +313,8 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) if (ia_valid & ATTR_MODE) mask |= FS_ATTRIB; - if (mask) { - if (S_ISDIR(inode->i_mode)) - mask |= FS_ISDIR; - - fsnotify_parent(NULL, dentry, mask); - fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); - } + if (mask) + fsnotify_dentry(dentry, mask); } #endif /* _LINUX_FS_NOTIFY_H */ From patchwork Mon Feb 17 13:14:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386397 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 88FB5159A for ; Mon, 17 Feb 2020 13:15:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 69A2B208C4 for ; Mon, 17 Feb 2020 13:15:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FCG5s5F9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729086AbgBQNPN (ORCPT ); Mon, 17 Feb 2020 08:15:13 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:43876 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729018AbgBQNPM (ORCPT ); Mon, 17 Feb 2020 08:15:12 -0500 Received: by mail-wr1-f68.google.com with SMTP id r11so19636622wrq.10 for ; Mon, 17 Feb 2020 05:15:11 -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=fWbh+qHr8xslK5qL2cBUHYqV44AIJRERVFrOcrvwwPI=; b=FCG5s5F9VNPRGfWxxH7/WDdMikIjkauG8NPRDu6F5ZwagzXVVwOphnPmK/rCy5e1Dx 41Tg3wq5kmJjnmt/s/a7dq1xpPaCuU52ShMo/rpM2i6bCRb7qJ7W5PqFbQyofWuUkX6q ZCRyCx/ZshlJsiLU1qJK7Yif9Qc/yQ6S1+D5ot3qkh3jnSw9rC/n4d3/R129EvLBqwNK vDOieMV3XYVOisdD2zlVvURdN0UCjLJWUJP12H2t8imKKDxjNsi6k6eFXUXV1fYDKH0A bsXmUMiPN5vj8eN5bA0vBCViSpP3QlloEUkFG44KJNCgn9YD+oQ7Ik+vqaXvUA9eYsKx /Q/A== 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=fWbh+qHr8xslK5qL2cBUHYqV44AIJRERVFrOcrvwwPI=; b=l7dm20T3TJihKYXzfkWdJ6OGThiBIt/h07sgAn3EWSLw+IpE2JMnM8gP15w10RPW/6 /gkI5mhE0gundtjCwX7r/3QUMSl7vUCKsp5vBP0B+neSO/WODXNCkmmutIDqaxIl1DsL MSfOhSnNToBdpozBL1a3LsXgRzSxODhxGBI00Ev3OJ/oRWd4vlO6YjXR56WpenTo9SHh xHBoEfhQkddqkkk74hnMoUx4hbZCiOuO/6XqM3wJR344+L9br1MfimtW29gozMKceDWb PWwvqTkuZEKrF8K8z/pyoukoOanvqKr5Y7iIN7vojM3YWhSF9sc1B6EULy5N+bAJ+ZcL zPsw== X-Gm-Message-State: APjAAAXBPeCbzeG9VuAyfvPTSjHU+sdbZlibrdA/YnwYDs/fykQLJUjA qG8+ZR+FW1G2Eoe8L4t8LAg= X-Google-Smtp-Source: APXvYqwNDDn+xq0x/UYectA3U0tWKXWXvFPGRQ+IQ1LLFwENxiusf75Seurce42gyll8CjTXh2kbtQ== X-Received: by 2002:a5d:5704:: with SMTP id a4mr23556227wrv.198.1581945310754; Mon, 17 Feb 2020 05:15:10 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:10 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 03/16] fsnotify: funnel all dirent events through fsnotify_name() Date: Mon, 17 Feb 2020 15:14:42 +0200 Message-Id: <20200217131455.31107-4-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Factor out fsnotify_name() from fsnotify_dirent(), so it can also serve link and rename events and use this helper to report all directory entry change events. Both helpers return void because no caller checks their return value. Signed-off-by: Amir Goldstein --- include/linux/fsnotify.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a87d4ab98da7..420aca9fd5f4 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -18,16 +18,24 @@ #include /* - * Notify this @dir inode about a change in the directory entry @dentry. + * Notify this @dir inode about a change in a child directory entry. + * The directory entry may have turned positive or negative or its inode may + * have changed (i.e. renamed over). * * Unlike fsnotify_parent(), the event will be reported regardless of the * FS_EVENT_ON_CHILD mask on the parent inode. */ -static inline int fsnotify_dirent(struct inode *dir, struct dentry *dentry, - __u32 mask) +static inline void fsnotify_name(struct inode *dir, __u32 mask, + struct inode *child, + const struct qstr *name, u32 cookie) { - return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE, - &dentry->d_name, 0); + fsnotify(dir, mask, child, FSNOTIFY_EVENT_INODE, name, cookie); +} + +static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry, + __u32 mask) +{ + fsnotify_name(dir, mask, d_inode(dentry), &dentry->d_name, 0); } /* Notify this dentry's parent about a child's events. */ @@ -137,10 +145,8 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, mask |= FS_ISDIR; } - fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name, - fs_cookie); - fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name, - fs_cookie); + fsnotify_name(old_dir, old_dir_mask, source, old_name, fs_cookie); + fsnotify_name(new_dir, new_dir_mask, source, new_name, fs_cookie); if (target) fsnotify_link_count(target); @@ -195,12 +201,13 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) * Note: We have to pass also the linked inode ptr as some filesystems leave * new_dentry->d_inode NULL and instantiate inode pointer later */ -static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) +static inline void fsnotify_link(struct inode *dir, struct inode *inode, + struct dentry *new_dentry) { fsnotify_link_count(inode); audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE); - fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, &new_dentry->d_name, 0); + fsnotify_name(dir, FS_CREATE, inode, &new_dentry->d_name, 0); } /* From patchwork Mon Feb 17 13:14:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386387 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 5228F159A for ; Mon, 17 Feb 2020 13:15:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 27A4724685 for ; Mon, 17 Feb 2020 13:15:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="d/4f7Htv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729140AbgBQNPS (ORCPT ); Mon, 17 Feb 2020 08:15:18 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:37442 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729078AbgBQNPP (ORCPT ); Mon, 17 Feb 2020 08:15:15 -0500 Received: by mail-wm1-f68.google.com with SMTP id a6so18437669wme.2 for ; Mon, 17 Feb 2020 05:15:12 -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=n4QRMUmDbTzXCoJUleJyV2gfRI6X6+6qFC3WMs48hTs=; b=d/4f7Htv6BZDv0ad9/o6CAdSiR6dAT+XGqZft9zdaJoTrmG6/Lo8+/UFxwxH0bhTyx 7kGYh0CPPuGTZYUc5u0m++NjQpjz512z5HroArnSF06jK7o1EoIrnCA8HRodiXcnah7W HerVZjdfQF78oW9v/wdLz0hHg5qzxv+ISq29MIxNAXyibj1yLFrSY0MlaSS2xd4odR1V tfUAGbZxEM+Hrk1H2pIpvRGejsfLIbocMwQFPJHn5iI1bVhEcC+xtvvIoHjT7nUtzUnt BAkSWP0NTfDPgB3cmvT6kWN2FGwyouprdifMM/fwSYfvHUcIYo1dLsEZe0a4v10O9tDW +kMQ== 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=n4QRMUmDbTzXCoJUleJyV2gfRI6X6+6qFC3WMs48hTs=; b=W6582gAgQT1RcK3TXLBvKvEz960E65hIV6ai010vFM9gRblszX9B2yWUTRiJEJG8CR Hcm3ZEOQ5RnlFx3OSWHzB8ZDX4Dj6tee5KAivn/cu42AmJ1/wqds8iElyknr46qSVMwU LiCeoHrMeOj7C7OvCuSSEH1YncWZsPAf6tFffy9F50O+NuSvAqBrXmYDaonekMp7YN7Y TaGeAuYEhJBLSYJkIN5J6t9c+EGVn4UDQjzMO4gAyYm5ohfKptICnjl4CT7q9KFF0jmc yBiNsAFHyVQEtKpoQYYd3fZwe1R178AVPxdkZGU3PUs4ntDIMbRZqZqzjCUtc66r56bQ mPXA== X-Gm-Message-State: APjAAAV99WhhAz6c+Avefz64AcMg8nRuPseac+jTHzvT2x5ht0NY/bkn DCRQUCuDg9l5Qwk2G6uqU7Q= X-Google-Smtp-Source: APXvYqzla1EsEDnm+gbQE/y79h0xzllejg1rAGULRMtldn/Ctjyuol10rpChNivGLz7ED4QSrfvvOQ== X-Received: by 2002:a1c:7717:: with SMTP id t23mr23188802wmi.17.1581945312032; Mon, 17 Feb 2020 05:15:12 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:11 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 04/16] fsnotify: use helpers to access data by data_type Date: Mon, 17 Feb 2020 15:14:43 +0200 Message-Id: <20200217131455.31107-5-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Create helpers to access path and inode from different data types. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 18 +++++++-------- fs/notify/fsnotify.c | 5 ++-- fs/notify/inotify/inotify_fsnotify.c | 8 +++---- include/linux/fsnotify_backend.h | 34 ++++++++++++++++++++++++---- kernel/audit_fsnotify.c | 13 ++--------- kernel/audit_watch.c | 16 ++----------- 6 files changed, 48 insertions(+), 46 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 5778d1347b35..19ec7a4f4d50 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -151,7 +151,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, { __u32 marks_mask = 0, marks_ignored_mask = 0; __u32 test_mask, user_mask = FANOTIFY_OUTGOING_EVENTS; - const struct path *path = data; + const struct path *path = fsnotify_data_path(data, data_type); struct fsnotify_mark *mark; int type; @@ -160,7 +160,7 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, if (!FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { /* Do we have path to open a file descriptor? */ - if (data_type != FSNOTIFY_EVENT_PATH) + if (!path) return 0; /* Path type events are only relevant for files and dirs */ if (!d_is_reg(path->dentry) && !d_can_lookup(path->dentry)) @@ -269,11 +269,8 @@ static struct inode *fanotify_fid_inode(struct inode *to_tell, u32 event_mask, { if (event_mask & ALL_FSNOTIFY_DIRENT_EVENTS) return to_tell; - else if (data_type == FSNOTIFY_EVENT_INODE) - return (struct inode *)data; - else if (data_type == FSNOTIFY_EVENT_PATH) - return d_inode(((struct path *)data)->dentry); - return NULL; + + return (struct inode *)fsnotify_data_inode(data, data_type); } struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, @@ -284,6 +281,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, struct fanotify_event *event = NULL; gfp_t gfp = GFP_KERNEL_ACCOUNT; struct inode *id = fanotify_fid_inode(inode, mask, data, data_type); + const struct path *path = fsnotify_data_path(data, data_type); /* * For queues with unlimited length lost events are not expected and @@ -324,10 +322,10 @@ init: __maybe_unused if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { /* Report the event without a file identifier on encode error */ event->fh_type = fanotify_encode_fid(event, id, gfp, fsid); - } else if (data_type == FSNOTIFY_EVENT_PATH) { + } else if (path) { event->fh_type = FILEID_ROOT; - event->path = *((struct path *)data); - path_get(&event->path); + event->path = *path; + path_get(path); } else { event->fh_type = FILEID_INVALID; event->path.mnt = NULL; diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 46f225580009..a5d6467f89a0 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -318,6 +318,7 @@ static void fsnotify_iter_next(struct fsnotify_iter_info *iter_info) int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, const struct qstr *file_name, u32 cookie) { + const struct path *path = fsnotify_data_path(data, data_is); struct fsnotify_iter_info iter_info = {}; struct super_block *sb = to_tell->i_sb; struct mount *mnt = NULL; @@ -325,8 +326,8 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, int ret = 0; __u32 test_mask = (mask & ALL_FSNOTIFY_EVENTS); - if (data_is == FSNOTIFY_EVENT_PATH) { - mnt = real_mount(((const struct path *)data)->mnt); + if (path) { + mnt = real_mount(path->mnt); mnt_or_sb_mask |= mnt->mnt_fsnotify_mask; } /* An event "on child" is not intended for a mount/sb mark */ diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index d510223d302c..6bb98522bbfd 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -61,6 +61,7 @@ int inotify_handle_event(struct fsnotify_group *group, 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 inotify_inode_mark *i_mark; struct inotify_event_info *event; @@ -73,12 +74,9 @@ int inotify_handle_event(struct fsnotify_group *group, return 0; if ((inode_mark->mask & FS_EXCL_UNLINK) && - (data_type == FSNOTIFY_EVENT_PATH)) { - const struct path *path = data; + path && d_unlinked(path->dentry)) + return 0; - if (d_unlinked(path->dentry)) - return 0; - } if (file_name) { len = file_name->len; alloc_len += len + 1; diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index db3cabb4600e..5cc838db422a 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -212,10 +212,36 @@ struct fsnotify_group { }; }; -/* when calling fsnotify tell it if the data is a path or inode */ -#define FSNOTIFY_EVENT_NONE 0 -#define FSNOTIFY_EVENT_PATH 1 -#define FSNOTIFY_EVENT_INODE 2 +/* When calling fsnotify tell it if the data is a path or inode */ +enum fsnotify_data_type { + FSNOTIFY_EVENT_NONE, + FSNOTIFY_EVENT_PATH, + FSNOTIFY_EVENT_INODE, +}; + +static inline const struct inode *fsnotify_data_inode(const void *data, + int data_type) +{ + switch (data_type) { + case FSNOTIFY_EVENT_INODE: + return data; + case FSNOTIFY_EVENT_PATH: + return d_inode(((const struct path *)data)->dentry); + default: + return NULL; + } +} + +static inline const struct path *fsnotify_data_path(const void *data, + int data_type) +{ + switch (data_type) { + case FSNOTIFY_EVENT_PATH: + return data; + default: + return NULL; + } +} enum fsnotify_obj_type { FSNOTIFY_OBJ_TYPE_INODE, diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index f0d243318452..3596448bfdab 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -160,23 +160,14 @@ static int audit_mark_handle_event(struct fsnotify_group *group, { struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); struct audit_fsnotify_mark *audit_mark; - const struct inode *inode = NULL; + const struct inode *inode = fsnotify_data_inode(data, data_type); audit_mark = container_of(inode_mark, struct audit_fsnotify_mark, mark); BUG_ON(group != audit_fsnotify_group); - switch (data_type) { - case (FSNOTIFY_EVENT_PATH): - inode = ((const struct path *)data)->dentry->d_inode; - break; - case (FSNOTIFY_EVENT_INODE): - inode = (const struct inode *)data; - break; - default: - BUG(); + if (WARN_ON(!inode)) return 0; - } if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) { if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL)) diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 4508d5e0cf69..dcfbb44c6720 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -473,25 +473,13 @@ static int audit_watch_handle_event(struct fsnotify_group *group, struct fsnotify_iter_info *iter_info) { struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info); - const struct inode *inode; + const struct inode *inode = fsnotify_data_inode(data, data_type); struct audit_parent *parent; parent = container_of(inode_mark, struct audit_parent, mark); BUG_ON(group != audit_watch_group); - - switch (data_type) { - case (FSNOTIFY_EVENT_PATH): - inode = d_backing_inode(((const struct path *)data)->dentry); - break; - case (FSNOTIFY_EVENT_INODE): - inode = (const struct inode *)data; - break; - default: - BUG(); - inode = NULL; - break; - } + WARN_ON(!inode); if (mask & (FS_CREATE|FS_MOVED_TO) && inode) audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0); From patchwork Mon Feb 17 13:14:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386391 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 2ED5C139A for ; Mon, 17 Feb 2020 13:15:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0AC67208C4 for ; Mon, 17 Feb 2020 13:15:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WP/vQDIS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729150AbgBQNPV (ORCPT ); Mon, 17 Feb 2020 08:15:21 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:54267 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729018AbgBQNPO (ORCPT ); Mon, 17 Feb 2020 08:15:14 -0500 Received: by mail-wm1-f68.google.com with SMTP id s10so17114350wmh.3 for ; Mon, 17 Feb 2020 05:15:13 -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=YEwTGL2sezTfgqALhHfJLmjkjavhlZLO+UQi7Telv5I=; b=WP/vQDISp7WSJR0qPlTGzbUn6Ozv9NRlcmSfRfJJjRZ6dV4Qgti8yP18Arvmhxib2I wCeDRFIvxaYeYEfWBVEK2Wt/Z2s4Y5Lvcu0e10cI8XbpABYnme9lH07SOUTZFm1QKxAk ACNYHbjps4/roUEszUFPNWa6/ueJqegYbvQeK4w86jQPVdsn3j3SOwZNvwMFS1sphIhZ mfVUm5fJ9f+jGk05Sq+GamVu8wSKk12YxFaWg/ISlC0zzt5qSyBeWvwtYMwq05yDezQq oilOxuzPnAjuMXBKmZYVv86crIyoEDOZGG7v5ULalHgEYcKFRa8z5EGh97wzg379VX8J vrxw== 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=YEwTGL2sezTfgqALhHfJLmjkjavhlZLO+UQi7Telv5I=; b=akw3nqJf8NRCBOhzC470H8KmiB7kXjJUrmILjc8hKrnO/MEbc+pahGTfCynyRcPc1J L3TZqqPHDK2Qjqp2ISLF9FDFa3Z70yGcxmZzBkn9BOtro0LjYqN7Myzj3BUuqY/Xm3Qj ZINltfhOxZH8Lm+DWZIhd+qBIoTCS6x2yKQipdNSb3h7yjGK0ds4u9UMMpJDIrJlnNua /ySeNsoh17qMEqyg2ib+6Me9VYb/oJHzHsldtGtjIyV6+G1ALZb9ypLXooPWcHt1t7Bk fw/1mu+0/SCGpAOb3UxUOnDJx8sbucp+BkY60kGJ7B+1EHLcaUX5RmLSC9zLDICONRPd BJiA== X-Gm-Message-State: APjAAAWOn0Vqtc5+PoBwgTfXPDZ2E27l7vVJkSxrGuuv01CyGi+joOIs yzabe3XT1AqEtss8J5tom7P6TqA7 X-Google-Smtp-Source: APXvYqwcjFBdoa2iVt7DGl6DOgd6Q1jol6/1v1ZFfW+uX5ni+L2QfdKwKR1o7zQ2DU9sKqHSWSdKRQ== X-Received: by 2002:a7b:cb46:: with SMTP id v6mr23605147wmj.117.1581945313213; Mon, 17 Feb 2020 05:15:13 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:12 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 05/16] fsnotify: simplify arguments passing to fsnotify_parent() Date: Mon, 17 Feb 2020 15:14:44 +0200 Message-Id: <20200217131455.31107-6-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-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 passing both dentry and path and having to figure out which one to use, pass data/data_type to simplify the code. Signed-off-by: Amir Goldstein Reported-by: kbuild test robot --- fs/notify/fsnotify.c | 15 ++++----------- include/linux/fsnotify.h | 14 ++------------ include/linux/fsnotify_backend.h | 13 +++++++------ 3 files changed, 13 insertions(+), 29 deletions(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index a5d6467f89a0..193530f57963 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -143,15 +143,13 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) } /* Notify this dentry's parent about a child's events. */ -int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask) +int fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, + int data_type) { struct dentry *parent; struct inode *p_inode; int ret = 0; - if (!dentry) - dentry = path->dentry; - if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) return 0; @@ -168,12 +166,7 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask mask |= FS_EVENT_ON_CHILD; take_dentry_name_snapshot(&name, dentry); - if (path) - ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH, - &name.name, 0); - else - ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, - &name.name, 0); + ret = fsnotify(p_inode, mask, data, data_type, &name.name, 0); release_dentry_name_snapshot(&name); } @@ -181,7 +174,7 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask return ret; } -EXPORT_SYMBOL_GPL(__fsnotify_parent); +EXPORT_SYMBOL_GPL(fsnotify_parent); static int send_to_group(struct inode *to_tell, __u32 mask, const void *data, diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 420aca9fd5f4..af30e0a56f2e 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -38,16 +38,6 @@ static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry, fsnotify_name(dir, mask, d_inode(dentry), &dentry->d_name, 0); } -/* Notify this dentry's parent about a child's events. */ -static inline int fsnotify_parent(const struct path *path, - struct dentry *dentry, __u32 mask) -{ - if (!dentry) - dentry = path->dentry; - - return __fsnotify_parent(path, dentry, mask); -} - /* * Simple wrappers to consolidate calls fsnotify_parent()/fsnotify() when * an event is on a file/dentry. @@ -59,7 +49,7 @@ static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask) if (S_ISDIR(inode->i_mode)) mask |= FS_ISDIR; - fsnotify_parent(NULL, dentry, mask); + fsnotify_parent(dentry, mask, inode, FSNOTIFY_EVENT_INODE); fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); } @@ -75,7 +65,7 @@ static inline int fsnotify_file(struct file *file, __u32 mask) if (S_ISDIR(inode->i_mode)) mask |= FS_ISDIR; - ret = fsnotify_parent(path, NULL, mask); + ret = fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH); if (ret) return ret; diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 5cc838db422a..b1f418cc28e1 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -376,9 +376,10 @@ struct fsnotify_mark { /* called from the vfs helpers */ /* main fsnotify call to send events */ -extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, - const struct qstr *name, u32 cookie); -extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask); +extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, + int data_type, const struct qstr *name, u32 cookie); +extern int fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, + int data_type); extern void __fsnotify_inode_delete(struct inode *inode); extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); extern void fsnotify_sb_delete(struct super_block *sb); @@ -533,13 +534,13 @@ static inline void fsnotify_init_event(struct fsnotify_event *event, #else -static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, - const struct qstr *name, u32 cookie) +static inline int fsnotify(struct inode *to_tell, __u32 mask, const void *data, + int data_type, const struct qstr *name, u32 cookie) { return 0; } -static inline int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask) +static inline int fsnotify_parent(__u32 mask, const void *data, int data_type) { return 0; } From patchwork Mon Feb 17 13:14:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386393 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 8F76C159A for ; Mon, 17 Feb 2020 13:15:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 709DA207FD for ; Mon, 17 Feb 2020 13:15:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gi7x+CnB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729149AbgBQNPU (ORCPT ); Mon, 17 Feb 2020 08:15:20 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:46254 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729107AbgBQNPP (ORCPT ); Mon, 17 Feb 2020 08:15:15 -0500 Received: by mail-wr1-f67.google.com with SMTP id z7so19653329wrl.13 for ; Mon, 17 Feb 2020 05:15:14 -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=kkFQg2HH7gHiyqi5OvCqenDUG/5/Cpl5W50irvXu3Kw=; b=gi7x+CnBsWYKqMkLtcOJsFs2KZwtlSKD+/FGYMf4rs9xdka8QPakOv7VmkUFQB26Rg vqnWPBEs23xINQe3zb7ec+aykGSX+u+f0a0w/7u2zCknWWkqHIf2x3OBWuGWi56y8N0z zEpGfzv7ZT7WgxK2gr6z1U9eWERRwdeg27KKfWKpSqAY7ua88hkyBF/SdGD5JbGJ3QV2 F2zaJDx2vF3mhXROseV3o1TjZwI3nNR6lKvUe3tR0Uv0lv/2sZ6vywzqdDbxZkSnKPSn Upfm5lXPX1CxvOGO8bs7t1SBSubkrN1XaXku1DeYnGBYh3eNgSRuyF+g7HCsoVIXpzly WGiA== 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=kkFQg2HH7gHiyqi5OvCqenDUG/5/Cpl5W50irvXu3Kw=; b=FUt4BnL6Oh6GWC7hp5VjKFIMQCHJGLAruIFRqEpL35lp/IskxNapysv7CsNCr4m1Al CiGyDy3iQ0p/XcS6jNPqaB8CQZPvo8PRy1fXuYIbk7Hj1d4HzY6aQ6lvrw3WfP2OTc3V 7vzN7eXIZvb3MP2XY6r9W0cXsXNtMBrkmm186AuMD9Gaj+jYFIyaj5kSeuFt3d669Hwh y/vMvN2D2PWLRSWcCdhui8XATmJnBhwCFM/NrMl6twB3WOn8VrnmHxsnSSaAaARgCmEW aCTyttRfImZBQAnmVo8SrvNHUdMqmukgd7VYB5QHPGCoIGJSfky7TaPFobypURjrfD/V AxAg== X-Gm-Message-State: APjAAAWD9LuOhfLyBK9JHUVmGUsJvwUE4Mnd5/zHfarF1uM9GFINrAaF hcUaSbDQPgsy6AS6b8Fxbs8= X-Google-Smtp-Source: APXvYqzUVf7CxxAlEPlZGfdUpf5aoYQP4TiTEMCZSSGY+IuDSi1sAnmlVXK5sVqkl9wIprsFKKVVBQ== X-Received: by 2002:adf:ed0c:: with SMTP id a12mr22158227wro.368.1581945314283; Mon, 17 Feb 2020 05:15:14 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:13 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 06/16] fsnotify: pass dentry instead of inode for events possible on child Date: Mon, 17 Feb 2020 15:14:45 +0200 Message-Id: <20200217131455.31107-7-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Most events that can be reported to watching parent pass FSNOTIFY_EVENT_PATH as event data, except for FS_ARRTIB and FS_MODIFY as a result of truncate. Define a new data type to pass for event - FSNOTIFY_EVENT_DENTRY and use it to pass the dentry instead of it's ->d_inode for those events. Soon, we are going to use the dentry data type to report events with name info in fanotify backend. Signed-off-by: Amir Goldstein --- include/linux/fsnotify.h | 4 ++-- include/linux/fsnotify_backend.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index af30e0a56f2e..7ba40c19bc7e 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -49,8 +49,8 @@ static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask) if (S_ISDIR(inode->i_mode)) mask |= FS_ISDIR; - fsnotify_parent(dentry, mask, inode, FSNOTIFY_EVENT_INODE); - fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); + fsnotify_parent(dentry, mask, dentry, FSNOTIFY_EVENT_DENTRY); + fsnotify(inode, mask, dentry, FSNOTIFY_EVENT_DENTRY, NULL, 0); } static inline int fsnotify_file(struct file *file, __u32 mask) diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index b1f418cc28e1..bd3f6114a7a9 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -217,6 +217,7 @@ enum fsnotify_data_type { FSNOTIFY_EVENT_NONE, FSNOTIFY_EVENT_PATH, FSNOTIFY_EVENT_INODE, + FSNOTIFY_EVENT_DENTRY, }; static inline const struct inode *fsnotify_data_inode(const void *data, @@ -225,6 +226,8 @@ static inline const struct inode *fsnotify_data_inode(const void *data, switch (data_type) { case FSNOTIFY_EVENT_INODE: return data; + case FSNOTIFY_EVENT_DENTRY: + return d_inode(data); case FSNOTIFY_EVENT_PATH: return d_inode(((const struct path *)data)->dentry); default: @@ -232,6 +235,20 @@ static inline const struct inode *fsnotify_data_inode(const void *data, } } +static inline struct dentry *fsnotify_data_dentry(const void *data, + int data_type) +{ + switch (data_type) { + case FSNOTIFY_EVENT_DENTRY: + /* Non const is needed for dget() */ + return (struct dentry *)data; + case FSNOTIFY_EVENT_PATH: + return ((const struct path *)data)->dentry; + default: + return NULL; + } +} + static inline const struct path *fsnotify_data_path(const void *data, int data_type) { From patchwork Mon Feb 17 13:14:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386385 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 E74DF139A for ; Mon, 17 Feb 2020 13:15:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C6A1E206E2 for ; Mon, 17 Feb 2020 13:15:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qA4IWowt" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729139AbgBQNPR (ORCPT ); Mon, 17 Feb 2020 08:15:17 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:52519 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729125AbgBQNPR (ORCPT ); Mon, 17 Feb 2020 08:15:17 -0500 Received: by mail-wm1-f67.google.com with SMTP id p9so17108700wmc.2 for ; Mon, 17 Feb 2020 05:15:16 -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=FrjWKs7Er54lWDwKu5pX+EDCsHByz98RF1MpRiqTebk=; b=qA4IWowtwl2jLWou4xMwEV+yb9H/TxGLCnzvNRdJK3JQcpf1Fl7LPWnaoMvk460o9/ jXH36M8acBDuhOo4hxpGqDOIyk/kLD2VXgEMSyGWZ3WRJoEOdMpGNzWLgmirwujsLUYO eYEBDoBeLx7LF2fd0tEywhQBNAMPZmpgQkP5rFNIiIez9I/T9R0irgAWjoLguiUdfX5B v707zB+cE//ZbvPLJ1CFemenAEkZ8srDTTYoBwes59sj3LJ08PRIkzMqSpHFh5FP5zAe XJ9rHAIHaj4/hifdhpNaiVnFdt4KrfkEX/15Q79TeHzw/hi+xRUgZZZ6K8B+jQfRx9B1 YAPw== 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=FrjWKs7Er54lWDwKu5pX+EDCsHByz98RF1MpRiqTebk=; b=B/Rjawm1SxUgEBzQtrZweLr79g/v5Tl0DghYM9ajDMxO2vRU3PzR2WJUnBUMVESi23 xPh2h/Is4Sv+cCDB19LNNRazd8Yjjl7o+RhQTA6je5plJcVkk5Ji+DAQqJ/sPbmUS3kl Au7ZcSiOuNN37pdojnAA+fAZl89fojV8XskENs1XXoDsX9hLfcohzZt5KckMe1RYrtB4 qItDle+dY33j934CA2xtckgt+6VHfk11VyJyHt/ulyZDQ7F8vVejpcg8FHAvbQXLgXVq 8hhUoxK4v34LG+b1lZFYKKPrVx0krC40i/6XViUA2lgZ48s+jLWu5+vLtr/SQCzPX8mH 3ifQ== X-Gm-Message-State: APjAAAXo+NDOYn5TEkCxr0/Q+hoVEH9CMAACxaA1Yu51zGmClj5HNWSf 0hYgIW8aAezQH8edN8mhLS5c6o+r X-Google-Smtp-Source: APXvYqw0cZeYxrZGXo0U2aCRtMlHwLJacIImiocV43N1xQx4KJmGrJYLovHs7rNuEDYLCL+PaDd5PQ== X-Received: by 2002:a1c:1f51:: with SMTP id f78mr22084484wmf.60.1581945315439; Mon, 17 Feb 2020 05:15:15 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:14 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 07/16] fsnotify: replace inode pointer with tag Date: Mon, 17 Feb 2020 15:14:46 +0200 Message-Id: <20200217131455.31107-8-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The event inode field is used only for comparison in queue merges and cannot be dereferenced after handle_event(), because it does not hold a refcount on the inode. Replace it with an abstract tag do to the same thing. We are going to set this tag for values other than inode pointer in fanotify. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 2 +- fs/notify/inotify/inotify_fsnotify.c | 2 +- include/linux/fsnotify_backend.h | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 19ec7a4f4d50..98c3cbf29003 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -26,7 +26,7 @@ static bool should_merge(struct fsnotify_event *old_fsn, old = FANOTIFY_E(old_fsn); new = FANOTIFY_E(new_fsn); - if (old_fsn->inode != new_fsn->inode || old->pid != new->pid || + if (old_fsn->tag != new_fsn->tag || old->pid != new->pid || old->fh_type != new->fh_type || old->fh_len != new->fh_len) return false; diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 6bb98522bbfd..4f42ea7b7fdd 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -39,7 +39,7 @@ static bool event_compare(struct fsnotify_event *old_fsn, if (old->mask & FS_IN_IGNORED) return false; if ((old->mask == new->mask) && - (old_fsn->inode == new_fsn->inode) && + (old_fsn->tag == new_fsn->tag) && (old->name_len == new->name_len) && (!old->name_len || !strcmp(old->name, new->name))) return true; diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index bd3f6114a7a9..cd106b5c87a4 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -132,8 +132,7 @@ struct fsnotify_ops { */ struct fsnotify_event { struct list_head list; - /* inode may ONLY be dereferenced during handle_event(). */ - struct inode *inode; /* either the inode the event happened to or its parent */ + unsigned long tag; /* identifier for queue merges */ }; /* @@ -542,11 +541,10 @@ extern void fsnotify_put_mark(struct fsnotify_mark *mark); extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info); -static inline void fsnotify_init_event(struct fsnotify_event *event, - struct inode *inode) +static inline void fsnotify_init_event(struct fsnotify_event *event, void *tag) { INIT_LIST_HEAD(&event->list); - event->inode = inode; + event->tag = (unsigned long)tag; } #else From patchwork Mon Feb 17 13:14:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386389 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 8A11D139A for ; Mon, 17 Feb 2020 13:15:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6AC6F215A4 for ; Mon, 17 Feb 2020 13:15:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kuUuOup7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729142AbgBQNPT (ORCPT ); Mon, 17 Feb 2020 08:15:19 -0500 Received: from mail-wr1-f66.google.com ([209.85.221.66]:41429 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729043AbgBQNPS (ORCPT ); Mon, 17 Feb 2020 08:15:18 -0500 Received: by mail-wr1-f66.google.com with SMTP id c9so19706023wrw.8 for ; Mon, 17 Feb 2020 05:15:17 -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=mp/NZJhDpTVTKOe7pgjJLtK1WnKPYZUsnP23pwfKWw8=; b=kuUuOup7VeeeOqe1tdVqZ18/1b1s9aQAntaEngYN8UUvm78utGpmZzDIUJ+1wpjbwu /YKviWALtol6zNhA9zIBjQ28S2IXogGLUrxP+7MJxP2ehsDTYAFYa3DCAcqnV+/eEMUf SRCHUQm/b9a96YUBdI/NC2aQ7tj7ovzqyzYIfGXrdPaJxJzC5q2iXIDy4SPXxo87/WA0 M7HuSMaW+7y8mnO+bg3CNRSyntbBZfXRlADOQ8lhPtxUnd1kLRHKxp+d/ckubYYZ7hpc Etr9+73GIgeBPTVGFxOXs+HOQisPsy68CNmqEZzW6juvXkxWEJ2mhCEgTfdQgtCN2ZwI aBRw== 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=mp/NZJhDpTVTKOe7pgjJLtK1WnKPYZUsnP23pwfKWw8=; b=FpdGhJ7YZO+BiDEvxZJQtHQnaSjz9o02J+KicAJihK+CVThdjXcGkZhm87S5viTZU0 Grh9t0LkxEJpqDdTbOAswOtLRPahKRSXz1ZJ+u/XhFQgrOYyB+iwuHZa/n8JUWNnl0Ko yce1q19o6xLvYA+7kZdS8jCAsFz+5Lsce63Sc78QMze2OZk+bWfau9Y6ygeUWzr+x1gE 3qzZsE8Gy+3Sktcr+e/FOUNYS4oFyvgwbtARniHvibmPPeIOyG5wtFN9xuacBkrKJfYb NYuaJxmfZzueoP9O3yxmqvpxli5XhckTOpyWsqb7bhvg9NrSzHmE25Mk5+CyW2n6nYJY gwcg== X-Gm-Message-State: APjAAAVTVQK9ZhSwuLD3Pwhs1t1YBP2/HBIH5s2k3u6iTYFmy31ram1o BGZCYzRwC8gjdIopTBgMf7o= X-Google-Smtp-Source: APXvYqwkXESPAbAWFag7TpqSQ75UK2h9ppcC9Q9VDwE4CX01B6WTFByB4BJLIrhOL1Ar82m08gwSzA== X-Received: by 2002:a05:6000:4:: with SMTP id h4mr23487272wrx.403.1581945316694; Mon, 17 Feb 2020 05:15:16 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:16 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 08/16] fanotify: merge duplicate events on parent and child Date: Mon, 17 Feb 2020 15:14:47 +0200 Message-Id: <20200217131455.31107-9-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org With inotify, when a watch is set on a directory and on its child, an event on the child is reported twice, once with wd of the parent watch and once with wd of the child watch without the filename. With fanotify, when a watch is set on a directory and on its child, an event on the child is reported twice, but it has the exact same information - either an open file descriptor of the child or an encoded fid of the child. The reason that the two identical events are not merged is because the tag used for merging events in the queue is the child inode in one event and parent inode in the other. For events with path or dentry data, use the dentry instead of inode as the tag for event merging, so that the event reported on parent will be merged with the event reported on the child. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 98c3cbf29003..dab7e9895e02 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -282,6 +282,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, gfp_t gfp = GFP_KERNEL_ACCOUNT; struct inode *id = fanotify_fid_inode(inode, mask, data, data_type); const struct path *path = fsnotify_data_path(data, data_type); + struct dentry *dentry = fsnotify_data_dentry(data, data_type); /* * For queues with unlimited length lost events are not expected and @@ -312,7 +313,12 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, if (!event) goto out; init: __maybe_unused - fsnotify_init_event(&event->fse, inode); + /* + * Use the dentry instead of inode as tag for event queue, so event + * reported on parent is merged with event reported on child when both + * directory and child watches exist. + */ + fsnotify_init_event(&event->fse, (void *)dentry ?: inode); event->mask = mask; if (FAN_GROUP_FLAG(group, FAN_REPORT_TID)) event->pid = get_pid(task_pid(current)); From patchwork Mon Feb 17 13:14:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386395 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 E5451139A for ; Mon, 17 Feb 2020 13:15:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C1CE322B48 for ; Mon, 17 Feb 2020 13:15:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bXGOYfFf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729147AbgBQNPU (ORCPT ); Mon, 17 Feb 2020 08:15:20 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:44878 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729078AbgBQNPT (ORCPT ); Mon, 17 Feb 2020 08:15:19 -0500 Received: by mail-wr1-f65.google.com with SMTP id m16so19647092wrx.11 for ; Mon, 17 Feb 2020 05:15:18 -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=opyi01Gy2VvVvfzLBUO4P8c3KpDkIjDxhze7gbYoZZk=; b=bXGOYfFfVCbbbvA6vPF2Y3+jC8tVup78YtA8mhbNUhhNoYQzC9h5M/zu8X5cJ2ksi+ ApvMFR4QzgXtMhzVdE9JDaaDjP4B5V1StCEQweafizyMDH1WWe5gWOEMYhtKIeb0MGDc UpEgTc1oiWXoWPm+5WTPaZWq9sONOIhL6PvzXCuQez7FAI93qP1lBG1MnldwtDoBywu2 7u5RqGGJm9+ZhQxmN6Ajs8Hfkei4mgHOh5y0nUV2FwbzWV/skgEKFdAoYInolRbv+y0I h55KC4XPiDL0TCPA8OlvkGzuLBftsEsiKhVOvGBFjL8n0/uXKNRSuZMqPuI31Xx3jcJU qZcA== 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=opyi01Gy2VvVvfzLBUO4P8c3KpDkIjDxhze7gbYoZZk=; b=sJeSzrF/9f9WvGzRo4h2YDyFBoYcoXmkdvxZAhqT2U8JcgQq1zDMQa77UC5oAWg0bm Ztvfmshq6PJB9+VHHnlUAepGaPLRPFodRidWN8dq76PDM6zOh1+3gQWJJjfg5K7QFZwb +tSCVoC415nkwLz/iJuQb4+99k/5sGP9Skvxg/ALUcsMA8yyuBMu8XN/kweZuzOUTYVG u7G5dsqhQzru3ULJuswYu3mWbVgYGM5bFX0Hk8VLLDo8E4N96WxJ6wWXtHqEOmdIs75p Vxfs9XGe/Hf5UFTJ+eaSqDEQxe5mihuGkAbVtOgltaCOoxXyoQsaTVd8/roZZrYllIGj mquA== X-Gm-Message-State: APjAAAX2wsO1uGwAgzC+mbdJiX5Af/ewp57IEsecAd/LgZEtlPZAY1pp VPD0AR60bsWQYl58+tY2UZs= X-Google-Smtp-Source: APXvYqw17owg2YplLG7C1XrOfVfJn4akUufp940rCgY1G+Icq8UhxwQoxI9gKDSDy7zowQV8QEhiVA== X-Received: by 2002:a5d:68cf:: with SMTP id p15mr21439910wrw.31.1581945317976; Mon, 17 Feb 2020 05:15:17 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:17 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 09/16] fanotify: fix merging marks masks with FAN_ONDIR Date: Mon, 17 Feb 2020 15:14:48 +0200 Message-Id: <20200217131455.31107-10-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Change the logic of FAN_ONDIR in two ways that are similar to the logic of FAN_EVENT_ON_CHILD, that was fixed in commit 54a307ba8d3c ("fanotify: fix logic of events on child"): 1. The flag is meaningless in ignore mask 2. The flag refers only to events in the mask of the mark where it is set This is what the fanotify_mark.2 man page says about FAN_ONDIR: "Without this flag, only events for files are created." It doesn't say anything about setting this flag in ignore mask to stop getting events on directories nor can I think of any setup where this capability would be useful. Currently, when marks masks are merged, the FAN_ONDIR flag set in one mark affects the events that are set in another mark's mask and this behavior causes unexpected results. For example, a user adds a mark on a directory with mask FAN_ATTRIB | FAN_ONDIR and a mount mark with mask FAN_OPEN (without FAN_ONDIR). An opendir() of that directory (which is inside that mount) generates a FAN_OPEN event even though neither of the marks requested to get open events on directories. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index dab7e9895e02..36903542aa57 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -171,6 +171,13 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, if (!fsnotify_iter_should_report_type(iter_info, type)) continue; mark = iter_info->marks[type]; + /* + * If the event is on dir and this mark doesn't care about + * events on dir, don't send it! + */ + if (event_mask & FS_ISDIR && !(mark->mask & FS_ISDIR)) + continue; + /* * If the event is for a child and this mark doesn't care about * events on a child, don't send it! @@ -203,10 +210,6 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, user_mask &= ~FAN_ONDIR; } - if (event_mask & FS_ISDIR && - !(marks_mask & FS_ISDIR & ~marks_ignored_mask)) - return 0; - return test_mask & user_mask; } From patchwork Mon Feb 17 13:14:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386417 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 EAF2D14E3 for ; Mon, 17 Feb 2020 13:15:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C32D1208C4 for ; Mon, 17 Feb 2020 13:15:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="t9ldRPTV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729181AbgBQNP3 (ORCPT ); Mon, 17 Feb 2020 08:15:29 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38977 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729043AbgBQNPW (ORCPT ); Mon, 17 Feb 2020 08:15:22 -0500 Received: by mail-wm1-f66.google.com with SMTP id c84so18447517wme.4; Mon, 17 Feb 2020 05:15:20 -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=Lz+xcFdtQb9MfwudpkflwlNS1QuyfuZosxO8i55t0/o=; b=t9ldRPTVxPsgaaeqI24DkK0+48DTyQS1K/VjBmeqFyXp9H+TzRdS6NBHrNq+yjgm87 P6O4ZSOeEG/zMh15Inw96qPX/YozRLyH88U1CNIuIPncgI0aWXKGSWqu4RxLAyLBxbr8 SnjB8WRDDpaoFIHuemRU6Q8cL5cWq4/zC+D0BSAnbvg65Nd4dlbJ1huucyYS8hbwlJfH zslSnAdVyhr4J0krABizHf8tDCmI6j5vVyxJv1spiLeEFwxUeolCmT+P5zxCI75YkMeg 5DIquCPWcWzPL1l6wswYwldz2V/KGSWZv30AqmOdKJ+8Vx4YUzzjVA1b2ok511p6gE+b GZKA== 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=Lz+xcFdtQb9MfwudpkflwlNS1QuyfuZosxO8i55t0/o=; b=MPUKYgvqkOKbFZflwKigE34cxK01uSbPA0aD5oqweFC7IsgrfimaFZgATZBLduYbgz 3ql3WwW5BKc9WQ+EaeAR9oh36wzr2ZDWFgp8jnDC//Wrjfr88zaiadg94JTzY2rWeix/ bxrTDLmBsmxZX/pgJy6dv2CM14D0MZTw4hKeCId4f3jBzNFdf+FnPRGfBjQGlcoOfgS2 0GGqTllkewyhjbyJoHnwHyJIRKHSzkN0PpZEqQmgCzOpZDPUb5zEiHnDDFAz/zDZgd98 kRjpoceFG3tTrRB+rjRl+/U70y7AlcCUbI3bAG1ZVmsaRpryFwjuSLeXAR2WqTDKkNUJ EDYA== X-Gm-Message-State: APjAAAW+pahSUUAaYz3FJJ5jwljP2vw9T9lj5z4QJIgrRdOsQxcULSVb +5xATtzBNwqvZuDGfNohZGRNo4V+ X-Google-Smtp-Source: APXvYqy02avEyoX3UKEo2nVco1Fo/wUPTOQeHOueRs4qH06fKzqEz+tdkKGERFXQAvun9EhWZA637Q== X-Received: by 2002:a05:600c:2147:: with SMTP id v7mr21397524wml.61.1581945319728; Mon, 17 Feb 2020 05:15:19 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:19 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v2 10/16] fanotify: send FAN_DIR_MODIFY event flavor with dir inode and name Date: Mon, 17 Feb 2020 15:14:49 +0200 Message-Id: <20200217131455.31107-11-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Dirent events are going to be supported in two flavors: 1. Directory fid info + mask that includes the specific event types (e.g. FAN_CREATE) and an optional FAN_ONDIR flag. 2. Directory fid info + name + mask that includes only FAN_DIR_MODIFY. To request the second event flavor, user needs to set the event type FAN_DIR_MODIFY in the mark mask. The first flavor is supported since kernel v5.1 for groups initialized with flag FAN_REPORT_FID. It is intended to be used for watching directories in "batch mode" - the watcher is notified when directory is changed and re-scans the directory content in response. This event flavor is stored more compactly in the event queue, so it is optimal for workloads with frequent directory changes. The second event flavor is intended to be used for watching large directories, where the cost of re-scan of the directory on every change is considered too high. The watcher getting the event with the directory fid and entry name is expected to call fstatat(2) to query the content of the entry after the change. Legacy inotify events are reported with name and event mask (e.g. "foo", FAN_CREATE | FAN_ONDIR). That can lead users to the conclusion that there is *currently* an entry "foo" that is a sub-directory, when in fact "foo" may be negative or non-dir by the time user gets the event. To make it clear that the current state of the named entry is unknown, when reporting an event with name info, fanotify obfuscates the specific event types (e.g. create,delete,rename) and uses a common event type - FAN_DIR_MODIFY to decribe the change. This should make it harder for users to make wrong assumptions and write buggy filesystem monitors. At this point, name info reporting is not yet implemented, so trying to set FAN_DIR_MODIFY in mark mask will return -EINVAL. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 7 ++++--- fs/notify/fsnotify.c | 2 +- include/linux/fsnotify.h | 6 ++++++ include/linux/fsnotify_backend.h | 4 +++- include/uapi/linux/fanotify.h | 1 + 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 36903542aa57..1f60823931b7 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -194,9 +194,9 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, 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 dirent modification events (create/delete/move) that do not carry + * the child entry name information, 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 @@ -399,6 +399,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, BUILD_BUG_ON(FAN_MOVED_FROM != FS_MOVED_FROM); BUILD_BUG_ON(FAN_CREATE != FS_CREATE); BUILD_BUG_ON(FAN_DELETE != FS_DELETE); + BUILD_BUG_ON(FAN_DIR_MODIFY != FS_DIR_MODIFY); BUILD_BUG_ON(FAN_DELETE_SELF != FS_DELETE_SELF); BUILD_BUG_ON(FAN_MOVE_SELF != FS_MOVE_SELF); BUILD_BUG_ON(FAN_EVENT_ON_CHILD != FS_EVENT_ON_CHILD); diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 193530f57963..72d332ce8e12 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -383,7 +383,7 @@ static __init int fsnotify_init(void) { int ret; - BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 25); + BUILD_BUG_ON(HWEIGHT32(ALL_FSNOTIFY_BITS) != 26); ret = init_srcu_struct(&fsnotify_mark_srcu); if (ret) diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 7ba40c19bc7e..fb54d9d70552 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -30,6 +30,12 @@ static inline void fsnotify_name(struct inode *dir, __u32 mask, const struct qstr *name, u32 cookie) { fsnotify(dir, mask, child, FSNOTIFY_EVENT_INODE, name, cookie); + /* + * Send another flavor of the event without child inode data and + * without the specific event type (e.g. FS_CREATE|FS_IS_DIR). + * The name is relative to the dir inode the event is reported to. + */ + fsnotify(dir, FS_DIR_MODIFY, dir, FSNOTIFY_EVENT_INODE, name, 0); } static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry, diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index cd106b5c87a4..310c639de04e 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -47,6 +47,7 @@ #define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */ #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */ #define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */ +#define FS_DIR_MODIFY 0x00080000 /* Directory entry was modified */ #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 @@ -66,7 +67,8 @@ * The watching parent may get an FS_ATTRIB|FS_EVENT_ON_CHILD event * when a directory entry inside a child subdir changes. */ -#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE) +#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE | \ + FS_DIR_MODIFY) #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \ FS_OPEN_EXEC_PERM) diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 2a1844edda47..615fa2c87179 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -24,6 +24,7 @@ #define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ #define FAN_OPEN_EXEC_PERM 0x00040000 /* File open/exec in perm check */ +#define FAN_DIR_MODIFY 0x00080000 /* Directory entry was modified */ #define FAN_EVENT_ON_CHILD 0x08000000 /* Interested in child events */ From patchwork Mon Feb 17 13:14:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386409 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 95810159A for ; Mon, 17 Feb 2020 13:15:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6DE6222B48 for ; Mon, 17 Feb 2020 13:15:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XG8xYfru" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729184AbgBQNP3 (ORCPT ); Mon, 17 Feb 2020 08:15:29 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:34320 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729018AbgBQNPW (ORCPT ); Mon, 17 Feb 2020 08:15:22 -0500 Received: by mail-wr1-f68.google.com with SMTP id n10so17740011wrm.1 for ; Mon, 17 Feb 2020 05:15:21 -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=3GrSWkT/bnpfGwMb4aFnds0xBYXXx0zoUkU4vUi40U4=; b=XG8xYfruTiz7vBYZHTkkMaItl3EconcQ/uEUXCRkERsiYZLlYAhJbNFi2+K5Dg9oTW 8jIkdheTBEAJ7O2I9cenKy4NBG90ETkwI88ywRZBo18bs50FKMr5n4AvyqEdEGCM/+RC 5C2oMs8BmNh3MPLMjjSrRQ954pksiCOMsmHHdIStUi53PiDv/uPkF9EPASAqSCTAF30A 7Q2Q7bJq4MYJV9PGt5Wrpxt/7nSyiv7FRIqNxltqiOQkg7OU5MT823dWSucz3BvjFH4q rl6mPU84x5gpYo9kFMnSsShhL+wyQFFtZVVCA1RZa9tH9elztDplcPeuKK1EYQxVCXb4 dmyg== 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=3GrSWkT/bnpfGwMb4aFnds0xBYXXx0zoUkU4vUi40U4=; b=ZTfeFiC5qyyKzLP/NlOMnL0KArsP9I11vMTMy2NQSxCgwOIOHc4OorqlLiLCUcRfra cp1MyG0nsZMA0McdYx42jyXZCMVhH0nLKTUoaVXSMP+t+0LUbhUlUDCtPJY8kerAAaVU pLicXC1KKtoJN8rK3hIKoa/XtsGEIOIch36Zg6hdwiCHGduEzash6RlV/0iihYRL9Uhb fABUuFTWLsv1N8kFtHKl5/BqUkP7H8XSfpXisF/TJds0Co5TyFOZ7CSfq1Y3Iflhw5kq iay3W3vWyVmEvLDj1k3SXmPo9yBOa8OxCeTMYqGAx5P5m01L3Tb00kbKFax25GiK2fWs bPXg== X-Gm-Message-State: APjAAAUiZzBSlom4HX8swoB+wnRrZEMC4T1kaJ9TztoXO5dKfMXtPpzM xa9iXFd0woeUOz3M2n2ROSU= X-Google-Smtp-Source: APXvYqykZRyy/6u7w1sw/oOEVgc7rSa+la98X78ShyYpGDA0Lkun1UlDDItYRDFIkWZ+PXNzN1iq7w== X-Received: by 2002:adf:ea85:: with SMTP id s5mr21798692wrm.75.1581945320842; Mon, 17 Feb 2020 05:15:20 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:20 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 11/16] fanotify: prepare to encode both parent and child fid's Date: Mon, 17 Feb 2020 15:14:50 +0200 Message-Id: <20200217131455.31107-12-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-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, we are going to encode both child and parent fid's, so we need to do a little refactoring of struct fanotify_event and fid helper functions. Move fsid member from struct fanotify_fid out to struct fanotify_event, so we can store fsid once for two encoded fid's (we will only encode parent if it is on the same filesystem). This does not change the size of struct fanotify_event because struct fanotify_fid is still bigger than struct path on 32bit arch and is the same size as struct path (16 bytes) on 64bit arch. Group fh_len and fh_type as struct fanotify_fid_hdr. Pass struct fanotify_fid and struct fanotify_fid_hdr to helpers fanotify_encode_fid() and copy_fid_to_user() instead of passing the containing fanotify_event struct. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 48 +++++++++++++------------ fs/notify/fanotify/fanotify.h | 58 ++++++++++++++++-------------- fs/notify/fanotify/fanotify_user.c | 35 ++++++++++-------- 3 files changed, 78 insertions(+), 63 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 1f60823931b7..3bc28f08aad1 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -27,7 +27,7 @@ static bool should_merge(struct fsnotify_event *old_fsn, new = FANOTIFY_E(new_fsn); if (old_fsn->tag != new_fsn->tag || old->pid != new->pid || - old->fh_type != new->fh_type || old->fh_len != new->fh_len) + old->fh.type != new->fh.type || old->fh.len != new->fh.len) return false; if (fanotify_event_has_path(old)) { @@ -43,7 +43,8 @@ static bool should_merge(struct fsnotify_event *old_fsn, * 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); + fanotify_fsid_equal(&old->fsid, &new->fsid) && + fanotify_fid_equal(&old->fid, &new->fid, old->fh.len); } /* Do not merge events if we failed to encode fid */ @@ -213,18 +214,18 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, return test_mask & user_mask; } -static int fanotify_encode_fid(struct fanotify_event *event, - struct inode *inode, gfp_t gfp, - __kernel_fsid_t *fsid) +static struct fanotify_fid_hdr fanotify_encode_fid(struct fanotify_fid *fid, + struct inode *inode, + gfp_t gfp) { - struct fanotify_fid *fid = &event->fid; + struct fanotify_fid_hdr fh = { }; int dwords, bytes = 0; - int err, type; + int err; fid->ext_fh = NULL; dwords = 0; err = -ENOENT; - type = exportfs_encode_inode_fh(inode, NULL, &dwords, NULL); + fh.type = exportfs_encode_inode_fh(inode, NULL, &dwords, NULL); if (!dwords) goto out_err; @@ -237,26 +238,25 @@ static int fanotify_encode_fid(struct fanotify_event *event, goto out_err; } - type = exportfs_encode_inode_fh(inode, fanotify_fid_fh(fid, bytes), - &dwords, NULL); + fh.type = exportfs_encode_inode_fh(inode, fanotify_fid_fh(fid, bytes), + &dwords, NULL); err = -EINVAL; - if (!type || type == FILEID_INVALID || bytes != dwords << 2) + if (!fh.type || fh.type == FILEID_INVALID || bytes != dwords << 2) goto out_err; - fid->fsid = *fsid; - event->fh_len = bytes; + fh.len = bytes; - return type; + return fh; out_err: - pr_warn_ratelimited("fanotify: failed to encode fid (fsid=%x.%x, " - "type=%d, bytes=%d, err=%i)\n", - fsid->val[0], fsid->val[1], type, bytes, err); + pr_warn_ratelimited("fanotify: failed to encode fid (type=%d, len=%d, err=%i)\n", + fh.type, bytes, err); kfree(fid->ext_fh); fid->ext_fh = NULL; - event->fh_len = 0; + fh.type = FILEID_INVALID; + fh.len = 0; - return FILEID_INVALID; + return fh; } /* @@ -327,16 +327,18 @@ init: __maybe_unused event->pid = get_pid(task_pid(current)); else event->pid = get_pid(task_tgid(current)); - event->fh_len = 0; + event->fh.len = 0; + if (fsid) + event->fsid = *fsid; if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { /* Report the event without a file identifier on encode error */ event->fh_type = fanotify_encode_fid(event, id, gfp, fsid); } else if (path) { - event->fh_type = FILEID_ROOT; + event->fh.type = FILEID_ROOT; event->path = *path; path_get(path); } else { - event->fh_type = FILEID_INVALID; + event->fh.type = FILEID_INVALID; event->path.mnt = NULL; event->path.dentry = NULL; } @@ -485,7 +487,7 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event) event = FANOTIFY_E(fsn_event); if (fanotify_event_has_path(event)) path_put(&event->path); - else if (fanotify_event_has_ext_fh(event)) + else if (fanotify_fid_has_ext_fh(&event->fh)) kfree(event->fid.ext_fh); put_pid(event->pid); if (fanotify_is_perm_event(event->mask)) { diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 68b30504284c..4fee002235b6 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -18,10 +18,10 @@ enum { /* * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation). - * For 32bit arch, fid increases the size of fanotify_event by 12 bytes and - * fh_* fields increase the size of fanotify_event by another 4 bytes. - * For 64bit arch, fid increases the size of fanotify_fid by 8 bytes and - * fh_* fields are packed in a hole after mask. + * For 32bit arch, fsid and fid increase the size of fanotify_event by 12 bytes + * and fh.* fields increase the size of fanotify_event by another 4 bytes. + * For 64bit arch, fanotify_fid is the same size as struct path, fsid increases + * fanotify_event by 8 bytes and fh.* fields are packed in a hole after mask. */ #if BITS_PER_LONG == 32 #define FANOTIFY_INLINE_FH_LEN (3 << 2) @@ -29,28 +29,46 @@ enum { #define FANOTIFY_INLINE_FH_LEN (4 << 2) #endif +struct fanotify_fid_hdr { + u8 type; + u8 len; +}; + struct fanotify_fid { - __kernel_fsid_t fsid; union { unsigned char fh[FANOTIFY_INLINE_FH_LEN]; unsigned char *ext_fh; }; }; +static inline bool fanotify_fid_has_fh(struct fanotify_fid_hdr *fh) +{ + return fh->type != FILEID_ROOT && fh->type != FILEID_INVALID; +} + +static inline bool fanotify_fid_has_ext_fh(struct fanotify_fid_hdr *fh) +{ + return fanotify_fid_has_fh(fh) && fh->len > FANOTIFY_INLINE_FH_LEN; +} + static inline void *fanotify_fid_fh(struct fanotify_fid *fid, unsigned int fh_len) { return fh_len <= FANOTIFY_INLINE_FH_LEN ? fid->fh : fid->ext_fh; } +static inline bool fanotify_fsid_equal(__kernel_fsid_t *fsid1, + __kernel_fsid_t *fsid2) +{ + return fsid1->val[0] == fsid1->val[0] && fsid2->val[1] == fsid2->val[1]; +} + static inline bool fanotify_fid_equal(struct fanotify_fid *fid1, struct fanotify_fid *fid2, unsigned int fh_len) { - return fid1->fsid.val[0] == fid2->fsid.val[0] && - fid1->fsid.val[1] == fid2->fsid.val[1] && - !memcmp(fanotify_fid_fh(fid1, fh_len), - fanotify_fid_fh(fid2, fh_len), fh_len); + return !memcmp(fanotify_fid_fh(fid1, fh_len), + fanotify_fid_fh(fid2, fh_len), fh_len); } /* @@ -63,13 +81,13 @@ struct fanotify_event { u32 mask; /* * Those fields are outside fanotify_fid to pack fanotify_event nicely - * on 64bit arch and to use fh_type as an indication of whether path + * on 64bit arch and to use fh.type as an indication of whether path * or fid are used in the union: * FILEID_ROOT (0) for path, > 0 for fid, FILEID_INVALID for neither. */ - u8 fh_type; - u8 fh_len; + struct fanotify_fid_hdr fh; u16 pad; + __kernel_fsid_t fsid; union { /* * We hold ref to this path so it may be dereferenced at any @@ -88,24 +106,12 @@ struct fanotify_event { static inline bool fanotify_event_has_path(struct fanotify_event *event) { - return event->fh_type == FILEID_ROOT; + return event->fh.type == FILEID_ROOT; } static inline bool fanotify_event_has_fid(struct fanotify_event *event) { - return event->fh_type != FILEID_ROOT && - event->fh_type != FILEID_INVALID; -} - -static inline bool fanotify_event_has_ext_fh(struct fanotify_event *event) -{ - return fanotify_event_has_fid(event) && - event->fh_len > FANOTIFY_INLINE_FH_LEN; -} - -static inline void *fanotify_event_fh(struct fanotify_event *event) -{ - return fanotify_fid_fh(&event->fid, event->fh_len); + return fanotify_fid_has_fh(&event->fh); } /* diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 0aa362b88550..beb9f0661a7c 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -51,14 +51,19 @@ struct kmem_cache *fanotify_perm_event_cachep __read_mostly; #define FANOTIFY_EVENT_ALIGN 4 +static int fanotify_fid_info_len(struct fanotify_fid_hdr *fh) +{ + return roundup(sizeof(struct fanotify_event_info_fid) + + sizeof(struct file_handle) + fh->len, + FANOTIFY_EVENT_ALIGN); +} + static int fanotify_event_info_len(struct fanotify_event *event) { if (!fanotify_event_has_fid(event)) return 0; - return roundup(sizeof(struct fanotify_event_info_fid) + - sizeof(struct file_handle) + event->fh_len, - FANOTIFY_EVENT_ALIGN); + return fanotify_fid_info_len(&event->fh); } /* @@ -204,13 +209,14 @@ static int process_access_response(struct fsnotify_group *group, return -ENOENT; } -static int copy_fid_to_user(struct fanotify_event *event, char __user *buf) +static int copy_fid_to_user(__kernel_fsid_t *fsid, struct fanotify_fid_hdr *fh, + struct fanotify_fid *fid, char __user *buf) { struct fanotify_event_info_fid info = { }; struct file_handle handle = { }; - unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh; - size_t fh_len = event->fh_len; - size_t len = fanotify_event_info_len(event); + unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *data; + size_t fh_len = fh->len; + size_t len = fanotify_fid_info_len(fh); if (!len) return 0; @@ -221,13 +227,13 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf) /* Copy event info fid header followed by vaiable sized file handle */ info.hdr.info_type = FAN_EVENT_INFO_TYPE_FID; info.hdr.len = len; - info.fsid = event->fid.fsid; + info.fsid = *fsid; if (copy_to_user(buf, &info, sizeof(info))) return -EFAULT; buf += sizeof(info); len -= sizeof(info); - handle.handle_type = event->fh_type; + handle.handle_type = fh->type; handle.handle_bytes = fh_len; if (copy_to_user(buf, &handle, sizeof(handle))) return -EFAULT; @@ -238,12 +244,12 @@ static int copy_fid_to_user(struct fanotify_event *event, char __user *buf) * For an inline fh, copy through stack to exclude the copy from * usercopy hardening protections. */ - fh = fanotify_event_fh(event); + data = fanotify_fid_fh(fid, fh_len); if (fh_len <= FANOTIFY_INLINE_FH_LEN) { - memcpy(bounce, fh, fh_len); - fh = bounce; + memcpy(bounce, data, fh_len); + data = bounce; } - if (copy_to_user(buf, fh, fh_len)) + if (copy_to_user(buf, data, fh_len)) return -EFAULT; /* Pad with 0's */ @@ -301,7 +307,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, if (fanotify_event_has_path(event)) { fd_install(fd, f); } else if (fanotify_event_has_fid(event)) { - ret = copy_fid_to_user(event, buf + FAN_EVENT_METADATA_LEN); + ret = copy_fid_to_user(&event->fsid, &event->fh, &event->fid, + buf + FAN_EVENT_METADATA_LEN); if (ret < 0) return ret; } From patchwork Mon Feb 17 13:14:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386407 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 3908F14E3 for ; Mon, 17 Feb 2020 13:15:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 10F7322B48 for ; Mon, 17 Feb 2020 13:15:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MwxnCj6o" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729180AbgBQNP2 (ORCPT ); Mon, 17 Feb 2020 08:15:28 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:40273 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729151AbgBQNPY (ORCPT ); Mon, 17 Feb 2020 08:15:24 -0500 Received: by mail-wm1-f67.google.com with SMTP id t14so18415650wmi.5 for ; Mon, 17 Feb 2020 05:15:22 -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=i8Cgn1/XkKY0izl8w6EPwd7OUxtAip/yA9F16G0Snms=; b=MwxnCj6ov0B+ItjCj9LoBUfNQInd5VAKCrIXJFsGa/bWJ+eMGEcc1FkNZz7sPG/YUG SdJA8AL5CWQiCLU5N2ln/fL2VNZ+kqYJ6Wj+eSI0Hx1l1xy0R3hqZXAbigDnepf4QC5a 3NCWfqsOvSX8WVtaMyD+oQQLSyewvD1ELNZ1AsIZ6vLnGepHGFsyUTBbPqNJeXHOGgLh mF5wEt+6l6vkLaejSENiXM8AwB0XrF9quLtAGrhZHU2acX1r00sim0KA3s1TV3CRmQyP MaN9DEQScGxB0WKWEOImlxhh8YLJQKRFg8g652CzMLPChU25GV/ibXPn+tP0913PL0Hi BB1w== 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=i8Cgn1/XkKY0izl8w6EPwd7OUxtAip/yA9F16G0Snms=; b=Xeqad0wNflYCT3iBM35D1vILjoavwM5SS87tUhjs16MZ5LYmOXMsCxfxykqEAHQT12 LFFyoCcrmqVssdfjzXBkcv8bnus8FmrRW6GnXyTU0flO6gGQ7RJoYNb3rid+xfKVJTqn 9tF5tz1G7cbaCOCtFtsH8X9VsTcacjxAmUNfyBXWuRonDWhJNqOo2Uzl8OAXoP+Hhg6+ jGl3VJvgYUnyIx/8Ojwepjxwm7FhriusnRwniT1wcH98ZYsB0RpuCWgt2CN9YLO7/rYZ ykQvjZ6C+iy0CEihXz7LgomPO0dFnPqgjEjWNU0f8CsyhsUIVAy1mbJgAAFHphoCSaLj P4LA== X-Gm-Message-State: APjAAAV5hTObC2oq8R5enDT1EssxtRAjs8d7N+WFKIv8C0gEOn0Bwt2Z K1QPDyNYcE7hWNEa9id//bA= X-Google-Smtp-Source: APXvYqwdnHN4yETib+bLsqpqApD+4TEn0S3O99IeQMRhSbqjfN4A6SRPAnCeauGkuvv4XZ0D2KcTBA== X-Received: by 2002:a7b:cb46:: with SMTP id v6mr23605791wmj.117.1581945322107; Mon, 17 Feb 2020 05:15:22 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:21 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 12/16] fanotify: record name info for FAN_DIR_MODIFY event Date: Mon, 17 Feb 2020 15:14:51 +0200 Message-Id: <20200217131455.31107-13-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org For FAN_DIR_MODIFY event, allocate a larger event struct to store the dir entry name along side the directory fid. We are going to add support for reporting parent fid, name and child fid for events reported on children. FAN_DIR_MODIFY event does not record nor report the child fid, but in order to stay consistent with events "on child", we store the directory fid in struct fanotify_name_event and not in the base struct fanotify_event as we do for other event types. This wastes a few unused bytes (16) of memory per FAN_DIR_MODIFY event, but keeps the code simpler and avoids creating a custom kmem_cache pool just for FAN_DIR_MODIFY events. At this point, name info reporting is not yet implemented, so trying to set FAN_DIR_MODIFY in mark mask will return -EINVAL. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 87 +++++++++++++++++++++++++++--- fs/notify/fanotify/fanotify.h | 65 +++++++++++++++++++++- fs/notify/fanotify/fanotify_user.c | 5 +- 3 files changed, 149 insertions(+), 8 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 3bc28f08aad1..fc75dc53a218 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -33,7 +33,22 @@ static bool should_merge(struct fsnotify_event *old_fsn, if (fanotify_event_has_path(old)) { return old->path.mnt == new->path.mnt && old->path.dentry == new->path.dentry; - } else if (fanotify_event_has_fid(old)) { + } + + if (!fanotify_fsid_equal(&old->fsid, &new->fsid)) + return false; + + if (fanotify_event_has_dfid_name(old)) { + if (!fanotify_dfid_name_equal(FANOTIFY_NE(old_fsn), + FANOTIFY_NE(new_fsn))) + return false; + + /* FAN_DIR_MODIFY does not encode the "child" fid */ + if (!fanotify_event_has_fid(old)) + return true; + } + + if (fanotify_event_has_fid(old)) { /* * We want to merge many dirent events in the same dir (i.e. * creates/unlinks/renames), but we do not want to merge dirent @@ -43,7 +58,6 @@ static bool should_merge(struct fsnotify_event *old_fsn, * unlink pair or rmdir+create pair of events. */ return (old->mask & FS_ISDIR) == (new->mask & FS_ISDIR) && - fanotify_fsid_equal(&old->fsid, &new->fsid) && fanotify_fid_equal(&old->fid, &new->fid, old->fh.len); } @@ -279,13 +293,16 @@ static struct inode *fanotify_fid_inode(struct inode *to_tell, u32 event_mask, struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, + const struct qstr *file_name, __kernel_fsid_t *fsid) { struct fanotify_event *event = NULL; + struct fanotify_name_event *fne = NULL; gfp_t gfp = GFP_KERNEL_ACCOUNT; struct inode *id = fanotify_fid_inode(inode, mask, data, data_type); const struct path *path = fsnotify_data_path(data, data_type); struct dentry *dentry = fsnotify_data_dentry(data, data_type); + struct inode *dir = NULL; /* * For queues with unlimited length lost events are not expected and @@ -310,12 +327,56 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, event = &pevent->fae; pevent->response = 0; pevent->state = FAN_EVENT_INIT; + /* + * Make sure that fanotify_event_has_fid() and + * fanotify_event_has_name() are false for permission events. + */ + id = NULL; + event->dfh.type = FILEID_ROOT; + goto init; + } + + /* + * For FAN_DIR_MODIFY event, we report the fid of the directory and + * the name of the modified entry. + * Allocate an fanotify_name_event struct and copy the name. + */ + if (mask & FAN_DIR_MODIFY && !(WARN_ON_ONCE(!file_name))) { + char *name = NULL; + + /* + * Make sure that fanotify_event_has_name() is true and that + * fanotify_event_has_fid() is false for FAN_DIR_MODIFY events. + */ + id = NULL; + dir = inode; + if (file_name->len + 1 > FANOTIFY_INLINE_NAME_LEN) { + name = kmalloc(file_name->len + 1, gfp); + if (!name) + goto out; + } + + fne = kmem_cache_alloc(fanotify_name_event_cachep, gfp); + if (!fne) + goto out; + + event = &fne->fae; + if (!name) + name = fne->inline_name; + strcpy(name, file_name->name); + fne->name.name = name; + fne->name.len = file_name->len; + event->fh.type = FILEID_INVALID; + event->dfh.type = FILEID_INVALID; goto init; } + event = kmem_cache_alloc(fanotify_event_cachep, gfp); if (!event) goto out; -init: __maybe_unused + + event->dfh.type = FILEID_ROOT; +init: /* * Use the dentry instead of inode as tag for event queue, so event * reported on parent is merged with event reported on child when both @@ -328,11 +389,16 @@ init: __maybe_unused else event->pid = get_pid(task_tgid(current)); event->fh.len = 0; + event->dfh.len = 0; if (fsid) event->fsid = *fsid; - if (id && FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { /* Report the event without a file identifier on encode error */ - event->fh_type = fanotify_encode_fid(event, id, gfp, fsid); + if (id) + event->fh = fanotify_encode_fid(&event->fid, id, gfp); + /* The reported name is relative to 'dir' */ + if (fne) + event->dfh = fanotify_encode_fid(&fne->dfid, dir, gfp); } else if (path) { event->fh.type = FILEID_ROOT; event->path = *path; @@ -439,7 +505,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, } event = fanotify_alloc_event(group, inode, mask, data, data_type, - &fsid); + file_name, &fsid); ret = -ENOMEM; if (unlikely(!event)) { /* @@ -494,6 +560,15 @@ static void fanotify_free_event(struct fsnotify_event *fsn_event) kmem_cache_free(fanotify_perm_event_cachep, FANOTIFY_PE(fsn_event)); return; + } else if (fanotify_event_has_dfid_name(event)) { + struct fanotify_name_event *fne = FANOTIFY_NE(fsn_event); + + if (fanotify_fid_has_ext_fh(&event->dfh)) + kfree(fne->dfid.ext_fh); + if (fanotify_event_has_ext_name(fne)) + kfree(fne->name.name); + kmem_cache_free(fanotify_name_event_cachep, fne); + return; } kmem_cache_free(fanotify_event_cachep, event); } diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 4fee002235b6..e4a67a2d77b8 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -6,6 +6,7 @@ extern struct kmem_cache *fanotify_mark_cache; extern struct kmem_cache *fanotify_event_cachep; +extern struct kmem_cache *fanotify_name_event_cachep; extern struct kmem_cache *fanotify_perm_event_cachep; /* Possible states of the permission event */ @@ -84,9 +85,10 @@ struct fanotify_event { * on 64bit arch and to use fh.type as an indication of whether path * or fid are used in the union: * FILEID_ROOT (0) for path, > 0 for fid, FILEID_INVALID for neither. + * Non zero dfh.type indicates embedded in an fanotify_name_event. */ struct fanotify_fid_hdr fh; - u16 pad; + struct fanotify_fid_hdr dfh; __kernel_fsid_t fsid; union { /* @@ -114,6 +116,66 @@ static inline bool fanotify_event_has_fid(struct fanotify_event *event) return fanotify_fid_has_fh(&event->fh); } +/* + * Structure for fanotify events with name info. + * DNAME_INLINE_LEN is good enough for dentry name, so it's good enough for us. + * It also happens to bring the size of this struct to 128 bytes on 64bit arch. + */ +#define FANOTIFY_INLINE_NAME_LEN DNAME_INLINE_LEN + +struct fanotify_name_event { + struct fanotify_event fae; + struct fanotify_fid dfid; + struct qstr name; + unsigned char inline_name[FANOTIFY_INLINE_NAME_LEN]; +}; + +static inline struct fanotify_name_event * +FANOTIFY_NE(struct fsnotify_event *fse) +{ + return container_of(fse, struct fanotify_name_event, fae.fse); +} + +static inline bool fanotify_event_has_dfid_name(struct fanotify_event *event) +{ + return event->dfh.type != FILEID_ROOT; +} + +static inline unsigned int fanotify_event_name_len(struct fanotify_event *event) +{ + return event->dfh.type != FILEID_ROOT ? + FANOTIFY_NE(&event->fse)->name.len : 0; +} + +static inline bool fanotify_event_has_ext_name(struct fanotify_name_event *fne) +{ + return fne->name.len + 1 > FANOTIFY_INLINE_NAME_LEN; +} + +static inline bool fanotify_dfid_name_equal(struct fanotify_name_event *fne1, + struct fanotify_name_event *fne2) +{ + struct qstr *name1 = &fne1->name; + struct qstr *name2 = &fne2->name; + struct fanotify_fid_hdr *dfh1 = &fne1->fae.dfh; + struct fanotify_fid_hdr *dfh2 = &fne2->fae.dfh; + + if (dfh1->type != dfh2->type || dfh1->len != dfh2->len || + name1->len != name2->len) + return false; + + /* Could be pointing to same external_name */ + if (name1->len && name1->name != name2->name && + strcmp(name1->name, name2->name)) + return false; + + /* No dfid means that encoding failed */ + if (!dfh1->len) + return true; + + return fanotify_fid_equal(&fne1->dfid, &fne2->dfid, dfh1->len); +} + /* * Structure for permission fanotify events. It gets allocated and freed in * fanotify_handle_event() since we wait there for user response. When the @@ -148,4 +210,5 @@ static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse) struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, struct inode *inode, u32 mask, const void *data, int data_type, + const struct qstr *file_name, __kernel_fsid_t *fsid); diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index beb9f0661a7c..284f3548bb79 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -47,6 +47,7 @@ extern const struct fsnotify_ops fanotify_fsnotify_ops; struct kmem_cache *fanotify_mark_cache __read_mostly; struct kmem_cache *fanotify_event_cachep __read_mostly; +struct kmem_cache *fanotify_name_event_cachep __read_mostly; struct kmem_cache *fanotify_perm_event_cachep __read_mostly; #define FANOTIFY_EVENT_ALIGN 4 @@ -831,7 +832,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) group->memcg = get_mem_cgroup_from_mm(current->mm); oevent = fanotify_alloc_event(group, NULL, FS_Q_OVERFLOW, NULL, - FSNOTIFY_EVENT_NONE, NULL); + FSNOTIFY_EVENT_NONE, NULL, NULL); if (unlikely(!oevent)) { fd = -ENOMEM; goto out_destroy_group; @@ -1147,6 +1148,8 @@ static int __init fanotify_user_setup(void) fanotify_mark_cache = KMEM_CACHE(fsnotify_mark, SLAB_PANIC|SLAB_ACCOUNT); fanotify_event_cachep = KMEM_CACHE(fanotify_event, SLAB_PANIC); + fanotify_name_event_cachep = KMEM_CACHE(fanotify_name_event, + SLAB_PANIC); if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) { fanotify_perm_event_cachep = KMEM_CACHE(fanotify_perm_event, SLAB_PANIC); From patchwork Mon Feb 17 13:14:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386403 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 AA637139A for ; Mon, 17 Feb 2020 13:15:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 82C0D208C4 for ; Mon, 17 Feb 2020 13:15:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MI1CsE3t" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729030AbgBQNP1 (ORCPT ); Mon, 17 Feb 2020 08:15:27 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:39939 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729062AbgBQNP0 (ORCPT ); Mon, 17 Feb 2020 08:15:26 -0500 Received: by mail-wr1-f68.google.com with SMTP id t3so19676958wru.7; Mon, 17 Feb 2020 05:15:24 -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=VlYgvIwOdhyhUz4lK253x8q9VozlyCJr3zdxshyY+mw=; b=MI1CsE3t508bvqGqsR/YJOYTgE4BHulTJmrTHvlwbfU557s/0tkF6F/priYIEdFP0k lrlWyoaiklt6lxareJN+oz+RKCbw6s50n6m8DJ/BCBA41YR1iGf77n5JREsF+qeJHptW xYG7u7L6NU4WLyWUzvNNlp1Xh55xmaS8wAn0h1kGpIj0MJOQnHc+vVgNjx8QlAOWb7Z3 eRXi3ggkxZAXrwbFc3UElXjBO8wVYoXcOx9iIRCs51n2OjrLR0ejKNIGSuZbtAg5+f55 Y5N4M3y36q6q159JOK8MmJ+hbjF/8qHckryW6rZg/+E84YfcnZv2NT/z49hqraDC2b7n eQ/w== 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=VlYgvIwOdhyhUz4lK253x8q9VozlyCJr3zdxshyY+mw=; b=XhdcBmqAtY0phDAjTvBB+d2lhnfFX4w446dvkNRYFgsUSw0nGS3vUt7ESVH8p4KuYS OF4X5cquaQR7CUjlg9mhb3i910JCb2qhXw8Mil49PG2HcsylWclJfpmYBi89v5bySEdL 81piiOZc+3T9cxR6e//EICLcDQ4xWNsstVEMauAku9MulrC4YNolaFrFKsYCkEWhor1F +o5AhaGFBjbM9n4B1h9TxsSjsd4lBsnZT3XBogiJLStPgWuJFGtfWf2zOt04ZB6x2TLd TTiGzXykIx4NQ+N+0jtoxbdAQe0ptWKGhTwhxcBYaTRsMp0yXLQweeR/EuXmHHKJeC30 SDeA== X-Gm-Message-State: APjAAAVh4igHzg4ASRXHlY7gL9LtSZJAQLunDJrK5HyRofqL2guzyysK QbK0O044hAPjmiLcpO069Vs= X-Google-Smtp-Source: APXvYqzmUIQoOqIgTBovSm/QkZx5mdkuDOVo9yqPteD/kS0Fn+nzk0DQFVV8CpvZnFE3r9ryAqFb2A== X-Received: by 2002:adf:ca07:: with SMTP id o7mr21638636wrh.49.1581945323285; Mon, 17 Feb 2020 05:15:23 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:22 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v2 13/16] fanotify: report name info for FAN_DIR_MODIFY event Date: Mon, 17 Feb 2020 15:14:52 +0200 Message-Id: <20200217131455.31107-14-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Report event FAN_DIR_MODIFY with name in a variable length record similar to how fid's are reported. With name info reporting implemented, setting FAN_DIR_MODIFY in mark mask is now allowed. When events are reported with name, the reported fid identifies the directory and the name follows the fid. The info record type for this event info is FAN_EVENT_INFO_TYPE_DFID_NAME. For now, all reported events have at most one info record which is either FAN_EVENT_INFO_TYPE_FID or FAN_EVENT_INFO_TYPE_DFID_NAME (for FAN_DIR_MODIFY). Later on, events "on child" will report both records. There are several ways that an application can use this information: 1. When watching a single directory, the name is always relative to the watched directory, so application need to fstatat(2) the name relative to the watched directory. 2. When watching a set of directories, the application could keep a map of dirfd for all watched directories and hash the map by fid obtained with name_to_handle_at(2). When getting a name event, the fid in the event info could be used to lookup the base dirfd in the map and then call fstatat(2) with that dirfd. 3. When watching a filesystem (FAN_MARK_FILESYSTEM) or a large set of directories, the application could use open_by_handle_at(2) with the fid in event info to obtain dirfd for the directory where event happened and call fstatat(2) with this dirfd. The last option scales better for a large number of watched directories. The first two options may be available in the future also for non privileged fanotify watchers, because open_by_handle_at(2) requires the CAP_DAC_READ_SEARCH capability. Signed-off-by: Amir Goldstein Reported-by: kbuild test robot Reported-by: kbuild test robot --- fs/notify/fanotify/fanotify.c | 2 +- fs/notify/fanotify/fanotify_user.c | 120 ++++++++++++++++++++++------- include/linux/fanotify.h | 3 +- include/uapi/linux/fanotify.h | 1 + 4 files changed, 98 insertions(+), 28 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index fc75dc53a218..b651c18d3a93 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -478,7 +478,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, BUILD_BUG_ON(FAN_OPEN_EXEC != FS_OPEN_EXEC); BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM); - BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 19); + BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 20); mask = fanotify_group_event_mask(group, iter_info, mask, data, data_type); diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 284f3548bb79..a1bafc21ebbb 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -51,20 +51,32 @@ struct kmem_cache *fanotify_name_event_cachep __read_mostly; struct kmem_cache *fanotify_perm_event_cachep __read_mostly; #define FANOTIFY_EVENT_ALIGN 4 +#define FANOTIFY_INFO_HDR_LEN \ + (sizeof(struct fanotify_event_info_fid) + sizeof(struct file_handle)) -static int fanotify_fid_info_len(struct fanotify_fid_hdr *fh) +static int fanotify_fid_info_len(int fh_len, int name_len) { - return roundup(sizeof(struct fanotify_event_info_fid) + - sizeof(struct file_handle) + fh->len, - FANOTIFY_EVENT_ALIGN); + int info_len = fh_len; + + if (name_len) + info_len += name_len + 1; + + return roundup(FANOTIFY_INFO_HDR_LEN + info_len, FANOTIFY_EVENT_ALIGN); } static int fanotify_event_info_len(struct fanotify_event *event) { - if (!fanotify_event_has_fid(event)) - return 0; + int info_len = 0; + + if (fanotify_event_has_fid(event)) + info_len += fanotify_fid_info_len(event->fh.len, 0); + + if (fanotify_event_has_dfid_name(event)) { + info_len += fanotify_fid_info_len(event->dfh.len, + fanotify_event_name_len(event)); + } - return fanotify_fid_info_len(&event->fh); + return info_len; } /* @@ -210,23 +222,34 @@ static int process_access_response(struct fsnotify_group *group, return -ENOENT; } -static int copy_fid_to_user(__kernel_fsid_t *fsid, struct fanotify_fid_hdr *fh, - struct fanotify_fid *fid, char __user *buf) +static int copy_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fid_hdr *fh, + struct fanotify_fid *fid, const struct qstr *name, + char __user *buf, size_t count) { struct fanotify_event_info_fid info = { }; struct file_handle handle = { }; - unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *data; + unsigned char bounce[max(FANOTIFY_INLINE_FH_LEN, DNAME_INLINE_LEN)]; + const unsigned char *data; size_t fh_len = fh->len; - size_t len = fanotify_fid_info_len(fh); + size_t name_len = name ? name->len : 0; + size_t info_len = fanotify_fid_info_len(fh_len, name_len); + size_t len = info_len; + + pr_debug("%s: fh_len=%lu name_len=%lu, info_len=%lu, count=%lu\n", + __func__, fh_len, name_len, info_len, count); - if (!len) + if (!fh_len || (name && !name_len)) return 0; - if (WARN_ON_ONCE(len < sizeof(info) + sizeof(handle) + fh_len)) + if (WARN_ON_ONCE(len < sizeof(info) || len > count)) return -EFAULT; - /* Copy event info fid header followed by vaiable sized file handle */ - info.hdr.info_type = FAN_EVENT_INFO_TYPE_FID; + /* + * Copy event info fid header followed by vaiable sized file handle + * and optionally followed by vaiable sized filename. + */ + info.hdr.info_type = name_len ? FAN_EVENT_INFO_TYPE_DFID_NAME : + FAN_EVENT_INFO_TYPE_FID; info.hdr.len = len; info.fsid = *fsid; if (copy_to_user(buf, &info, sizeof(info))) @@ -234,6 +257,9 @@ static int copy_fid_to_user(__kernel_fsid_t *fsid, struct fanotify_fid_hdr *fh, buf += sizeof(info); len -= sizeof(info); + if (WARN_ON_ONCE(len < sizeof(handle))) + return -EFAULT; + handle.handle_type = fh->type; handle.handle_bytes = fh_len; if (copy_to_user(buf, &handle, sizeof(handle))) @@ -241,9 +267,12 @@ static int copy_fid_to_user(__kernel_fsid_t *fsid, struct fanotify_fid_hdr *fh, buf += sizeof(handle); len -= sizeof(handle); + if (WARN_ON_ONCE(len < fh_len)) + return -EFAULT; + /* - * For an inline fh, copy through stack to exclude the copy from - * usercopy hardening protections. + * For an inline fh and inline file name, copy through stack to exclude + * the copy from usercopy hardening protections. */ data = fanotify_fid_fh(fid, fh_len); if (fh_len <= FANOTIFY_INLINE_FH_LEN) { @@ -253,14 +282,33 @@ static int copy_fid_to_user(__kernel_fsid_t *fsid, struct fanotify_fid_hdr *fh, if (copy_to_user(buf, data, fh_len)) return -EFAULT; - /* Pad with 0's */ buf += fh_len; len -= fh_len; + + if (name_len) { + /* Copy the filename with terminating null */ + name_len++; + if (WARN_ON_ONCE(len < name_len)) + return -EFAULT; + + data = name->name; + if (name_len <= DNAME_INLINE_LEN) { + memcpy(bounce, data, name_len); + data = bounce; + } + if (copy_to_user(buf, data, name_len)) + return -EFAULT; + + buf += name_len; + len -= name_len; + } + + /* Pad with 0's */ WARN_ON_ONCE(len < 0 || len >= FANOTIFY_EVENT_ALIGN); if (len > 0 && clear_user(buf, len)) return -EFAULT; - return 0; + return info_len; } static ssize_t copy_event_to_user(struct fsnotify_group *group, @@ -282,12 +330,12 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, metadata.mask = event->mask & FANOTIFY_OUTGOING_EVENTS; metadata.pid = pid_vnr(event->pid); - if (fanotify_event_has_path(event)) { + if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + metadata.event_len += fanotify_event_info_len(event); + } else if (fanotify_event_has_path(event)) { fd = create_fd(group, event, &f); if (fd < 0) return fd; - } else if (fanotify_event_has_fid(event)) { - metadata.event_len += fanotify_event_info_len(event); } metadata.fd = fd; @@ -302,16 +350,36 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, if (copy_to_user(buf, &metadata, FAN_EVENT_METADATA_LEN)) goto out_close_fd; + buf += FAN_EVENT_METADATA_LEN; + count -= FAN_EVENT_METADATA_LEN; + if (fanotify_is_perm_event(event->mask)) FANOTIFY_PE(fsn_event)->fd = fd; - if (fanotify_event_has_path(event)) { + if (f) fd_install(fd, f); - } else if (fanotify_event_has_fid(event)) { - ret = copy_fid_to_user(&event->fsid, &event->fh, &event->fid, - buf + FAN_EVENT_METADATA_LEN); + + /* Event info records order is: dir fid + name, child fid */ + if (fanotify_event_has_dfid_name(event)) { + struct fanotify_name_event *fne = FANOTIFY_NE(fsn_event); + + ret = copy_info_to_user(&event->fsid, &event->dfh, &fne->dfid, + &fne->name, buf, count); if (ret < 0) return ret; + + buf += ret; + count -= ret; + } + + if (fanotify_event_has_fid(event)) { + ret = copy_info_to_user(&event->fsid, &event->fh, &event->fid, + NULL, buf, count); + if (ret < 0) + return ret; + + buf += ret; + count -= ret; } return metadata.event_len; diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index b79fa9bb7359..3049a6c06d9e 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -47,7 +47,8 @@ * Directory entry modification events - reported only to directory * where entry is modified and not to a watching parent. */ -#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE) +#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE | \ + FAN_DIR_MODIFY) /* Events that can only be reported with data type FSNOTIFY_EVENT_INODE */ #define FANOTIFY_INODE_EVENTS (FANOTIFY_DIRENT_EVENTS | \ diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 615fa2c87179..2b56e194b858 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -117,6 +117,7 @@ struct fanotify_event_metadata { }; #define FAN_EVENT_INFO_TYPE_FID 1 +#define FAN_EVENT_INFO_TYPE_DFID_NAME 2 /* Variable length info record following event metadata */ struct fanotify_event_info_header { From patchwork Mon Feb 17 13:14:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386405 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 0A1C5159A for ; Mon, 17 Feb 2020 13:15:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DE406207FD for ; Mon, 17 Feb 2020 13:15:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SStQvpfj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729169AbgBQNP2 (ORCPT ); Mon, 17 Feb 2020 08:15:28 -0500 Received: from mail-wm1-f51.google.com ([209.85.128.51]:37660 "EHLO mail-wm1-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729161AbgBQNP0 (ORCPT ); Mon, 17 Feb 2020 08:15:26 -0500 Received: by mail-wm1-f51.google.com with SMTP id a6so18438484wme.2; Mon, 17 Feb 2020 05:15:25 -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=8F0CX6it1nL7U9hvMyLSspSI86vC4vkI7nzEDH4dLio=; b=SStQvpfjFS/G/sZ1jYT5Zy631Hp06tAKeQu42LY4NUG5rkO7AZefVmtdjd1o/QFiSD Oz1Bt5YXrrzntwQxdcIIT3Fyx1vY4Oki3tAp1PNik+xwiA1LWvX9uqlAuTCdbhYSY0iY jQ7sNwKRLELgNy3uEz7BANyO6YnqEgEXCPlBvT6Wm11Q6PSoIHH1IO79a5q18IYx62rS 9IeTp51XsEDDOg3P1AodbQx0MVC8m0QMO0vfaks7uwuDMbVd2qvUCjMEbau+FM8Ip8Gp VxrD4ptaRm3meTpiBp2HcHXrfe7FuycL9oK+SHIUzhM2RT8S65JG7d8iogYd6e+cnXWl mZhw== 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=8F0CX6it1nL7U9hvMyLSspSI86vC4vkI7nzEDH4dLio=; b=Vsw7RVxyZA01fcsnj48ODfxstUYaYA6eGX0MtytGtmdvBTMvGtw70bcHdJleTNZ53B ERD7tOEHN0wR2lI+GN607qOZsEyvccXblA+AUdxOID7UrR1beBRFJ7P18RJbM7mP6qzG TI2m+Gdq4ozYz9CTAT0mBJdsXdgephBJ8x/JORL/bHIokOK5puZHfQQV7zdtu7ex9VLE GCKHERuZLPKe/lp6UNWSoJTH3rjDF7J0mnBS+ollY6nb27RNGJqjNqNEiZBwC79ZozZj /6ZTsIM8IMYl5mJGUccaSTl9Z9xRJUBntLIjh2UZ6gylt4j26Q2a9n90+LLPw4l7ZvX6 M7KQ== X-Gm-Message-State: APjAAAXHrcvZJtskV+tfdpIXFHU2PUiNz3I9bpoLfulSaTEMr/vTtosF yrXd6omdlMl0OnRsRBfH3R84krtW X-Google-Smtp-Source: APXvYqwWDykXdOOvHNRbvLMYrCiHlGu16fI+ZwqQO3AUpU7auFal6T1OSRhkzaIsYbHbXIfYXyULRQ== X-Received: by 2002:a1c:f001:: with SMTP id a1mr21419112wmb.76.1581945324455; Mon, 17 Feb 2020 05:15:24 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:23 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v2 14/16] fanotify: report parent fid + name with FAN_REPORT_NAME Date: Mon, 17 Feb 2020 15:14:53 +0200 Message-Id: <20200217131455.31107-15-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-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_NAME, we report the parent fid and name for events possible "on child" (e.g. FAN_MODIFY) in addition to reporting the child fid. The flag FAN_REPORT_NAME requires the flag FAN_REPORT_FID and there is a constant for setting both flags named FAN_REPORT_FID_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 name info is reported for FAN_DIR_MODIFY events. The child fid is reported with another info record of type FAN_EVENT_INFO_TYPE_FID that follows the first info record, with the same fid info that is reported to a group with FAN_REPORT_FID flag. Events with name are reported the same way when reported to sb, mount or inode marks and when reported to a directory watching children. Events not possible "on child" (e.g. FAN_DELETE_SELF) are reported with a single FAN_EVENT_INFO_TYPE_FID record, same as they are reported to a group with FAN_REPORT_FID flag. If parent is unknown (dentry is disconnected) or parent is not on the same filesystem as child (dentry is sb root), event is also reported with a single FAN_EVENT_INFO_TYPE_FID record. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 25 +++++++++++++++++++++++-- fs/notify/fanotify/fanotify_user.c | 6 +++++- include/linux/fanotify.h | 2 +- include/uapi/linux/fanotify.h | 4 ++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b651c18d3a93..43c338a8a2f1 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -302,6 +302,8 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, struct inode *id = fanotify_fid_inode(inode, mask, data, data_type); const struct path *path = fsnotify_data_path(data, data_type); struct dentry *dentry = fsnotify_data_dentry(data, data_type); + struct dentry *parent = NULL; + struct name_snapshot child_name; struct inode *dir = NULL; /* @@ -339,17 +341,32 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, /* * For FAN_DIR_MODIFY event, we report the fid of the directory and * the name of the modified entry. + * With flag FAN_REPORT_NAME, we report the parent fid and name for + * events possible "on child" in addition to reporting the child fid. + * If parent is unknown (dentry is disconnected) or parent is not on the + * same filesystem as child (dentry is sb root), only "child" fid is + * reported. Events are reported the same way when reported to sb, mount + * or inode marks and when reported to a directory watching children. * Allocate an fanotify_name_event struct and copy the name. */ if (mask & FAN_DIR_MODIFY && !(WARN_ON_ONCE(!file_name))) { - char *name = NULL; - /* * Make sure that fanotify_event_has_name() is true and that * fanotify_event_has_fid() is false for FAN_DIR_MODIFY events. */ id = NULL; dir = inode; + } else if (FAN_GROUP_FLAG(group, FAN_REPORT_NAME) && + mask & FS_EVENTS_POSS_ON_CHILD && + likely(dentry && !IS_ROOT(dentry))) { + parent = dget_parent(dentry); + dir = d_inode(parent); + take_dentry_name_snapshot(&child_name, dentry); + file_name = &child_name.name; + } + if (dir) { + char *name = NULL; + if (file_name->len + 1 > FANOTIFY_INLINE_NAME_LEN) { name = kmalloc(file_name->len + 1, gfp); if (!name) @@ -409,6 +426,10 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, event->path.dentry = NULL; } out: + if (parent) { + dput(parent); + release_dentry_name_snapshot(&child_name); + } memalloc_unuse_memcg(); return event; } diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index a1bafc21ebbb..5d369aa5d1bc 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -875,6 +875,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) (flags & FANOTIFY_CLASS_BITS) != FAN_CLASS_NOTIF) return -EINVAL; + /* Child name is reported with partent fid */ + if ((flags & FAN_REPORT_NAME) && !(flags & FAN_REPORT_FID)) + return -EINVAL; + user = get_current_user(); if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) { free_uid(user); @@ -1210,7 +1214,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 3049a6c06d9e..5412a25c54c0 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -19,7 +19,7 @@ FAN_CLASS_PRE_CONTENT) #define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | \ - FAN_REPORT_TID | FAN_REPORT_FID | \ + FAN_REPORT_TID | FAN_REPORT_FID_NAME | \ FAN_CLOEXEC | FAN_NONBLOCK | \ FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS) diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 2b56e194b858..04181769bb50 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -54,6 +54,10 @@ /* 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_NAME 0x00000400 /* Report events with name */ + +/* Convenience macro - FAN_REPORT_NAME requires FAN_REPORT_FID */ +#define FAN_REPORT_FID_NAME (FAN_REPORT_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 Mon Feb 17 13:14:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386411 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 396EF139A for ; Mon, 17 Feb 2020 13:15:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 197C9215A4 for ; Mon, 17 Feb 2020 13:15:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FpWJATGo" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729186AbgBQNPa (ORCPT ); Mon, 17 Feb 2020 08:15:30 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:32966 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729164AbgBQNP1 (ORCPT ); Mon, 17 Feb 2020 08:15:27 -0500 Received: by mail-wr1-f67.google.com with SMTP id u6so19738037wrt.0 for ; Mon, 17 Feb 2020 05:15:26 -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=YXRsI1FLp1ez4RjlBLLPoXSAG6JY/ciFQ8Zwwl8DhpQ=; b=FpWJATGo8c/CR2bW6pMfuLl6VrkmKJvAzcnijzkNY3Y/15t0rMmUOjPFPnduL95qGR uVvyYScKAmo3wyfhplZnBtwMudnp4bVIj3MMlMNaXULGTPxwyuF2nTC8MPVXVxWjWCR5 tKHesXdt+ybvPkHxbhpGZ+w4URvqhNkXL3hLXOsbYwj5YXY686P50oY8Xei4gKqNSX6p fSdYj1mjqKdl+ggo30w3qvJhaVX50TsLYjSsWUhFmTX8NM7BpoPDFchZY23zTvZpwP/P En0k3vq45sgLK8UYq0Uae3oiZIjDfZsljTR2O6ai8Pdj46TnodwKaGa68HIz2VZDekR0 +KWw== 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=YXRsI1FLp1ez4RjlBLLPoXSAG6JY/ciFQ8Zwwl8DhpQ=; b=f8V29AUeu1ESbHhr7aBUN2HkwlMC6OMDZuc7t62xBToBNnzlpRNC2kapM/OfzyYPAY HQartAEBFnmjAarzo7U6Ho79w5oPOzjWIy/RWQzDnSx3NeNX5q4/VH5AFGlxi8ZkDZ+Z VMx5vYwQUDGKMqyZN2AiE1xXJnKWyoPQjkAtUwnHo5UitFTY6asJgzHGRDzvHSg1o5KL 108k4vAHFjeC/R2rZ7/9u8bnAn82Jnyixmd4cyblqYaVwQU+2dVcAah0c4ObELWEHVcX hFguIrfSoRidgpe/6SG/3/+XLD9JC1nXA5e8j9T1scfO6DD3EiHAPewI6YLRQruPoGp1 QKzg== X-Gm-Message-State: APjAAAUXjzNpc3/F5hNYQFhRbO8mNDrUnQyMqO527BU2ZjX6F9yOz/B7 GkLnunZdgtFSj6xCQnvnpls= X-Google-Smtp-Source: APXvYqzjf6eu5g4GcuyYd36C8PfXQ0wLum0xFgMEGT8Xlga9X7WDZkt6OcdL2O+ne/R6FD9eXRoojg== X-Received: by 2002:adf:df83:: with SMTP id z3mr22070045wrl.389.1581945325564; Mon, 17 Feb 2020 05:15:25 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:25 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org Subject: [PATCH v2 15/16] fanotify: refine rules for when name is reported Date: Mon, 17 Feb 2020 15:14:54 +0200 Message-Id: <20200217131455.31107-16-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org With FAN_REPORT_NAME, name will be reported if event is in the mask of a watching parent or filesystem mark. Name will not be reported if event is only in the mask of a mark on the victim inode itself. If event is only in the mask of a marked mount, name will be reported if the victim inode is not the mount's root. Note that the mount's root could be a non-directory in case of bind mount. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 37 +++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 43c338a8a2f1..45203c1484b9 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -202,6 +202,32 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, !(mark->mask & FS_EVENT_ON_CHILD))) continue; + /* + * fanotify_alloc_event() uses the "on child" flag as indication + * for reporting name, but the flag will be masked out before + * reporting to user. + * + * With FAN_REPORT_NAME, name will be reported if event is in + * the mask of a watching parent or filesystem mark. + * name will not be reported if event is only in the mask of a + * mark on the victim inode itself. + * If event is only in the mask of a marked mount, name will be + * reported if the victim inode is not the mount's root. Note + * that the mount's root could be a non-directory in case of + * bind mount. + */ + if (FAN_GROUP_FLAG(group, FAN_REPORT_NAME) && + event_mask & mark->mask & FS_EVENTS_POSS_ON_CHILD) { + user_mask |= FS_EVENT_ON_CHILD; + if (type == FSNOTIFY_OBJ_TYPE_SB || + (type == FSNOTIFY_OBJ_TYPE_VFSMOUNT && + !WARN_ON_ONCE(data_type != FSNOTIFY_EVENT_PATH) && + path->dentry != path->mnt->mnt_root)) { + event_mask |= FS_EVENT_ON_CHILD; + marks_mask |= FS_EVENT_ON_CHILD; + } + } + marks_mask |= mark->mask; marks_ignored_mask |= mark->ignored_mask; } @@ -344,9 +370,8 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, * With flag FAN_REPORT_NAME, we report the parent fid and name for * events possible "on child" in addition to reporting the child fid. * If parent is unknown (dentry is disconnected) or parent is not on the - * same filesystem as child (dentry is sb root), only "child" fid is - * reported. Events are reported the same way when reported to sb, mount - * or inode marks and when reported to a directory watching children. + * same filesystem/mount as child (dentry is sb/mount root), only the + * "child" fid is reported. * Allocate an fanotify_name_event struct and copy the name. */ if (mask & FAN_DIR_MODIFY && !(WARN_ON_ONCE(!file_name))) { @@ -357,7 +382,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, id = NULL; dir = inode; } else if (FAN_GROUP_FLAG(group, FAN_REPORT_NAME) && - mask & FS_EVENTS_POSS_ON_CHILD && + mask & FS_EVENT_ON_CHILD && likely(dentry && !IS_ROOT(dentry))) { parent = dget_parent(dentry); dir = d_inode(parent); @@ -400,7 +425,7 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, * directory and child watches exist. */ fsnotify_init_event(&event->fse, (void *)dentry ?: inode); - event->mask = mask; + event->mask = mask & FANOTIFY_OUTGOING_EVENTS; if (FAN_GROUP_FLAG(group, FAN_REPORT_TID)) event->pid = get_pid(task_pid(current)); else @@ -503,7 +528,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, mask = fanotify_group_event_mask(group, iter_info, mask, data, data_type); - if (!mask) + if (!(mask & FANOTIFY_OUTGOING_EVENTS)) return 0; pr_debug("%s: group=%p inode=%p mask=%x\n", __func__, group, inode, From patchwork Mon Feb 17 13:14:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 11386415 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 9A5CB14E3 for ; Mon, 17 Feb 2020 13:15:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 72D70215A4 for ; Mon, 17 Feb 2020 13:15:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qDRAcOHU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729202AbgBQNPa (ORCPT ); Mon, 17 Feb 2020 08:15:30 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:36173 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729166AbgBQNPa (ORCPT ); Mon, 17 Feb 2020 08:15:30 -0500 Received: by mail-wm1-f66.google.com with SMTP id p17so18420317wma.1; Mon, 17 Feb 2020 05:15:27 -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=MPopq/7KWlkqXSzsgjde6MGol3l+YXrmzEp29RmzokU=; b=qDRAcOHUX9VxeSvORk3o+sADAPDgCaqhH5cSU8Ru9a3zXMNofts+XQywJQHur123ht F47i/iTUfHJy0OSgmKcaQFUeO17lDZF4dfBmVZmUlB7Lp2LqrUvQoIhLKecoOx8Yl8d4 52q48KWGlFQBoFuIUchnYhlVtfasWp235JSqCUXOfa9AhqgqEN0QUetFW522XMWQ0ag9 J21beKFPPsRpIiEcu5oMOcTmjpHGS7BUrftl2uhISJsmK/BLU/QYid0dBUUpOKGmmd3Q 69Gyqvxu1g0lJfDI8NgmJpgOx47EnRq5ks+0wHyEP/9/2hYUHRWF30/+8s6KeZbm9PMc 2zVA== 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=MPopq/7KWlkqXSzsgjde6MGol3l+YXrmzEp29RmzokU=; b=fcUkeqENTApv5gIhKhOYGGg16cCrbZQFG/p0i2PJ+joM9WkDOx5mTJxOi/W7DV9Ina Jje1pmiU/7sMcFbipgAjbbXUfOo4bpHxKl9iTyUUHggouz+kSg6WFTNlqt6SSPTE8G1c vEtAk2lyxLFPsMPEZy0WAu06nP5iu2fvd2YSpENjf+w+gVBlZiaQEEC2/81hh33TJ3PB 9LqhqJDPMvYTgLVdjHxUeJF3bHZHYwZcdOxSntlh+VALFkAt54oALQcu2q8MNmx7kGiC 4jkSu877LCGwszThasx3Xc/zb+C4oyVXK0NbWnUn1Jlh2FtWHxULJ9UzfdcbpyQ5nGA1 X7Yg== X-Gm-Message-State: APjAAAU5OFG8Xg6kglpgJjgmMMb27Lyrr/z3Y4RubIGPAEnc8j18tOI5 XIoBStrwrGIVOYy51cmgZyA= X-Google-Smtp-Source: APXvYqxt5XPM/viO/n6hl+qybwvNVOoVNy2BqL1jaE0LIpXLtnI56oDVdrqcCyar5IFH1m6SHQfBmA== X-Received: by 2002:a7b:c084:: with SMTP id r4mr21117319wmh.99.1581945326868; Mon, 17 Feb 2020 05:15:26 -0800 (PST) Received: from amir-ThinkPad-T480.ctera.local (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id m21sm545745wmi.27.2020.02.17.05.15.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Feb 2020 05:15:26 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org, Matthew Bobrowski Subject: [BONUS][PATCH v2 16/16] fanotify: support limited functionality for unprivileged users Date: Mon, 17 Feb 2020 15:14:55 +0200 Message-Id: <20200217131455.31107-17-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200217131455.31107-1-amir73il@gmail.com> References: <20200217131455.31107-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 new fanotify_init() flag FAN_UNPRIVILEGED. User may request an unprivileged event listener using this flag even if user is privileged. An unprivileged event listener does not get an open file descriptor in the event nor the process pid of another process. An unprivileged event listener cannot request permission events, cannot set mount/filesystem marks and cannot request unlimited queue/marks. This enables the limited functionality similar to inotify when watching a set of files and directories for OPEN/ACCESS/MODIFY/CLOSE events, without requiring SYS_CAP_ADMIN privileges. The FAN_DIR_MODIFY event and FAN_REPORT_FID_NAME init flag, provide a method for an unprivileged event listener watching a set of directories (with FAN_EVENT_ON_CHILD) to monitor all changes inside those directories. This typically requires that the listener keeps a map of watched directory fid to dirfd (O_PATH), where fid is obtained with name_to_handle_at() before starting to watch for changes. When getting an event, the reported fid of the parent should be resolved to dirfd and fstatsat(2) with dirfd and name should be used to query the state of the filesystem entry. Note that even though events do not report the event creator pid, fanotify does not merge similar events on the same object that were generated by different processes. This is aligned with exiting behavior when generating processes are outside of the listener pidns (which results in reporting 0 pid to listener). Cc: Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify_user.c | 42 ++++++++++++++++++++++++++---- include/linux/fanotify.h | 16 +++++++++++- include/uapi/linux/fanotify.h | 1 + 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 5d369aa5d1bc..ac2cdb5287fe 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -328,11 +328,21 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, metadata.vers = FANOTIFY_METADATA_VERSION; metadata.reserved = 0; metadata.mask = event->mask & FANOTIFY_OUTGOING_EVENTS; - metadata.pid = pid_vnr(event->pid); + /* + * An unprivileged event listener does not get an open file descriptor + * in the event nor another generating process pid. If the event was + * generated by the unprivileged process itself, self pid is reported. + */ + if (!FAN_GROUP_FLAG(group, FAN_UNPRIVILEGED) || + task_tgid(current) == event->pid) + metadata.pid = pid_vnr(event->pid); + else + metadata.pid = 0; if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { metadata.event_len += fanotify_event_info_len(event); - } else if (fanotify_event_has_path(event)) { + } else if (!FAN_GROUP_FLAG(group, FAN_UNPRIVILEGED) && + fanotify_event_has_path(event)) { fd = create_fd(group, event, &f); if (fd < 0) return fd; @@ -845,12 +855,26 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) int f_flags, fd; struct user_struct *user; struct fanotify_event *oevent; + unsigned int class = flags & FANOTIFY_CLASS_BITS; pr_debug("%s: flags=%x event_f_flags=%x\n", __func__, flags, event_f_flags); - if (!capable(CAP_SYS_ADMIN)) + if (flags & FAN_UNPRIVILEGED) { + /* + * User can request an unprivileged event listener even if + * user is privileged. An unprivileged event listener does not + * get an open file descriptor in the event nor the proccess id + * of another process. An unprivileged event listener and cannot + * request permission events, cannot set mount/filesystem marks + * and cannot request unlimited queue/marks. + */ + if ((flags & ~FANOTIFY_UNPRIV_INIT_FLAGS) || + class != FAN_CLASS_NOTIF) + return -EINVAL; + } else if (!capable(CAP_SYS_ADMIN)) { return -EPERM; + } #ifdef CONFIG_AUDITSYSCALL if (flags & ~(FANOTIFY_INIT_FLAGS | FAN_ENABLE_AUDIT)) @@ -916,7 +940,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; @@ -1101,6 +1125,14 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, group->priority == FS_PRIO_0) goto fput_and_out; + /* + * An unprivileged event listener is not allowed to watch a mount + * point nor a filesystem. + */ + if (FAN_GROUP_FLAG(group, FAN_UNPRIVILEGED) && + mark_type != FAN_MARK_INODE) + goto fput_and_out; + /* * Events with data type inode do not carry enough information to report * event->fd, so we do not allow setting a mask for inode events unless @@ -1214,7 +1246,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 5412a25c54c0..93107b44e4e1 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -21,7 +21,21 @@ #define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | \ FAN_REPORT_TID | FAN_REPORT_FID_NAME | \ FAN_CLOEXEC | FAN_NONBLOCK | \ - FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS) + FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS | \ + FAN_UNPRIVILEGED) + +/* + * fanotify_init() flags allowed for unprivileged listener. + * FAN_CLASS_NOTIF in this mask is purely semantic because it is zero, + * but it is the only class we allow for unprivileged listener. + * Since unprivileged listener does not provide file descriptors in events, + * FAN_REPORT_FID_NAME makes sense, but it is not a must. + * FAN_REPORT_TID does not make sense for unprivileged listener, which uses + * event->pid only to filter out events generated by listener process itself. + */ +#define FANOTIFY_UNPRIV_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \ + FAN_CLASS_NOTIF | FAN_UNPRIVILEGED | \ + FAN_REPORT_FID_NAME) #define FANOTIFY_MARK_TYPE_BITS (FAN_MARK_INODE | FAN_MARK_MOUNT | \ FAN_MARK_FILESYSTEM) diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 04181769bb50..2be673862a43 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -50,6 +50,7 @@ #define FAN_UNLIMITED_QUEUE 0x00000010 #define FAN_UNLIMITED_MARKS 0x00000020 #define FAN_ENABLE_AUDIT 0x00000040 +#define FAN_UNPRIVILEGED 0x00000080 /* Flags to determine fanotify event format */ #define FAN_REPORT_TID 0x00000100 /* event->pid is thread id */