- struct list_head *tmp;
- struct dentry *dentry;
- struct dentry *last_discon = NULL;
-
- cfs_spin_lock(&ll_lookup_lock);
- spin_lock(&dcache_lock);
- list_for_each(tmp, &inode->i_dentry) {
- dentry = list_entry(tmp, struct dentry, d_alias);
-
- /* We are called here with 'de' already on the aliases list. */
- if (unlikely(dentry == de)) {
- CERROR("whoops\n");
- continue;
- }
-
- if (dentry->d_flags & DCACHE_DISCONNECTED) {
- /* LASSERT(last_discon == NULL); LU-405, bz 20055 */
- last_discon = dentry;
- continue;
- }
-
- if (dentry->d_parent != de->d_parent)
- continue;
-
- if (dentry->d_name.hash != de->d_name.hash)
- continue;
-
- if (dentry->d_name.len != de->d_name.len)
- continue;
-
- if (memcmp(dentry->d_name.name, de->d_name.name,
- de->d_name.len) != 0)
- continue;
-
- dget_locked(dentry);
- ll_dops_init(dentry, 0, 1);
- ll_dentry_rehash(dentry, 1);
- spin_unlock(&dcache_lock);
- cfs_spin_unlock(&ll_lookup_lock);
- iput(inode);
- CDEBUG(D_DENTRY, "alias dentry %.*s (%p) parent %p inode %p "
- "refc %d\n", de->d_name.len, de->d_name.name, de,
- de->d_parent, de->d_inode, atomic_read(&de->d_count));
- return dentry;
- }
-
- if (last_discon) {
- CDEBUG(D_DENTRY, "Reuse disconnected dentry %p inode %p "
- "refc %d\n", last_discon, last_discon->d_inode,
- atomic_read(&last_discon->d_count));
- dget_locked(last_discon);
- lock_dentry(last_discon);
- last_discon->d_flags |= DCACHE_LUSTRE_INVALID;
- unlock_dentry(last_discon);
- spin_unlock(&dcache_lock);
- cfs_spin_unlock(&ll_lookup_lock);
- ll_dops_init(last_discon, 1, 1);
- d_rehash(de);
- d_move(last_discon, de);
- iput(inode);
- return last_discon;
- }
- lock_dentry(de);
- de->d_flags |= DCACHE_LUSTRE_INVALID;
- unlock_dentry(de);
- ll_d_add(de, inode);
- spin_unlock(&dcache_lock);
- cfs_spin_unlock(&ll_lookup_lock);
-
- security_d_instantiate(de, inode);
- d_rehash(de);
-
+ struct dentry *new;
+
+ if (inode) {
+ new = ll_find_alias(inode, de);
+ if (new) {
+ ll_dops_init(new, 1, 1);
+ d_move(new, de);
+ iput(inode);
+ CDEBUG(D_DENTRY,
+ "Reuse dentry %p inode %p refc %d flags %#x\n",
+ new, new->d_inode, d_refcount(new), new->d_flags);
+ return new;
+ }
+ }
+ __d_lustre_invalidate(de);
+ ll_dops_init(de, 1, 1);
+ d_add(de, inode);
+ CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n",
+ de, de->d_inode, d_refcount(de), de->d_flags);