Commit 8016ab9e authored by NeilBrown's avatar NeilBrown Committed by Greg Kroah-Hartman
Browse files

staging: lustre: llite: refine ll_find_alias based on d_exact_alias



The task of ll_find_alias() is now very similar to d_exact_alias().
We cannot use that function directly, but we can copy much of
the structure so that the similarities and differences are more
obvious.
Examining d_exact_alias() shows that the d_lock spinlock does not
need to be held in ll_find_alias as much as it currently is.

Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7e08e9a8
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -381,6 +381,10 @@ void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2)

/*
 * Try to reuse unhashed or invalidated dentries.
 * This is very similar to d_exact_alias(), and any changes in one should be
 * considered for inclusion in the other.  The differences are that we don't
 * need an unhashed alias, and we don't want d_compare to be used for
 * comparison.
 */
static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry)
{
@@ -392,20 +396,26 @@ static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry)
	spin_lock(&inode->i_lock);
	hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
		LASSERT(alias != dentry);
		/*
		 * Don't need alias->d_lock here, because aliases with
		 * d_parent == entry->d_parent are not subject to name or
		 * parent changes, because the parent inode i_mutex is held.
		 */

		spin_lock(&alias->d_lock);
		if (alias->d_parent == dentry->d_parent	     &&
		    alias->d_name.hash == dentry->d_name.hash       &&
		    alias->d_name.len == dentry->d_name.len	 &&
		if (alias->d_parent != dentry->d_parent)
			continue;
		if (alias->d_name.hash != dentry->d_name.hash)
			continue;
		if (alias->d_name.len != dentry->d_name.len ||
		    memcmp(alias->d_name.name, dentry->d_name.name,
			   dentry->d_name.len) == 0) {
			   dentry->d_name.len) != 0)
			continue;
		spin_lock(&alias->d_lock);
		dget_dlock(alias);
		spin_unlock(&alias->d_lock);
		spin_unlock(&inode->i_lock);
		return alias;
	}
		spin_unlock(&alias->d_lock);
	}
	spin_unlock(&inode->i_lock);

	return NULL;