- lock_dentry(dentry);
- if (atomic_read(&dentry->d_count) == 0) {
- CDEBUG(D_DENTRY, "deleting dentry %.*s (%p) parent %p "
- "inode %p\n", dentry->d_name.len,
- dentry->d_name.name, dentry, dentry->d_parent,
- dentry->d_inode);
- dget_locked(dentry);
- __d_drop(dentry);
- unlock_dentry(dentry);
- spin_unlock(&dcache_lock);
- cfs_spin_unlock(&ll_lookup_lock);
- dput(dentry);
- cfs_spin_lock(&ll_lookup_lock);
- spin_lock(&dcache_lock);
- return 1;
- }
- /* disconected dentry can not be find without lookup, because we
- * not need his to unhash or mark invalid. */
- if (dentry->d_flags & DCACHE_DISCONNECTED) {
- unlock_dentry(dentry);
- RETURN (0);
- }
-
- if (!(dentry->d_flags & DCACHE_LUSTRE_INVALID)) {
- CDEBUG(D_DENTRY, "unhashing dentry %.*s (%p) parent %p "
- "inode %p refc %d\n", dentry->d_name.len,
- dentry->d_name.name, dentry, dentry->d_parent,
- dentry->d_inode, atomic_read(&dentry->d_count));
- /* actually we don't unhash the dentry, rather just
- * mark it inaccessible for to __d_lookup(). otherwise
- * sys_getcwd() could return -ENOENT -bzzz */
- dentry->d_flags |= DCACHE_LUSTRE_INVALID;
- if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
- __d_drop(dentry);
- }
- unlock_dentry(dentry);
- return 0;
-}
-
-void ll_unhash_aliases(struct inode *inode)
-{
- struct list_head *tmp, *head;
- ENTRY;
-
- if (inode == NULL) {
- CERROR("unexpected NULL inode, tell phil\n");
- return;
- }
-
- CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n",
- inode->i_ino, inode->i_generation, inode);
-
- head = &inode->i_dentry;
- cfs_spin_lock(&ll_lookup_lock);
- spin_lock(&dcache_lock);
-restart:
- tmp = head;
- while ((tmp = tmp->next) != head) {
- struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
-
- CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
- "inode %p flags %d\n", dentry->d_name.len,
- dentry->d_name.name, dentry, dentry->d_parent,
- dentry->d_inode, dentry->d_flags);
-
- if (dentry->d_name.len == 1 && dentry->d_name.name[0] == '/') {
- CERROR("called on root (?) dentry=%p, inode=%p "
- "ino=%lu\n", dentry, inode, inode->i_ino);
- lustre_dump_dentry(dentry, 1);
+ struct dentry *dentry;
+ struct ll_d_hlist_node *p;
+ ENTRY;
+
+ LASSERT(inode != NULL);
+
+ CDEBUG(D_INODE, "marking dentries for ino %lu/%u(%p) invalid\n",
+ inode->i_ino, inode->i_generation, inode);
+
+ ll_lock_dcache(inode);
+ ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
+ CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
+ "inode %p flags %d\n", dentry->d_name.len,
+ dentry->d_name.name, dentry, dentry->d_parent,
+ dentry->d_inode, dentry->d_flags);
+
+ if (unlikely(dentry == dentry->d_sb->s_root)) {
+ CERROR("%s: called on root dentry=%p, fid="DFID"\n",
+ ll_get_fsname(dentry->d_sb, NULL, 0),
+ dentry, PFID(ll_inode2fid(inode)));
+ lustre_dump_dentry(dentry, 1);