Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755226AbcKYRFP (ORCPT ); Fri, 25 Nov 2016 12:05:15 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:38497 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754740AbcKYRFJ (ORCPT ); Fri, 25 Nov 2016 12:05:09 -0500 From: Quentin Casasnovas To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Quentin Casasnovas , Al Viro Subject: [PATCH] ovl: tentative fix for broken vfs_open() on stacked overlayfs. Date: Fri, 25 Nov 2016 18:09:23 +0100 Message-Id: <20161125170923.21674-1-quentin.casasnovas@oracle.com> X-Mailer: git-send-email 2.11.0.rc2 In-Reply-To: <20161125145604.GG6842@chrystal.oracle.com> References: <20161125145604.GG6842@chrystal.oracle.com> X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2398 Lines: 82 If two overlayfs filesystems are stacked on top of each other, then we need to recurse when opening a file. This used to work and was first broken by: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay...") and fixed by: 1c8a47df36d7 ("ovl: fix open in stacked overlay") But it looks like it was re-introduced in: 2d902671ce1c ("vfs: merge .d_select_inode() into .d_real()") I know close to nothing about VFS/overlayfs so this might be completely wrong for many reasons but it fixes the following test case for me: #!/bin/bash -xeu tmpdir=$(mktemp -d) pushd ${tmpdir} mkdir -p {upper,lower,work} echo -n 'rocks' > lower/ksplice mount -t overlay level_zero upper -o lowerdir=lower,upperdir=upper,workdir=work cat upper/ksplice tmpdir2=$(mktemp -d) pushd ${tmpdir2} mkdir -p {upper,work} mount -t overlay level_one upper -o lowerdir=${tmpdir}/upper,upperdir=upper,workdir=work ls -l upper/ksplice cat upper/ksplice For sanity checking, I've run the test-suite mentionned in Documentation/filesystems/overlayfs.txt: git://git.infradead.org/users/dhowells/unionmount-testsuite.git Though with and without this patch it returned zero so I am assuming it does not contain any tests with stacked overlayfs. Fixes: 2d902671ce1c ("vfs: merge .d_select_inode() into .d_real()") Cc: Al Viro Cc: Miklos Szeredi Signed-off-by: Quentin Casasnovas --- fs/overlayfs/super.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index edd46a0e951d..ae0b36474a9a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -321,16 +321,22 @@ static struct dentry *ovl_d_real(struct dentry *dentry, } real = ovl_dentry_upper(dentry); - if (real && (!inode || inode == d_inode(real))) - return real; + if (real && inode && inode == d_inode(real)) + return real; + + if (real && !inode && d_inode(real)) + return d_real(real, d_inode(real), open_flags); real = ovl_dentry_lower(dentry); if (!real) goto bug; - if (!inode || inode == d_inode(real)) + if (inode && inode == d_inode(real)) return real; + if (!inode && d_inode(real)) + return d_real(real, d_inode(real), open_flags); + /* Handle recursion */ return d_real(real, inode, open_flags); bug: -- 2.11.0.rc2