From patchwork Mon May 18 18:18:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 1292713 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 49QnLn1X7vz9sVC; Tue, 19 May 2020 04:18:09 +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 1jakKz-0004Z8-Us; Mon, 18 May 2020 18:18:05 +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 1jakKy-0004Z2-Fn for kernel-team@lists.ubuntu.com; Mon, 18 May 2020 18:18:04 +0000 Received: from ip5f5af183.dynamic.kabel-deutschland.de ([95.90.241.131] 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 1jakKy-0007p7-5q; Mon, 18 May 2020 18:18:04 +0000 From: Christian Brauner To: kernel-team@lists.ubuntu.com, seth.forshee@canonical.com Subject: [SRU][UNSTABLE/FOCAL/BIONIC][PATCH v2] UBUNTU: SAUCE: shiftfs: fix dentry revalidation Date: Mon, 18 May 2020 20:18:02 +0200 Message-Id: <20200518181802.3406919-1-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.26.2 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: James Troup Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/1879196 While fixing [1] we introduced a regression and triggered [2] whereby the underlay and overlay go out of sync because they disagree about the dcache. Such situation easily arise when the underlay is modified directly. This means the overlay needs to revalidate the dentry in the dcache to catchup with the underlay. Note, in general it's not advisable to directly modify the underlay while a shiftfs mount is on top. In some way this means we need to keep two caches in sync and it's hard enough to keep a single cache happy. But shiftfs' use-case is inherently prone to be used for exactly that. So this is something we have to navigate carefully and honestly we have no full model upstream that does the same. Overlayfs has the copy-up behavior which let's it get around most of the issues but we don't have it and ecryptfs is broken in such scenarios which we verified quite a while back. In any case, I built a kernel with this patch and re-ran all regressions that are related to this that we have so far (cf. [1], [2], and [3]). None of them were reproducible with this patch here. So we still fix the ESTALE issue but also keep underlay and overlay in sync. [1]: https://bugs.launchpad.net/bugs/1872757 [2]: https://bugs.launchpad.net/bugs/1879196 [3]: https://bugs.launchpad.net/bugs/1860041 Cc: Seth Forshee Cc: James Troup Signed-off-by: Christian Brauner --- fs/shiftfs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) base-commit: 9dd531622eff2baf657b906293745ca6dab9bb91 diff --git a/fs/shiftfs.c b/fs/shiftfs.c index 39b878a6f820..652fb67b0e0b 100644 --- a/fs/shiftfs.c +++ b/fs/shiftfs.c @@ -240,6 +240,9 @@ static int shiftfs_d_weak_revalidate(struct dentry *dentry, unsigned int flags) int err = 1; struct dentry *lowerd = dentry->d_fsdata; + 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) @@ -264,13 +267,16 @@ static int shiftfs_d_revalidate(struct dentry *dentry, unsigned int flags) if (flags & LOOKUP_RCU) return -ECHILD; + if (d_unhashed(lowerd) || + d_is_negative(lowerd) != d_is_negative(dentry)) + return 0; + 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); + d_invalidate(lowerd); return -ESTALE; } }