From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vinson Lee Subject: [PATCH] fold d_kill() and d_free() Date: Wed, 20 May 2015 17:31:59 -0700 Message-ID: <1432168319-30261-2-git-send-email-vlee@twopensource.com> References: <20150518174424.GA802@kroah.com> <1432168319-30261-1-git-send-email-vlee@twopensource.com> Cc: stable@vger.kernel.org, linux-fsdevel@vger.kernel.org, Vinson Lee To: Greg KH , Cong Wang , viro@zeniv.linux.org.uk Return-path: Received: from mail-pd0-f169.google.com ([209.85.192.169]:35875 "EHLO mail-pd0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753554AbbEUAcM (ORCPT ); Wed, 20 May 2015 20:32:12 -0400 Received: by pdfh10 with SMTP id h10so87556058pdf.3 for ; Wed, 20 May 2015 17:32:11 -0700 (PDT) In-Reply-To: <1432168319-30261-1-git-send-email-vlee@twopensource.com> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: From: Al Viro commit 03b3b889e79cdb6b806fc0ba9be0d71c186bbfaa upstream. Signed-off-by: Al Viro [ vlee: Backported to 3.14. Adjusted context. ] Signed-off-by: Vinson Lee --- fs/dcache.c | 77 +++++++++++++++++++------------------------------------------ 1 file changed, 24 insertions(+), 53 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index a9231c8..8486607 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -244,24 +244,6 @@ static void __d_free(struct rcu_head *head) kmem_cache_free(dentry_cache, dentry); } -/* - * no locks, please. - */ -static void d_free(struct dentry *dentry) -{ - WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias)); - BUG_ON((int)dentry->d_lockref.count > 0); - this_cpu_dec(nr_dentry); - if (dentry->d_op && dentry->d_op->d_release) - dentry->d_op->d_release(dentry); - - /* if dentry was never visible to RCU, immediate free is OK */ - if (!(dentry->d_flags & DCACHE_RCUACCESS)) - __d_free(&dentry->d_u.d_rcu); - else - call_rcu(&dentry->d_u.d_rcu, __d_free); -} - /** * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups * @dentry: the target dentry @@ -419,40 +401,6 @@ static void dentry_lru_del(struct dentry *dentry) } /** - * d_kill - kill dentry and return parent - * @dentry: dentry to kill - * @parent: parent dentry - * - * The dentry must already be unhashed and removed from the LRU. - * - * If this is the root of the dentry tree, return NULL. - * - * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by - * d_kill. - */ -static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) - __releases(dentry->d_lock) - __releases(parent->d_lock) - __releases(dentry->d_inode->i_lock) -{ - __list_del_entry(&dentry->d_child); - /* - * Inform d_walk() that we are no longer attached to the - * dentry tree - */ - dentry->d_flags |= DCACHE_DENTRY_KILLED; - if (parent) - spin_unlock(&parent->d_lock); - dentry_iput(dentry); - /* - * dentry_iput drops the locks, at which point nobody (except - * transient RCU lookups) can reach this dentry. - */ - d_free(dentry); - return parent; -} - -/** * d_drop - drop a dentry * @dentry: dentry to drop * @@ -545,7 +493,30 @@ relock: dentry_lru_del(dentry); /* if it was on the hash then remove it */ __d_drop(dentry); - return d_kill(dentry, parent); + list_del(&dentry->d_child); + /* + * Inform d_walk() that we are no longer attached to the + * dentry tree + */ + dentry->d_flags |= DCACHE_DENTRY_KILLED; + if (parent) + spin_unlock(&parent->d_lock); + dentry_iput(dentry); + /* + * dentry_iput drops the locks, at which point nobody (except + * transient RCU lookups) can reach this dentry. + */ + BUG_ON((int)dentry->d_lockref.count > 0); + this_cpu_dec(nr_dentry); + if (dentry->d_op && dentry->d_op->d_release) + dentry->d_op->d_release(dentry); + + /* if dentry was never visible to RCU, immediate free is OK */ + if (!(dentry->d_flags & DCACHE_RCUACCESS)) + __d_free(&dentry->d_u.d_rcu); + else + call_rcu(&dentry->d_u.d_rcu, __d_free); + return parent; } /* -- 2.1.0