@@ -320,81 +320,37 @@ void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2)
}
/*
- * try to reuse three types of dentry:
- * 1. unhashed alias, this one is unhashed by d_invalidate (but it may be valid
- * by concurrent .revalidate).
- * 2. INVALID alias (common case for no valid ldlm lock held, but this flag may
- * be cleared by others calling d_lustre_revalidate).
- * 3. DISCONNECTED alias.
- */
-static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry)
-{
- struct dentry *alias, *discon_alias, *invalid_alias;
-
- if (hlist_empty(&inode->i_dentry))
- return NULL;
-
- discon_alias = invalid_alias = NULL;
-
- ll_lock_dcache(inode);
- hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
- LASSERT(alias != dentry);
-
- spin_lock(&alias->d_lock);
- if (alias->d_flags & DCACHE_DISCONNECTED)
- /* LASSERT(last_discon == NULL); LU-405, bz 20055 */
- discon_alias = alias;
- else if (alias->d_parent == dentry->d_parent &&
- alias->d_name.hash == dentry->d_name.hash &&
- alias->d_name.len == dentry->d_name.len &&
- memcmp(alias->d_name.name, dentry->d_name.name,
- dentry->d_name.len) == 0)
- invalid_alias = alias;
- spin_unlock(&alias->d_lock);
-
- if (invalid_alias)
- break;
- }
- alias = invalid_alias ?: discon_alias ?: NULL;
- if (alias) {
- spin_lock(&alias->d_lock);
- dget_dlock(alias);
- spin_unlock(&alias->d_lock);
- }
- ll_unlock_dcache(inode);
-
- return alias;
-}
-
-/*
* Similar to d_splice_alias(), but lustre treats invalid alias
* similar to DCACHE_DISCONNECTED, and tries to use it anyway.
*/
struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de)
{
- struct dentry *new;
+ struct dentry *alias = NULL;
int rc;
if (inode) {
- new = ll_find_alias(inode, de);
- if (new) {
- rc = ll_d_init(new);
- if (rc < 0) {
- dput(new);
- return ERR_PTR(rc);
- }
- d_move(new, de);
+ alias = d_exact_alias(de, inode);
+ if (alias)
+ iput(inode);
+ }
+
+ if (!alias) {
+ rc = ll_d_init(de);
+ if (rc < 0) {
iput(inode);
- CDEBUG(D_DENTRY,
- "Reuse dentry %p inode %p refc %d flags %#x\n",
- new, d_inode(new), d_count(new), new->d_flags);
- return new;
+ return ERR_PTR(rc);
}
+ alias = d_splice_alias(inode, de);
+ if (IS_ERR(alias))
+ return alias;
+ }
+
+ if (alias) {
+ CDEBUG(D_DENTRY,
+ "Reuse dentry %p inode %p refc %d flags %#x\n",
+ alias, d_inode(alias), d_count(alias), alias->d_flags);
+ return alias;
}
- rc = ll_d_init(de);
- if (rc < 0)
- return ERR_PTR(rc);
- d_add(de, inode);
CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n",
de, d_inode(de), d_count(de), de->d_flags);
return de;
@@ -1576,6 +1576,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp,
alias = ll_splice_alias(inode,
*dentryp);
if (IS_ERR(alias)) {
+ entry->se_inode = NULL;
ll_sai_unplug(sai, entry);
return PTR_ERR(alias);
}