From patchwork Mon Feb 22 14:28:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vivek Goyal X-Patchwork-Id: 8377611 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3C8B89F314 for ; Mon, 22 Feb 2016 14:28:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 49B5A204D8 for ; Mon, 22 Feb 2016 14:28:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1159C2045B for ; Mon, 22 Feb 2016 14:28:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932314AbcBVO2h (ORCPT ); Mon, 22 Feb 2016 09:28:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54788 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932289AbcBVO2f (ORCPT ); Mon, 22 Feb 2016 09:28:35 -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 580C464394; Mon, 22 Feb 2016 14:28:35 +0000 (UTC) Received: from horse.redhat.com (dhcp-25-16.bos.redhat.com [10.18.25.16]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u1MESYeK015423; Mon, 22 Feb 2016 09:28:34 -0500 Received: by horse.redhat.com (Postfix, from userid 10451) id 65D402056E1; Mon, 22 Feb 2016 09:28:34 -0500 (EST) Date: Mon, 22 Feb 2016 09:28:34 -0500 From: Vivek Goyal To: linux-unionfs@vger.kernel.org Cc: linux-fsdevel , miklos@szeredi.hu, David Howells , Dave Chinner Subject: [PATCH] overlayfs: Ensure upper filesystem supports d_type Message-ID: <20160222142834.GA18393@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 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 22 Feb 2016 14:28:35 +0000 (UTC) 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 During mount, make sure upper fs supports d_type otherwise error out. In some instances xfs has been created with ftype=0 and there if a file on lower fs is removed, overlay leaves a whiteout in upper fs but that whiteout does not get filtered out and is visible to overlayfs users. And reason it does not get filtered out because upper filesystem does not report file type of whiteout as DT_CHR during iterate_dir(). So it seems to be a requirement that upper filesystem support d_type for overlayfs to work properly. Do this check during mount and fail if d_type is not supported. Suggested-by: Dave Chinner Signed-off-by: Vivek Goyal --- fs/overlayfs/overlayfs.h | 1 + fs/overlayfs/readdir.c | 37 +++++++++++++++++++++++++++++++++++++ fs/overlayfs/super.c | 15 +++++++++++++++ 3 files changed, 53 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: rhvgoyal-linux/fs/overlayfs/readdir.c =================================================================== --- rhvgoyal-linux.orig/fs/overlayfs/readdir.c 2016-02-19 16:10:09.440000000 +0000 +++ rhvgoyal-linux/fs/overlayfs/readdir.c 2016-02-22 14:09:30.745000000 +0000 @@ -43,6 +43,7 @@ struct ovl_readdir_data { struct ovl_cache_entry *first_maybe_whiteout; int count; int err; + bool d_type_supported; }; struct ovl_dir_file { @@ -577,3 +578,39 @@ void ovl_cleanup_whiteouts(struct dentry } inode_unlock(upper->d_inode); } + +static int ovl_check_d_type(struct dir_context *ctx, const char *name, + int namelen, loff_t offset, u64 ino, + unsigned int d_type) +{ + struct ovl_readdir_data *rdd = + container_of(ctx, struct ovl_readdir_data, ctx); + + /* Even if d_type is not supported, DT_DIR is returned for . and .. */ + if (!strncmp(name, ".", namelen) || !strncmp(name, "..", namelen)) + return 0; + + if (d_type != DT_UNKNOWN) + rdd->d_type_supported = true; + + return 0; +} + +/* + * Returns 1 if d_type is supported, 0 not supported/unknown. Negative values + * if error is encountered. + */ +int ovl_check_d_type_supported(struct path *realpath) +{ + int err; + struct ovl_readdir_data rdd = { + .ctx.actor = ovl_check_d_type, + .d_type_supported = false, + }; + + err = ovl_dir_read(realpath, &rdd); + if (err) + return err; + + return rdd.d_type_supported; +} Index: rhvgoyal-linux/fs/overlayfs/overlayfs.h =================================================================== --- rhvgoyal-linux.orig/fs/overlayfs/overlayfs.h 2016-02-19 16:10:09.440000000 +0000 +++ rhvgoyal-linux/fs/overlayfs/overlayfs.h 2016-02-22 14:09:30.746000000 +0000 @@ -166,6 +166,7 @@ extern const struct file_operations ovl_ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list); void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list); void ovl_cache_free(struct list_head *list); +int ovl_check_d_type_supported(struct path *realpath); /* inode.c */ int ovl_setattr(struct dentry *dentry, struct iattr *attr); Index: rhvgoyal-linux/fs/overlayfs/super.c =================================================================== --- rhvgoyal-linux.orig/fs/overlayfs/super.c 2016-02-19 16:10:09.440000000 +0000 +++ rhvgoyal-linux/fs/overlayfs/super.c 2016-02-22 14:09:30.746000000 +0000 @@ -1025,6 +1025,21 @@ static int ovl_fill_super(struct super_b sb->s_flags |= MS_RDONLY; ufs->workdir = NULL; } + + /* + * Upper should support d_type, else whiteouts are visible. + * Given workdir and upper are on same fs, we can do + * iterate_dir() on workdir. + */ + err = ovl_check_d_type_supported(&workpath); + if (err < 0) + goto out_put_workdir; + + if (!err) { + pr_err("overlayfs: upper fs needs to support d_type.\n"); + err = -EINVAL; + goto out_put_workdir; + } } err = -ENOMEM;