From patchwork Sat May 12 09:17:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10395843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D9D1960236 for ; Sat, 12 May 2018 09:16:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C910428FF8 for ; Sat, 12 May 2018 09:16:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD6652900F; Sat, 12 May 2018 09:16:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 21E7628FF8 for ; Sat, 12 May 2018 09:16:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750858AbeELJP4 (ORCPT ); Sat, 12 May 2018 05:15:56 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:32854 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750791AbeELJPz (ORCPT ); Sat, 12 May 2018 05:15:55 -0400 Received: by mail-wr0-f196.google.com with SMTP id o4-v6so7490511wrm.0; Sat, 12 May 2018 02:15:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=f/2ATY57xKh+ZkKKeenH9xqNR5/GJqANpbVrYSmgoV0=; b=WjPR3M3gvdIPuV82BLRskiakgyWL4Cj0eK9t4V2RvdDlZb4J9R6rMoal/ZjfHPwKLk BNGxGI4rOeIALvYnpEzjZYp0c/Yr9yfEMHkxCMbSSRtvH94Hl6EB1g1s4ICy13TM0eFV 9IVQN9iDGf9sjpG0Yo+ZGbQLBL69YRe/lLroMmOYuYfa3u2eVbIh1ObaUsu89LQURMux +xInt4MEyfyvRn9bTRzhXg5fKnt+AcPJHHbdidgJCHeVqoYZJGosUUsgQWrJziPciHx0 dPwpfcE7luDmWwT9cUEFde1sIYTVASPW0h15iQ/b7GBWyJWiWTNM31sXeN81yKgsm1du x4rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=f/2ATY57xKh+ZkKKeenH9xqNR5/GJqANpbVrYSmgoV0=; b=WJQ+SA0QenCr7bQHCfXWlbvy0oSWLF1zhOgJ/MX97iBDp+1HKSajMk2rcqZ5MPTLJ5 GYVN3B9k+pdsNgZaEfEl7eh3YhuHwuystEpfItFMl69MgLPo86HDoLMy/7ICYarvRDxn 6RNhHNYqcyc4Go2kmR4JwcmgQmz+0uwSKE7LTG7KlMB/v1q1/Img7uPbL5AZt9FVkZpO a26a6umJQObcyl/RMJ4JFQf/tsfXcGY6fXFDKGKLYbtr3XWiL8G2R4R7/HNZtzpBcQgc TyRjdnmEhGnsbWZHeSIgsK4T41F0xFtXdS5+w9S+9SYqs+QUdGzdxLNmDLpW6ZGc5MVE GDOA== X-Gm-Message-State: ALKqPwenMQ6i4qphOPCqxRNVr0DLy3AloL64cUq8t7mwgBCjZXoRhY7w GngvDeNXufRJ1aajDhJUXxg= X-Google-Smtp-Source: AB8JxZoXGCsf1uCQ6wkNAn+mwGOhJbbIFe4aAWzeELORCjwNtgp/Zj7sPem8JuAmKGhmbExyRTTBhA== X-Received: by 2002:adf:9814:: with SMTP id v20-v6mr1640765wrb.93.1526116553718; Sat, 12 May 2018 02:15:53 -0700 (PDT) Received: from localhost.localdomain ([94.230.83.122]) by smtp.gmail.com with ESMTPSA id x63-v6sm3566911wma.25.2018.05.12.02.15.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 12 May 2018 02:15:53 -0700 (PDT) From: Amir Goldstein To: Miklos Szeredi Cc: Al Viro , linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 1/3] ovl: use d_instantiate_new() to instantiate a new dentry Date: Sat, 12 May 2018 12:17:09 +0300 Message-Id: <1526116631-24186-2-git-send-email-amir73il@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1526116631-24186-1-git-send-email-amir73il@gmail.com> References: <1526116631-24186-1-git-send-email-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, there is a small window where ovl_obtain_alias() can race with ovl_instantiate() and create two aliases for an overlay directory inode, see Al's explanation in this post: https://marc.info/?l=linux-fsdevel&m=152599914515224&w=2 This patch fixes the race, by using the d_instantiate_new() helper. Another logic change by this patch is that if there is an inconcsistency and a new created upper inode apears to already exist in icache (hashed by the same real upper inode), we will export this error to user instead of silently not hashing the new inode. Backporting only makes sense for v4.16 where NFS export was introduced. Cc: Al Viro Cc: #v4.16 Signed-off-by: Amir Goldstein --- fs/overlayfs/dir.c | 27 +++++++++++++++++---------- fs/overlayfs/inode.c | 6 ++++++ fs/overlayfs/overlayfs.h | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 47dc980e8b33..c41825a5ed5f 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -183,23 +183,30 @@ static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry) } /* Common operations required to be done after creation of file on upper */ -static void ovl_instantiate(struct dentry *dentry, struct inode *inode, - struct dentry *newdentry, bool hardlink) +static int ovl_instantiate(struct dentry *dentry, struct inode *inode, + struct dentry *newdentry, bool hardlink) { ovl_dir_modified(dentry->d_parent, false); - ovl_copyattr(d_inode(newdentry), inode); ovl_dentry_set_upper_alias(dentry); if (!hardlink) { - ovl_inode_update(inode, newdentry); + int err; + + ovl_inode_init(inode, newdentry, NULL); + err = ovl_insert_inode_locked(inode, d_inode(newdentry)); + if (err) + return err; + + d_instantiate_new(dentry, inode); } else { WARN_ON(ovl_inode_real(inode) != d_inode(newdentry)); dput(newdentry); inc_nlink(inode); - } - d_instantiate(dentry, inode); - /* Force lookup of new upper hardlink to find its lower */ - if (hardlink) + d_instantiate(dentry, inode); + /* Force lookup of new upper hardlink to find its lower */ d_drop(dentry); + } + + return 0; } static bool ovl_type_merge(struct dentry *dentry) @@ -238,7 +245,7 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode, ovl_set_opaque(dentry, newdentry); } - ovl_instantiate(dentry, inode, newdentry, !!hardlink); + err = ovl_instantiate(dentry, inode, newdentry, !!hardlink); newdentry = NULL; out_dput: dput(newdentry); @@ -439,7 +446,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode, if (err) goto out_cleanup; } - ovl_instantiate(dentry, inode, newdentry, !!hardlink); + err = ovl_instantiate(dentry, inode, newdentry, !!hardlink); newdentry = NULL; out_dput2: dput(upper); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 7abcf96e94fc..70c966b1bb5a 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -741,6 +741,12 @@ static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry, return true; } +int ovl_insert_inode_locked(struct inode *inode, struct inode *realinode) +{ + return insert_inode_locked4(inode, (unsigned long) realinode, + ovl_inode_test, realinode); +} + struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real, bool is_upper) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index caaa47cea2aa..dd320be86600 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -343,6 +343,7 @@ int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); bool ovl_is_private_xattr(const char *name); struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev); +int ovl_insert_inode_locked(struct inode *inode, struct inode *realinode); struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real, bool is_upper); struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,