From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Hellwig Subject: [PATCH 07/10] fs: use RCU read side protection in d_validate Date: Sun, 10 Oct 2010 05:36:27 -0400 Message-ID: <20101010093721.924773504@canuck.infradead.org> References: <20101010093620.416498597@canuck.infradead.org> Cc: eparis@redhat.com, linux-fsdevel@vger.kernel.org To: viro@zeniv.linux.org.uk Return-path: Received: from canuck.infradead.org ([134.117.69.58]:40677 "EHLO canuck.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754139Ab0JJJhd (ORCPT ); Sun, 10 Oct 2010 05:37:33 -0400 Content-Disposition: inline; filename=dcache-d_validate-use-rcu Sender: linux-fsdevel-owner@vger.kernel.org List-ID: d_validate does a purely read lookup in the dentry hash, so use RCU read side locking instead of dcache_lock. Split out from a larget patch by Nick Piggin . Signed-off-by: Christoph Hellwig Index: linux-2.6/fs/dcache.c =================================================================== --- linux-2.6.orig/fs/dcache.c 2010-10-09 23:02:58.688004125 +0200 +++ linux-2.6/fs/dcache.c 2010-10-09 23:05:04.988254510 +0200 @@ -1491,33 +1491,26 @@ out: * This is used by ncpfs in its readdir implementation. * Zero is returned in the dentry is invalid. */ - -int d_validate(struct dentry *dentry, struct dentry *dparent) +int d_validate(struct dentry *dentry, struct dentry *parent) { - struct hlist_head *base; - struct hlist_node *lhp; + struct hlist_head *head = d_hash(parent, dentry->d_name.hash); + struct hlist_node *node; + struct dentry *d; /* Check whether the ptr might be valid at all.. */ if (!kmem_ptr_validate(dentry_cache, dentry)) - goto out; + return 0; + if (dentry->d_parent != parent) + return 0; - if (dentry->d_parent != dparent) - goto out; - - spin_lock(&dcache_lock); - base = d_hash(dparent, dentry->d_name.hash); - hlist_for_each(lhp,base) { - /* hlist_for_each_entry_rcu() not required for d_hash list - * as it is parsed under dcache_lock - */ - if (dentry == hlist_entry(lhp, struct dentry, d_hash)) { - __dget_locked(dentry); - spin_unlock(&dcache_lock); + rcu_read_lock(); + hlist_for_each_entry_rcu(d, node, head, d_hash) { + if (d == dentry) { + dget(dentry); return 1; } } - spin_unlock(&dcache_lock); -out: + rcu_read_unlock(); return 0; } EXPORT_SYMBOL(d_validate);