From patchwork Mon Jan 11 13:55:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 8004051 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4C494BEEE5 for ; Mon, 11 Jan 2016 13:55:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 68873202D1 for ; Mon, 11 Jan 2016 13:55:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6A34920165 for ; Mon, 11 Jan 2016 13:55:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932829AbcAKNzW (ORCPT ); Mon, 11 Jan 2016 08:55:22 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52560 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932984AbcAKNzU (ORCPT ); Mon, 11 Jan 2016 08:55:20 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id EBEA5C0BF2A5; Mon, 11 Jan 2016 13:55:19 +0000 (UTC) Received: from horse.redhat.com (vpn-48-211.rdu2.redhat.com [10.10.48.211]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u0BDtIjY014349; Mon, 11 Jan 2016 08:55:19 -0500 Received: by horse.redhat.com (Postfix, from userid 10451) id 88B44206E1A; Mon, 11 Jan 2016 08:55:18 -0500 (EST) Date: Mon, 11 Jan 2016 08:55:18 -0500 From: Vivek Goyal To: linux-unionfs@vger.kernel.org Cc: miklos@szeredi.hu, David Howells , linux-fsdevel@vger.kernel.org Subject: [PATCH] ovl: Do not leave whiteout during unlink/rmdir if parent does not have merge property Message-ID: <20160111135518.GB21233@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP I am trying to fix following bug https://bugzilla.kernel.org/show_bug.cgi?id=109611 Do following. $ mkdir upper lower work merged upper/dir/ $ touch lower/test $ sudo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work merged $ mv merged/test merged/dir/ $ rm merged/dir/test $ ls -l merged/dir/ /usr/bin/ls: cannot access merged/dir/test: No such file or directory total 0 c????????? ? ? ? ? ? test Basic problem seems to be that once a file has been unlinked, a whiteout has been left behind and doing ls makes that whiteout visible. whiteout is visible because parent dir is of not type MERGE, hence od->is_real is set during ovl_dir_open(). And that means ovl_iterate() passes on iterate handling directly to underlying fs. Underlying fs does not know/filter whiteouts so it becomes visible to user. Why did we leave a whiteout to begin with when we should not have. ovl_do_remove() checks for OVL_TYPE_PURE_UPPER() and does not leave whiteout if file is pure upper. In this case file is not found to be pure upper hence whiteout is left. So why file was not PURE_UPPER in this case? I think because dentry is still carrying some leftover state which was valid before rename. For example, od->numlower was set to 1 as it was a lower file. After rename, this state is not valid anymore as there is no such file in lower. Also during rename, we first copied up the file and set oe->opaque=1. That means this file will never be characterized as PURE. And hence we leave a whiteout when we should not have to. So I have put a temporary hack to check if parent is type MERGE or not. If it is not then looks like we might not have to leave a whiteout. This seems like a hack fix to me. Real problem seems to be that during rename some ovl_entry state got stale. Not sure how to take care of that. So sending this hack fix out and hoping somebody can suggest what's a better way to fix it. Signed-off-by: Vivek Goyal --- fs/overlayfs/dir.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 692ceda..a2fd06b 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -637,7 +637,7 @@ static inline int ovl_check_sticky(struct dentry *dentry) static int ovl_do_remove(struct dentry *dentry, bool is_dir) { - enum ovl_path_type type; + enum ovl_path_type type, parent_type; int err; err = ovl_check_sticky(dentry); @@ -653,7 +653,16 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) goto out_drop_write; type = ovl_path_type(dentry); - if (OVL_TYPE_PURE_UPPER(type)) { + parent_type = ovl_path_type(dentry->d_parent); + + /* + * After rename if a file is removed, it could have out of sync + * numlower and forced "opaque" set which means file will not be + * categorized as pure upper. So if parent is not type merge, then + * it is not present in any of the lower so there should not be + * any need to leave whiteout. + */ + if (OVL_TYPE_PURE_UPPER(type) || !OVL_TYPE_MERGE(parent_type)) { err = ovl_remove_upper(dentry, is_dir); } else { const struct cred *old_cred;