down(&dentry->d_inode->i_sem);
spin_lock(&dcache_lock);
+restart:
node = dentry->d_subdirs.next;
while (node != &dentry->d_subdirs) {
struct dentry * d = list_entry(node,struct dentry,d_child);
- list_del_init(node);
+ node = node->next;
pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count));
- if (d->d_inode) {
+ if (!d_unhashed(d) && (d->d_inode)) {
d = dget_locked(d);
pr_debug("removing");
d_delete(d);
simple_unlink(dentry->d_inode,d);
dput(d);
+ pr_debug(" done\n");
spin_lock(&dcache_lock);
+ /* re-acquired dcache_lock, need to restart */
+ goto restart;
}
- pr_debug(" done\n");
- node = dentry->d_subdirs.next;
}
- list_del_init(&dentry->d_child);
spin_unlock(&dcache_lock);
up(&dentry->d_inode->i_sem);