+static unsigned long now;
+
+/* Check if a dentry can be expired return 1 if it can else return 0 */
+static inline int autofs4_can_expire(struct dentry *dentry,
+ unsigned long timeout, int do_now)
+{
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+ /* dentry in the process of being deleted */
+ if (ino == NULL)
+ return 0;
+
+ /* No point expiring a pending mount */
+ if (dentry->d_flags & DCACHE_AUTOFS_PENDING)
+ return 0;
+
+ if (!do_now) {
+ /* Too young to die */
+ if (time_after(ino->last_used + timeout, now))
+ return 0;
+
+ /* update last_used here :-
+ - obviously makes sense if it is in use now
+ - less obviously, prevents rapid-fire expire
+ attempts if expire fails the first time */
+ ino->last_used = now;
+ }
+
+ return 1;
+}
+
+/* Check a mount point for busyness return 1 if not busy, otherwise */
+static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
+{
+ int status = 0;
+
+ DPRINTK("dentry %p %.*s",
+ dentry, (int)dentry->d_name.len, dentry->d_name.name);
+
+ mntget(mnt);
+ dget(dentry);
+
+ if (!follow_down(&mnt, &dentry))
+ goto done;
+
+ while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
+ ;
+
+ /* This is an autofs submount, we can't expire it */
+ if (is_autofs4_dentry(dentry))
+ goto done;
+
+ /* The big question */
+ if (may_umount_tree(mnt) == 0)
+ status = 1;
+done:
+ DPRINTK("returning = %d", status);
+ mntput(mnt);
+ dput(dentry);
+ return status;
+}
+
+/* Check a directory tree of mount points for busyness
+ * The tree is not busy iff no mountpoints are busy
+ * Return 1 if the tree is busy or 0 otherwise