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: NeilBrown <neilb@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7e08e9a894
commit
8016ab9ebb
|
@ -381,6 +381,10 @@ void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to reuse unhashed or invalidated dentries.
|
* 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)
|
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);
|
spin_lock(&inode->i_lock);
|
||||||
hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
|
hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
|
||||||
LASSERT(alias != dentry);
|
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)
|
||||||
if (alias->d_parent == dentry->d_parent &&
|
continue;
|
||||||
alias->d_name.hash == dentry->d_name.hash &&
|
if (alias->d_name.hash != dentry->d_name.hash)
|
||||||
alias->d_name.len == dentry->d_name.len &&
|
continue;
|
||||||
|
if (alias->d_name.len != dentry->d_name.len ||
|
||||||
memcmp(alias->d_name.name, dentry->d_name.name,
|
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);
|
dget_dlock(alias);
|
||||||
spin_unlock(&alias->d_lock);
|
spin_unlock(&alias->d_lock);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
spin_unlock(&alias->d_lock);
|
|
||||||
}
|
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue