unsigned long timeout,
                             int do_now)
 {
+       struct autofs_info *ino;
        struct dentry *p;
 
        DPRINTK("top %p %.*s",
        if (!simple_positive(top))
                return 1;
 
-       /* Timeout of a tree mount is determined by its top dentry */
-       if (!autofs4_can_expire(top, timeout, do_now))
-               return 1;
-
-       /* Is someone visiting anywhere in the tree ? */
-       if (may_umount_tree(mnt))
-               return 1;
-
        spin_lock(&dcache_lock);
        for (p = top; p; p = next_dentry(p, top)) {
                /* Negative dentry - give up */
                p = dget(p);
                spin_unlock(&dcache_lock);
 
+               /*
+                * Is someone visiting anywhere in the subtree ?
+                * If there's no mount we need to check the usage
+                * count for the autofs dentry.
+                */
+               ino = autofs4_dentry_ino(p);
                if (d_mountpoint(p)) {
-                       /* First busy => tree busy */
                        if (autofs4_mount_busy(mnt, p)) {
                                dput(p);
                                return 1;
                        }
+               } else {
+                       unsigned int ino_count = atomic_read(&ino->count);
+
+                       /* allow for dget above and top is already dgot */
+                       if (p == top)
+                               ino_count += 2;
+                       else
+                               ino_count++;
+
+                       if (atomic_read(&p->d_count) > ino_count) {
+                               dput(p);
+                               return 1;
+                       }
                }
                dput(p);
                spin_lock(&dcache_lock);
        }
        spin_unlock(&dcache_lock);
+
+       /* Timeout of a tree mount is ultimately determined by its top dentry */
+       if (!autofs4_can_expire(top, timeout, do_now))
+               return 1;
+
        return 0;
 }
 
 
        ino->size = 0;
 
        ino->last_used = jiffies;
+       atomic_set(&ino->count, 0);
 
        ino->sbi = sbi;
 
 
 void autofs4_free_ino(struct autofs_info *ino)
 {
+       struct autofs_info *p_ino;
+
        if (ino->dentry) {
                ino->dentry->d_fsdata = NULL;
-               if (ino->dentry->d_inode)
+               if (ino->dentry->d_inode) {
+                       struct dentry *parent = ino->dentry->d_parent;
+                       if (atomic_dec_and_test(&ino->count)) {
+                               p_ino = autofs4_dentry_ino(parent);
+                               if (p_ino && parent != ino->dentry)
+                                       atomic_dec(&p_ino->count);
+                       }
                        dput(ino->dentry);
+               }
                ino->dentry = NULL;
        }
        if (ino->free)
 
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
        struct autofs_info *ino = autofs4_dentry_ino(dentry);
+       struct autofs_info *p_ino;
        struct inode *inode;
        char *cp;
 
 
        dentry->d_fsdata = ino;
        ino->dentry = dget(dentry);
+       atomic_inc(&ino->count);
+       p_ino = autofs4_dentry_ino(dentry->d_parent);
+       if (p_ino && dentry->d_parent != dentry)
+               atomic_inc(&p_ino->count);
        ino->inode = inode;
 
        dir->i_mtime = CURRENT_TIME;
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
        struct autofs_info *ino = autofs4_dentry_ino(dentry);
+       struct autofs_info *p_ino;
        
        /* This allows root to remove symlinks */
        if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
                return -EACCES;
 
+       if (atomic_dec_and_test(&ino->count)) {
+               p_ino = autofs4_dentry_ino(dentry->d_parent);
+               if (p_ino && dentry->d_parent != dentry)
+                       atomic_dec(&p_ino->count);
+       }
        dput(ino->dentry);
 
        dentry->d_inode->i_size = 0;
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
        struct autofs_info *ino = autofs4_dentry_ino(dentry);
+       struct autofs_info *p_ino;
        
        if (!autofs4_oz_mode(sbi))
                return -EACCES;
        spin_unlock(&dentry->d_lock);
        spin_unlock(&dcache_lock);
 
+       if (atomic_dec_and_test(&ino->count)) {
+               p_ino = autofs4_dentry_ino(dentry->d_parent);
+               if (p_ino && dentry->d_parent != dentry)
+                       atomic_dec(&p_ino->count);
+       }
        dput(ino->dentry);
-
        dentry->d_inode->i_size = 0;
        dentry->d_inode->i_nlink = 0;
 
 {
        struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
        struct autofs_info *ino = autofs4_dentry_ino(dentry);
+       struct autofs_info *p_ino;
        struct inode *inode;
 
        if ( !autofs4_oz_mode(sbi) )
 
        dentry->d_fsdata = ino;
        ino->dentry = dget(dentry);
+       atomic_inc(&ino->count);
+       p_ino = autofs4_dentry_ino(dentry->d_parent);
+       if (p_ino && dentry->d_parent != dentry)
+               atomic_inc(&p_ino->count);
        ino->inode = inode;
        dir->i_nlink++;
        dir->i_mtime = CURRENT_TIME;