From patchwork Tue Jun 23 17:46:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 1315401 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ubuntu.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49rtxg40Q5z9sSF; Wed, 24 Jun 2020 03:46:31 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1jnn06-0003fB-V7; Tue, 23 Jun 2020 17:46:26 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jnn05-0003ez-9M for kernel-team@lists.ubuntu.com; Tue, 23 Jun 2020 17:46:25 +0000 Received: from ip5f5af08c.dynamic.kabel-deutschland.de ([95.90.240.140] helo=wittgenstein.fritz.box) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jnn04-0005Bp-W8; Tue, 23 Jun 2020 17:46:25 +0000 From: Christian Brauner To: kernel-team@lists.ubuntu.com, seth.forshee@canonical.com Subject: [SRU][FOCAL][PATCH 1/2] UBUNTU: SAUCE: Revert "UBUNTU: SAUCE: shiftfs: fix dentry revalidation" Date: Tue, 23 Jun 2020 19:46:15 +0200 Message-Id: <20200623174616.972066-1-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stgraber@ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1884767 With patch cfaa482afb97 ("UBUNTU: SAUCE: shiftfs: fix dentry revalidation") we tried to fix https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1872757 but it introduces a regression for shiftfs on btrfs users. Creating a btrfs subvolume, deleting it, and then trying to recreate it will cause EEXIST to be returned or the file be left in a half-created state. Faulty behavior such as this can be reproduced via: btrfs subvolume create my-subvol ls -al my-subvol btrfs subvolume delete my-subvol We thus need to revert this change restoring the old behavior.This will briefly resurface https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1872757 which is fixed in a follow-up patch on top of this revert. We simply split out the minimal fix into a separate tiny patch. This reverts commit cfaa482afb97e3c05d020af80b897b061109d51f. Cc: Seth Forshee Signed-off-by: Christian Brauner Acked-by: Seth Forshee Acked-by: Stefan Bader --- fs/shiftfs.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) base-commit: 51ee04d9d3b464e9aa8509013779491f0b001ebc diff --git a/fs/shiftfs.c b/fs/shiftfs.c index f5c709805fb8..5d88193b41db 100644 --- a/fs/shiftfs.c +++ b/fs/shiftfs.c @@ -240,17 +240,19 @@ static int shiftfs_d_weak_revalidate(struct dentry *dentry, unsigned int flags) int err = 1; struct dentry *lowerd = dentry->d_fsdata; - if (lowerd->d_flags & DCACHE_OP_WEAK_REVALIDATE) { + if (d_is_negative(lowerd) != d_is_negative(dentry)) + return 0; + + if ((lowerd->d_flags & DCACHE_OP_WEAK_REVALIDATE)) err = lowerd->d_op->d_weak_revalidate(lowerd, flags); - if (err < 0) - return err; - } if (d_really_is_positive(dentry)) { struct inode *inode = d_inode(dentry); struct inode *loweri = d_inode(lowerd); shiftfs_copyattr(loweri, inode); + if (!inode->i_nlink) + err = 0; } return err; @@ -261,25 +263,23 @@ static int shiftfs_d_revalidate(struct dentry *dentry, unsigned int flags) int err = 1; struct dentry *lowerd = dentry->d_fsdata; + if (d_unhashed(lowerd) || + ((d_is_negative(lowerd) != d_is_negative(dentry)))) + return 0; + if (flags & LOOKUP_RCU) return -ECHILD; - if (lowerd->d_flags & DCACHE_OP_REVALIDATE) { + if ((lowerd->d_flags & DCACHE_OP_REVALIDATE)) err = lowerd->d_op->d_revalidate(lowerd, flags); - if (err < 0) - return err; - if (!err) { - if (!(flags & LOOKUP_RCU)) - d_invalidate(lowerd); - return -ESTALE; - } - } if (d_really_is_positive(dentry)) { struct inode *inode = d_inode(dentry); struct inode *loweri = d_inode(lowerd); shiftfs_copyattr(loweri, inode); + if (!inode->i_nlink) + err = 0; } return err; @@ -736,6 +736,24 @@ static int shiftfs_fiemap(struct inode *inode, return err; } +static int shiftfs_tmpfile(struct inode *dir, struct dentry *dentry, + umode_t mode) +{ + int err; + const struct cred *oldcred; + struct dentry *lowerd = dentry->d_fsdata; + struct inode *loweri = dir->i_private; + + if (!loweri->i_op->tmpfile) + return -EOPNOTSUPP; + + oldcred = shiftfs_override_creds(dir->i_sb); + err = loweri->i_op->tmpfile(loweri, lowerd, mode); + revert_creds(oldcred); + + return err; +} + static int shiftfs_setattr(struct dentry *dentry, struct iattr *attr) { struct dentry *lowerd = dentry->d_fsdata; @@ -1002,6 +1020,7 @@ static const struct inode_operations shiftfs_file_inode_operations = { .listxattr = shiftfs_listxattr, .permission = shiftfs_permission, .setattr = shiftfs_setattr, + .tmpfile = shiftfs_tmpfile, }; static const struct inode_operations shiftfs_special_inode_operations = { From patchwork Tue Jun 23 17:46:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 1315400 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ubuntu.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49rtxg493jz9sSc; Wed, 24 Jun 2020 03:46:31 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1jnn08-0003fT-2W; Tue, 23 Jun 2020 17:46:28 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jnn06-0003f5-OL for kernel-team@lists.ubuntu.com; Tue, 23 Jun 2020 17:46:26 +0000 Received: from ip5f5af08c.dynamic.kabel-deutschland.de ([95.90.240.140] helo=wittgenstein.fritz.box) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jnn06-0005Bp-Aq; Tue, 23 Jun 2020 17:46:26 +0000 From: Christian Brauner To: kernel-team@lists.ubuntu.com, seth.forshee@canonical.com Subject: [SRU][FOCAL][PATCH 2/2] UBUNTU: SAUCE: shiftfs: prevent ESTALE for LOOKUP_JUMP lookups Date: Tue, 23 Jun 2020 19:46:16 +0200 Message-Id: <20200623174616.972066-2-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623174616.972066-1-christian.brauner@ubuntu.com> References: <20200623174616.972066-1-christian.brauner@ubuntu.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Evgeny Vereshchagin , Christian Kellner , stgraber@ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1872757 Users reported that creating temporary files shiftfs reports ESTALE. This can be reproduced via: import tempfile import os def test(): with tempfile.TemporaryFile() as fd: fd.write("data".encode('utf-8')) # re-open the file to get a read-only file descriptor return open(f"/proc/self/fd/{fd.fileno()}", "r") def main(): fd = test() fd.close() if __name__ == "__main__": main() a similar issue was reported here: https://github.com/systemd/systemd/issues/14861 Our revalidate methods were very opinionated about whether or not a lower dentry was valid especially when it became unlinked we simply invalidated the lower dentry which caused above bug to surface. This has led to bugs where a ESTALE was returned for e.g. temporary files that were created and directly re-opened afterwards through /proc//fd/. When a file is re-opened through /proc//fd/ LOOKUP_JUMP is set and the vfs will revalidate via d_weak_revalidate(). Since the file has been unhashed or even already gone negative we'd fail the open when we should've succeeded. Reported-by: Christian Kellner Reported-by: Evgeny Vereshchagin Cc: Seth Forshee Link: https://github.com/systemd/systemd/issues/14861 Signed-off-by: Christian Brauner Acked-by: Seth Forshee --- fs/shiftfs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/shiftfs.c b/fs/shiftfs.c index 5d88193b41db..6f40cb9272be 100644 --- a/fs/shiftfs.c +++ b/fs/shiftfs.c @@ -251,8 +251,6 @@ static int shiftfs_d_weak_revalidate(struct dentry *dentry, unsigned int flags) struct inode *loweri = d_inode(lowerd); shiftfs_copyattr(loweri, inode); - if (!inode->i_nlink) - err = 0; } return err; @@ -278,8 +276,6 @@ static int shiftfs_d_revalidate(struct dentry *dentry, unsigned int flags) struct inode *loweri = d_inode(lowerd); shiftfs_copyattr(loweri, inode); - if (!inode->i_nlink) - err = 0; } return err;