Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3288223imm; Sun, 29 Jul 2018 15:06:59 -0700 (PDT) X-Google-Smtp-Source: AAOMgpflkSYsoF+yhu/EJ9jHyh9Tq+yA9nMdaWn2RkFtEPdOZIEBS+ghiYwTsgA5oPxc3NwBQ3xj X-Received: by 2002:a65:5144:: with SMTP id g4-v6mr13887825pgq.21.1532902019172; Sun, 29 Jul 2018 15:06:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532902019; cv=none; d=google.com; s=arc-20160816; b=QMAF0iJVy+wMKaF5o8JQFdfowAeTVqscxB6lwDFM0EGwuQABPJt4PRk4yX9iIIesHX fzL7utA0S/i8Q/5BnGs2Bda8O5CWsT8VHsBjVeOWZ7WtR6kcCgaVvOWEkVEvRp+aJjjT pFqJjREkKCk/QwQDrcPzXjA3ehyI2eVHQ1yao2asMvn8xY4BUCDIQxFlzpkEKYLWrYyS ZGIr/X5O/YZlO4KUPLmMtu2Gn/Dj4hsIvL2CGP8vxikiRpACEJeO861Tpg+vMBsbKN9g nSWODtxtsfJk0hujL4RYgYGyQYejR+jCloWTpVjysirQVc1DzAhCbL9opg0kZJYnGyZb 4d7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=E1sR4Vaen0LPesMLo6u6jmrnnTqLKFbWVnluXPF8K40=; b=QPpcfA8hfwvJstcgOXajO+73MakcmTwvgJWfEE/jyU7Y8ILC8QTUxLOg6XLzNyLvxx FD9d4ue+6xwipLhgyj2ZY3UNSt+mAv90wk0CFADoE/PoYSuJeLV7Y6eqh3qHmVnM+Vfu gzphRw3C/ZrCuN7UWaSzPthClKBQ6LCOwLpRvIjoZPZripnXQHtDA0pdghbVZdTWSHUK iQfUXWNEZ2pcQgaF4dHQeL8bpZyTcngKmr0bFkayWCHQOV0+JDIlTZ64IZlJzL0WOO9y JrriZOFZxc0DZ+NaGbWGb06quaeYRaIJPYH7cfnSvDfIOj43IB+5UoY3bwt8cxIacdzB d1ag== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g10-v6si9823803pfd.86.2018.07.29.15.06.45; Sun, 29 Jul 2018 15:06:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732200AbeG2XhI (ORCPT + 99 others); Sun, 29 Jul 2018 19:37:08 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:51606 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729011AbeG2Xg5 (ORCPT ); Sun, 29 Jul 2018 19:36:57 -0400 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.87 #1 (Red Hat Linux)) id 1fjto6-0003W4-R4; Sun, 29 Jul 2018 22:04:54 +0000 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: Linus Torvalds , linux-kernel@vger.kernel.org, Miklos Szeredi , Miklos Szeredi Subject: [PATCH 10/16] kill d_instantiate_no_diralias() Date: Sun, 29 Jul 2018 23:04:47 +0100 Message-Id: <20180729220453.13431-10-viro@ZenIV.linux.org.uk> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180729220453.13431-1-viro@ZenIV.linux.org.uk> References: <20180729220317.GB30522@ZenIV.linux.org.uk> <20180729220453.13431-1-viro@ZenIV.linux.org.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Al Viro The only user is fuse_create_new_entry(), and there it's used to mitigate the same mkdir/open-by-handle race as in nfs_mkdir(). The same solution applies - unhash the mkdir argument, then call d_splice_alias() and if that returns a reference to preexisting alias, dput() and report success. ->mkdir() argument left unhashed negative with the preexisting alias moved in the right place is just fine from the ->mkdir() callers point of view. Cc: Miklos Szeredi Signed-off-by: Al Viro --- fs/dcache.c | 27 --------------------------- fs/fuse/dir.c | 15 +++++++++++---- include/linux/dcache.h | 1 - 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 0e8e5de3c48a..a7d9e7a4c283 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1899,33 +1899,6 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode) } EXPORT_SYMBOL(d_instantiate_new); -/** - * d_instantiate_no_diralias - instantiate a non-aliased dentry - * @entry: dentry to complete - * @inode: inode to attach to this dentry - * - * Fill in inode information in the entry. If a directory alias is found, then - * return an error (and drop inode). Together with d_materialise_unique() this - * guarantees that a directory inode may never have more than one alias. - */ -int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) -{ - BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); - - security_d_instantiate(entry, inode); - spin_lock(&inode->i_lock); - if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) { - spin_unlock(&inode->i_lock); - iput(inode); - return -EBUSY; - } - __d_instantiate(entry, inode); - spin_unlock(&inode->i_lock); - - return 0; -} -EXPORT_SYMBOL(d_instantiate_no_diralias); - struct dentry *d_make_root(struct inode *root_inode) { struct dentry *res = NULL; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 56231b31f806..4bbae6ac75c3 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -539,6 +539,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, { struct fuse_entry_out outarg; struct inode *inode; + struct dentry *d; int err; struct fuse_forget_link *forget; @@ -570,11 +571,17 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, } kfree(forget); - err = d_instantiate_no_diralias(entry, inode); - if (err) - return err; + d_drop(entry); + d = d_splice_alias(inode, entry); + if (IS_ERR(d)) + return PTR_ERR(d); - fuse_change_entry_timeout(entry, &outarg); + if (d) { + fuse_change_entry_timeout(d, &outarg); + dput(d); + } else { + fuse_change_entry_timeout(entry, &outarg); + } fuse_invalidate_attr(dir); return 0; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 66c6e17e61e5..0b83629a3d8f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -227,7 +227,6 @@ extern void d_instantiate(struct dentry *, struct inode *); extern void d_instantiate_new(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *); -extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); extern void d_delete(struct dentry *); -- 2.11.0