From patchwork Fri Jan 19 10:39:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 10174983 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 6EE8860392 for ; Fri, 19 Jan 2018 10:40:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E3372861C for ; Fri, 19 Jan 2018 10:40:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 515D62864A; Fri, 19 Jan 2018 10:40:04 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 385E128630 for ; Fri, 19 Jan 2018 10:40:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754840AbeASKkC (ORCPT ); Fri, 19 Jan 2018 05:40:02 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:33259 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751212AbeASKkA (ORCPT ); Fri, 19 Jan 2018 05:40:00 -0500 Received: by mail-wm0-f67.google.com with SMTP id x4so6634854wmc.0 for ; Fri, 19 Jan 2018 02:40:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=szeredi.hu; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=D+yFpF93UbRE9gG27lYiCZYrCXn3w9CCfwnVIavntQ4=; b=YxH6E4LOwz6D33vjYzUu86lCwZPamWQBOdJtK3ZDDUy1bVl4mqlHOlxDvcYUmJktn0 gCdhngQ3zK7VYvlMcdcakwFIVI5n5z8j5YRNAKGpj5Ss4IfamHeOlmXrIYse3YAHEkaJ PgVV5ZaUnAIfErOLshDdhKgxqt8OpOYSp56Xo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=D+yFpF93UbRE9gG27lYiCZYrCXn3w9CCfwnVIavntQ4=; b=TJBzf/fMefGbJGx3Qmyup9un4cX2pIouDhN9y7ueEtIhUSlg9LWYPagf3pB0Y6rIPW xUMSPjZM15DUhfmIphmY9wPMXP/nuaaokPj7XPdLQCM/icfdqdnKDT5nqJF5MPl4Mc8P 26pKU1RLwzAE+GFI2jK2Yw9cgNMNWRDSS/m1RTmyN6+skhF2fpQAZO8zZlPVM+GyRUKd +e2YDAy7+HM5zw8S9u35Ul4Kd2UEP2QufmnJgOAsIUXPuB3kCPMP0kx7LIlhIevLklcv 4jZJek8KKRX0E738Mbb3y6oy1RoN485NCLNk8DuCk7YGxMdDxbrpL0KauGCrln6PtOf1 D0tQ== X-Gm-Message-State: AKwxytd/miPgbHeYfVH2Cm4myRhciESWz4dGyYC2CXNOUpO07KDOr05G aoAo/kFZ9U7hCVrDsuBanOrGGw== X-Google-Smtp-Source: ACJfBos2fr5MHMrPeSRsKnRZW7LVbD0mB+SB6HAuBzoHgzrj7yE4/ISDDElkMk8YeQN4c3pQY6t37g== X-Received: by 10.28.0.207 with SMTP id 198mr7494636wma.115.1516358399323; Fri, 19 Jan 2018 02:39:59 -0800 (PST) Received: from veci.piliscsaba.redhat.com (catv-176-63-54-97.catv.broadband.hu. [176.63.54.97]) by smtp.gmail.com with ESMTPSA id 2sm1169619wmk.28.2018.01.19.02.39.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 19 Jan 2018 02:39:58 -0800 (PST) Date: Fri, 19 Jan 2018 11:39:52 +0100 From: Miklos Szeredi To: Amir Goldstein Cc: overlayfs , linux-fsdevel , Al Viro Subject: Re: [PATCH v2 03/17] ovl: decode pure upper file handles Message-ID: <20180119103952.GA24104@veci.piliscsaba.redhat.com> References: <1515086449-26563-1-git-send-email-amir73il@gmail.com> <1515086449-26563-4-git-send-email-amir73il@gmail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.1 (2017-09-22) 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 On Fri, Jan 19, 2018 at 02:23:35AM +0200, Amir Goldstein wrote: > > How is this for an option? [...] > > +struct dentry *d_obtain_alias_fsdata(struct inode *inode, void **fsdata) > > +{ > > + return __d_obtain_alias(inode, 1, fsdata); > > } > > EXPORT_SYMBOL(d_obtain_alias); It would work, but I like this interface better: +extern struct dentry * d_alloc_anon(struct super_block *); +extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *); And full patch: diff --git a/fs/dcache.c b/fs/dcache.c index b5d5ea984ac4..15dc32178813 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1699,9 +1699,15 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) } EXPORT_SYMBOL(d_alloc); +struct dentry *d_alloc_anon(struct super_block *sb) +{ + return __d_alloc(sb, NULL); +} +EXPORT_SYMBOL(d_alloc_anon); + struct dentry *d_alloc_cursor(struct dentry * parent) { - struct dentry *dentry = __d_alloc(parent->d_sb, NULL); + struct dentry *dentry = d_alloc_anon(parent->d_sb); if (dentry) { dentry->d_flags |= DCACHE_RCUACCESS | DCACHE_DENTRY_CURSOR; dentry->d_parent = dget(parent); @@ -1887,7 +1893,7 @@ struct dentry *d_make_root(struct inode *root_inode) struct dentry *res = NULL; if (root_inode) { - res = __d_alloc(root_inode->i_sb, NULL); + res = d_alloc_anon(root_inode->i_sb); if (res) d_instantiate(res, root_inode); else @@ -1926,33 +1932,18 @@ struct dentry *d_find_any_alias(struct inode *inode) } EXPORT_SYMBOL(d_find_any_alias); -static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) +static struct dentry *__d_instantiate_anon(struct dentry *dentry, + struct inode *inode, + bool disconnected) { - struct dentry *tmp; struct dentry *res; - unsigned add_flags; - - if (!inode) - return ERR_PTR(-ESTALE); - if (IS_ERR(inode)) - return ERR_CAST(inode); - - res = d_find_any_alias(inode); - if (res) - goto out_iput; - tmp = __d_alloc(inode->i_sb, NULL); - if (!tmp) { - res = ERR_PTR(-ENOMEM); - goto out_iput; - } - - security_d_instantiate(tmp, inode); + security_d_instantiate(dentry, inode); spin_lock(&inode->i_lock); res = __d_find_any_alias(inode); if (res) { spin_unlock(&inode->i_lock); - dput(tmp); + dput(dentry); goto out_iput; } @@ -1962,22 +1953,56 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) if (disconnected) add_flags |= DCACHE_DISCONNECTED; - spin_lock(&tmp->d_lock); - __d_set_inode_and_type(tmp, inode, add_flags); - hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry); - hlist_bl_lock(&tmp->d_sb->s_anon); - hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); - hlist_bl_unlock(&tmp->d_sb->s_anon); - spin_unlock(&tmp->d_lock); + spin_lock(&dentry->d_lock); + __d_set_inode_and_type(dentry, inode, add_flags); + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); + hlist_bl_lock(&dentry->d_sb->s_anon); + hlist_bl_add_head(&dentry->d_hash, &dentry->d_sb->s_anon); + hlist_bl_unlock(&dentry->d_sb->s_anon); + spin_unlock(&dentry->d_lock); spin_unlock(&inode->i_lock); - return tmp; + return dentry; out_iput: iput(inode); return res; } +struct dentry *d_instantiate_anon(struct dentry *dentry, struct inode *inode) +{ + return __d_instantiate_anon(dentry, inode, true); +} +EXPORT_SYMBOL(d_instantiate_anon); + +static struct dentry *__d_obtain_alias(struct inode *inode, bool disconnected) +{ + struct dentry *tmp; + struct dentry *res; + unsigned add_flags; + + if (!inode) + return ERR_PTR(-ESTALE); + if (IS_ERR(inode)) + return ERR_CAST(inode); + + res = d_find_any_alias(inode); + if (res) + goto out_iput; + + tmp = d_alloc_anon(inode->i_sb); + if (!tmp) { + res = ERR_PTR(-ENOMEM); + goto out_iput; + } + + return __d_instantiate_anon(tmp, inode, disconnected); + +out_iput: + iput(inode); + return res; +} + /** * d_obtain_alias - find or allocate a DISCONNECTED dentry for a given inode * @inode: inode to allocate the dentry for @@ -1998,7 +2023,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected) */ struct dentry *d_obtain_alias(struct inode *inode) { - return __d_obtain_alias(inode, 1); + return __d_obtain_alias(inode, true); } EXPORT_SYMBOL(d_obtain_alias); @@ -2019,7 +2044,7 @@ EXPORT_SYMBOL(d_obtain_alias); */ struct dentry *d_obtain_root(struct inode *inode) { - return __d_obtain_alias(inode, 0); + return __d_obtain_alias(inode, false); } EXPORT_SYMBOL(d_obtain_root); diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index 25461781c103..7477f28cb99b 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -184,28 +184,32 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb, return ERR_CAST(inode); } - dentry = d_obtain_alias(inode); - if (IS_ERR(dentry) || dentry->d_fsdata) - return dentry; - - oe = ovl_alloc_entry(!!lower); - if (!oe) { - dput(dentry); - return ERR_PTR(-ENOMEM); - } + if (index) + ovl_set_flag(OVL_INDEX, inode); - dentry->d_fsdata = oe; - if (upper_alias) - ovl_dentry_set_upper_alias(dentry); - if (lower) { - oe->lowerstack->dentry = dget(lower); - oe->lowerstack->layer = lowerpath->layer; + dentry = d_find_any_alias(inode); + if (!dentry) { + dentry = d_alloc_anon(inode->i_sb); + if (!dentry) + goto nomem; + oe = ovl_alloc_entry(lower ? 1 : 0); + if (!oe) + goto nomem; + if (lower) { + oe->lowerstack->dentry = dget(lower); + oe->lowerstack->layer = lowerpath->layer; + } + dentry->d_fsdata = oe; + if (upper_alias) + ovl_dentry_set_upper_alias(dentry); } - if (index) - ovl_set_flag(OVL_INDEX, inode); + return d_instantiate_anon(dentry, inode); - return dentry; +nomem: + iput(inode); + dput(dentry); + return ERR_PTR(-ENOMEM); } /* Get the upper or lower dentry in stach whose on layer @idx */ diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 65cd8ab60b7a..82a99d366aec 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -227,6 +227,7 @@ extern seqlock_t rename_lock; */ extern void d_instantiate(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); @@ -235,6 +236,7 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op /* allocate/de-allocate */ extern struct dentry * d_alloc(struct dentry *, const struct qstr *); +extern struct dentry * d_alloc_anon(struct super_block *); extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *, wait_queue_head_t *);