diff --git a/CHANGELOG b/CHANGELOG
index f68e16e..b0a255a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,6 +13,7 @@
 - cthon more parser corrections and attempt to fix multi-mounts
   with various combinations of submounts (still broken).
 - cthon fix expire of various forms of nested mounts.
+- cthon fix some shutdown races.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/Makefile.rules b/Makefile.rules
index 7796269..7a19d5f 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -27,7 +27,7 @@ LDFLAGS   = -g
 STRIP     = :
 else
 ifdef DONTSTRIP
-CFLAGS    = -O2 -g
+CFLAGS    ?= -O2 -g
 LDFLAGS   = -g
 STRIP     = :
 else
diff --git a/daemon/automount.c b/daemon/automount.c
index 91f4d15..35d443c 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -36,6 +36,7 @@ #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/poll.h>
 #include <dirent.h>
+#include <sys/vfs.h>
 
 #include "automount.h"
 
@@ -175,177 +176,6 @@ int rmdir_path(struct autofs_point *ap, 
 	return 0;
 }
 
-static int umount_offsets(struct autofs_point *ap, struct mnt_list *mnts, const char *base)
-{
-	char path[PATH_MAX + 1];
-	char *offset = path;
-	struct list_head list, head, *pos, *p;
-	char key[PATH_MAX + 1];
-	struct map_source *map;
-	struct mapent_cache *mc = NULL;
-	struct mapent *me = NULL;
-	char *ind_key;
-	int ret = 0, status;
-
-	INIT_LIST_HEAD(&list);
-	INIT_LIST_HEAD(&head);
-
-	if (!tree_get_mnt_list(mnts, &list, base, 0))
-		return 0;
-
-	list_for_each(p, &list) {
-		struct mnt_list *this;
-
-		this = list_entry(p, struct mnt_list, list);
-
-		if (strcmp(this->fs_type, "autofs"))
-			continue;
-
-		INIT_LIST_HEAD(&this->ordered);
-		add_ordered_list(this, &head);
-	}
-
-	/*
-	 * If it's a direct mount it's base is the key otherwise
-	 * the last path component is the indirect entry key.
-	 */
-	ind_key = strrchr(base, '/');
-	if (ind_key)
-		ind_key++;
-
-	master_source_readlock(ap->entry);
-	map = ap->entry->first;
-	while (map) {
-		mc = map->mc;
-		cache_readlock(mc);
-		me = cache_lookup_distinct(mc, base);
-		if (!me)
-			me = cache_lookup_distinct(mc, ind_key);
-		if (me)
-			break;
-		cache_unlock(mc);
-		map = map->next;
-	}
-	master_source_unlock(ap->entry);
-
-	if (!me)
-		return 0;
-
-	pos = NULL;
-	while ((offset = get_offset(base, offset, &head, &pos))) {
-		struct mapent *oe;
-
-		if (strlen(base) + strlen(offset) >= PATH_MAX) {
-			warn(ap->logopt, "can't umount - mount path too long");
-			ret++;
-			continue;
-		}
-
-		sched_yield();
-
-		strcpy(key, base);
-		strcat(key, offset);
-		oe = cache_lookup_distinct(mc, key);
-
-		if (!oe) {
-			debug(ap->logopt, "offset key %s not found", key);
-			continue;
-		}
-
-		warn(ap->logopt, "umount offset %s", key);
-
-		/*
-		 * We're in trouble if umounting the triggers fails.
-		 * It should always succeed due to the expire design.
-		 */
-		pthread_cleanup_push(cache_lock_cleanup, mc);
-		if (umount_autofs_offset(ap, oe)) {
-			crit(ap->logopt, "failed to umount offset %s", key);
-			ret++;
-		}
-		pthread_cleanup_pop(0);
-	}
-
-	if (!ret && me->multi == me) {
-		cache_multi_lock(mc);
-		status = cache_delete_offset_list(mc, me->key);
-		cache_multi_unlock(mc);
-		if (status != CHE_OK)
-			warn(ap->logopt, "couldn't delete offset list");
-	}
-	cache_unlock(mc);
-
-	return ret;
-}
-
-static int umount_ent(struct autofs_point *ap, const char *path, const char *type)
-{
-	struct stat st;
-	int sav_errno;
-	int is_smbfs = (strcmp(type, "smbfs") == 0);
-	int status;
-	int ret, rv = 1;
-
-	status = lstat(path, &st);
-	sav_errno = errno;
-
-	if (status < 0)
-		warn(ap->logopt, "lstat of %s failed with %d", path, status);
-
-	/*
-	 * lstat failed and we're an smbfs fs returning an error that is not
-	 * EIO or EBADSLT or the lstat failed so it's a bad path. Return
-	 * a fail.
-	 *
-	 * EIO appears to correspond to an smb mount that has gone away
-	 * and EBADSLT relates to CD changer not responding.
-	 */
-	if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
-		rv = spawnll(log_debug, PATH_UMOUNT, PATH_UMOUNT, path, NULL);
-	} else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
-		rv = spawnll(log_debug, PATH_UMOUNT, PATH_UMOUNT, path, NULL);
-	}
-
-	/* We are doing a forced shutcwdown down so unlink busy mounts */
-	if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
-		ret = stat(path, &st);
-		if (ret == -1 && errno == ENOENT) {
-			warn(ap->logopt, "mount point does not exist");
-			return 0;
-		}
-
-		if (ret == 0 && !S_ISDIR(st.st_mode)) {
-			warn(ap->logopt, "mount point is not a directory");
-			return 0;
-		}
-
-		if (ap->state == ST_SHUTDOWN_FORCE) {
-			msg("forcing umount of %s", path);
-			rv = spawnll(log_debug, PATH_UMOUNT, PATH_UMOUNT, "-l", path, NULL);
-		}
-
-		/*
-		 * Verify that we actually unmounted the thing.  This is a
-		 * belt and suspenders approach to not eating user data.
-		 * We have seen cases where umount succeeds, but there is
-		 * still a file system mounted on the mount point.  How
-		 * this happens has not yet been determined, but we want to
-		 * make sure to return failure here, if that is the case,
-		 * so that we do not try to call rmdir_path on the
-		 * directory.
-		 */
-		if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
-			crit(ap->logopt,
-			     "the umount binary reported that %s was "
-			     "unmounted, but there is still something "
-			     "mounted on this path.", path);
-			rv = -1;
-		}
-	}
-
-	return rv;
-}
-
 /* Like ftw, except fn gets called twice: before a directory is
    entered, and after.  If the before call returns 0, the directory
    isn't entered. */
@@ -517,7 +347,7 @@ static void update_map_cache(struct auto
 		mc = map->mc;
 		cache_writelock(mc);
 		me = cache_lookup_distinct(mc, key);
-		if (me)
+		if (me && me->ioctlfd == -1)
 			cache_delete(mc, key);
 		cache_unlock(mc);
 
@@ -530,73 +360,79 @@ static void update_map_cache(struct auto
 
 /* umount all filesystems mounted under path.  If incl is true, then
    it also tries to umount path itself */
-int umount_multi(struct autofs_point *ap, struct mnt_list *mnts, const char *path, int incl)
+int umount_multi(struct autofs_point *ap, const char *path, int incl)
 {
-	int left, n;
-	struct dirent **de;
-	struct mnt_list *mptr;
-	struct list_head *p;
-	struct list_head list;
-
-	INIT_LIST_HEAD(&list);
+	struct mapent *me;
+	struct statfs fs;
+	int is_autofs_fs;
+	int ret, left;
 
 	debug(ap->logopt, "path %s incl %d", path, incl);
 
-	if (!tree_get_mnt_list(mnts, &list, path, incl)) {
-		debug(ap->logopt, "no mounts found under %s", path);
-		check_rm_dirs(ap, path, incl);
-		return 0;
+	ret = statfs(path, &fs);
+	if (ret == -1) {
+		error(ap->logopt, "could not stat fs of %s", path);
+		return 1;
 	}
 
-	left = 0;
-	list_for_each(p, &list) {
-		struct autofs_point *oap = ap;
-		char *has_opt_direct;
-		int is_autofs;
+	is_autofs_fs = fs.f_type == AUTOFS_SUPER_MAGIC ? 1 : 0;
 
-		mptr = list_entry(p, struct mnt_list, list);
+	me = lookup_source_mapent(ap, path);
+	if (!me) {
+		char *ind_key;
 
-		is_autofs = !strcmp(mptr->fs_type, "autofs");
-		has_opt_direct = strstr(mptr->opts, "direct");
+		ind_key = strrchr(path, '/');
+		if (ind_key)
+			ind_key++;
 
-		/* We only want real mounts and top level direct mounts */
-		if (is_autofs && !has_opt_direct)
-			continue;
+		me = lookup_source_mapent(ap, ind_key);
+		if (!me) {
+			warn(ap->logopt, "no mounts found under %s", path);
+			return 0;
+		}
+	}
+
+	left = 0;
+
+	if (me && me->multi) {
+		struct autofs_point *oap = ap;
+		char *root, *base;
 
 		if (ap->submount)
 			oap = ap->parent;
 
-		sched_yield();
+		 if (me == me->multi && !strchr(me->key, '/')) {
+			/* Indirect multi-mount root */
+			root = alloca(strlen(ap->path) + strlen(me->key) + 2);
+			strcpy(root, ap->path);
+			strcat(root, "/");
+			strcat(root, me->key);
+			base = NULL;
+		} else {
+			root = me->multi->key;
+			base = me->key + strlen(root);
+		}
 
-		if (umount_offsets(oap, mnts, mptr->path))
+		if (umount_multi_triggers(oap, root, me, base)) {
 			warn(ap->logopt,
-			     "could not umount some offsets under %s",
-			     mptr->path);
-
-		if (is_autofs)
-			continue;
-
-		sched_yield();
-
-		warn(ap->logopt, "unmounting dir = %s", mptr->path);
-
-		if (umount_ent(ap, mptr->path, mptr->fs_type)) {
-			warn(ap->logopt, "could not umount dir %s",
-				mptr->path);
+			     "could not umount some offsets under %s", path);
 			left++;
 		}
 	}
+	cache_unlock(me->source->mc);
 
-	/* Catch any offsets of indirect mounts with no root mount */
-	if (!left && !tree_is_mounted(mnts, path, MNTS_ALL)) {
-		struct autofs_point *rap = ap;
+	if (left || is_autofs_fs || ap->submount)
+		return left;
 
-		if (ap->submount)
-			rap = ap->parent;
+	/*
+	 * If this is the root of a multi-mount we've had to umount
+	 * it already to ensure it's ok to remove any offset triggers
+	 */
+	if (me != me->multi) {
+		warn(ap->logopt, "unmounting dir = %s", path);
 
-		if (umount_offsets(rap, mnts, path)) {
-			warn(ap->logopt,
-			     "could not umount some offsets under %s", path);
+		if (umount_ent(ap, path)) {
+			warn(ap->logopt, "could not umount dir %s", path);
 			left++;
 		}
 	}
@@ -612,18 +448,13 @@ int umount_multi(struct autofs_point *ap
 
 static int umount_all(struct autofs_point *ap, int force)
 {
-	struct mnt_list *mnts;
 	int left;
 
-	mnts = tree_make_mnt_tree(_PROC_MOUNTS, ap->path);
-
-	left = umount_multi(ap, mnts, ap->path, 0);
+	left = umount_multi(ap, ap->path, 0);
 	if (force && left)
 		warn(ap->logopt, "could not unmount %d dirs under %s",
 		     left, ap->path);
 
-	tree_free_mnt_tree(mnts);
-
 	return left;
 }
 
@@ -729,7 +560,6 @@ static int get_pkt(struct autofs_point *
 			enum states next_state, post_state;
 			size_t read_size = sizeof(next_state);
 			int state_pipe;
-			int status;
 
 			next_state = post_state = ST_INVAL;
 
@@ -767,7 +597,6 @@ static int get_pkt(struct autofs_point *
 
 int do_expire(struct autofs_point *ap, const char *name, int namelen)
 {
-	struct mnt_list *mnts;
 	char buf[PATH_MAX + 1];
 	int len, ret;
 
@@ -786,15 +615,11 @@ int do_expire(struct autofs_point *ap, c
 
 	msg("expiring path %s", buf);
 
-	mnts = tree_make_mnt_tree(_PROC_MOUNTS, buf);
-
-	ret = umount_multi(ap, mnts, buf, 1);
+	ret = umount_multi(ap, buf, 1);
 	if (ret == 0)
 		msg("expired %s", buf);
 	else
-		warn(ap->logopt, "couldn't complet expire of %s", buf);
-
-	tree_free_mnt_tree(mnts);
+		warn(ap->logopt, "couldn't complete expire of %s", buf);
 
 	return ret;
 }
diff --git a/daemon/direct.c b/daemon/direct.c
index f4f60f3..a2aea9c 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -112,40 +112,50 @@ static int autofs_init_direct(struct aut
 int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
 {
 	char buf[MAX_ERR_BUF];
-	int rv, left;
+	int ioctlfd, rv, left;
 
-	left = umount_multi(ap, mnts, me->key, 1);
+	left = umount_multi(ap, me->key, 1);
 	if (left) {
 		warn(ap->logopt, "could not unmount %d dirs under %s",
 		     left, me->key);
 		return -1;
 	}
 
-	if (me->ioctlfd < 0)
-		me->ioctlfd = open(me->key, O_RDONLY);
+	if (me->ioctlfd != -1) {
+		if (tree_is_mounted(mnts, me->key, MNTS_REAL)) {
+			error(ap->logopt,
+			      "attempt to umount busy direct mount %s",
+			      me->key);
+			return 1;
+		}
+		ioctlfd = me->ioctlfd;
+	} else
+		ioctlfd = open(me->key, O_RDONLY);
 
-	if (me->ioctlfd >= 0) {
+	if (ioctlfd >= 0) {
 		int status = 1;
 
-		rv = ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
+		rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
 		if (rv) {
 			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 			error(ap->logopt, "ioctl failed: %s", estr);
 			return 1;
 		} else if (!status) {
 			if (ap->state != ST_SHUTDOWN_FORCE) {
-				debug(ap->logopt, "ask umount returned busy");
+				error(ap->logopt,
+				      "ask umount returned busy for %s",
+				      me->key);
 				return 1;
 			} else {
-				ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
-				close(me->ioctlfd);
 				me->ioctlfd = -1;
+				ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+				close(ioctlfd);
 				goto force_umount;
 			}
 		}
-		ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
-		close(me->ioctlfd);
 		me->ioctlfd = -1;
+		ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+		close(ioctlfd);
 	} else {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap->logopt,
@@ -283,7 +293,7 @@ int do_mount_autofs_direct(struct autofs
 	struct mnt_params *mp;
 	time_t timeout = ap->exp_timeout;
 	struct stat st;
-	int status, ret;
+	int status, ret, ioctlfd;
 	struct list_head list;
 
 	INIT_LIST_HEAD(&list);
@@ -299,6 +309,11 @@ int do_mount_autofs_direct(struct autofs
 		}
 	}
 
+	if (me->ioctlfd != -1) {
+		error(ap->logopt, "active direct mount %s", me->key);
+		return -1;
+	}
+
 	status = pthread_once(&key_mnt_params_once, key_mnt_params_init);
 	if (status)
 		fatal(status);
@@ -349,8 +364,8 @@ int do_mount_autofs_direct(struct autofs
 	}
 
 	/* Root directory for ioctl()'s */
-	me->ioctlfd = open(me->key, O_RDONLY);
-	if (me->ioctlfd < 0) {
+	ioctlfd = open(me->key, O_RDONLY);
+	if (ioctlfd < 0) {
 		crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
 		goto out_umount;
 	}
@@ -363,7 +378,7 @@ int do_mount_autofs_direct(struct autofs
 	ap->kver.minor = 0;
 
 	/* If this ioctl() doesn't work, it is kernel version 2 */
-	if (!ioctl(me->ioctlfd, AUTOFS_IOC_PROTOVER, &ap->kver.major)) {
+	if (!ioctl(ioctlfd, AUTOFS_IOC_PROTOVER, &ap->kver.major)) {
 		 /* If this ioctl() fails the kernel doesn't support direct mounts */
 		 if (ioctl(me->ioctlfd, AUTOFS_IOC_PROTOSUBVER, &ap->kver.minor)) {
 			ap->kver.minor = 0;
@@ -389,9 +404,9 @@ int do_mount_autofs_direct(struct autofs
 	}
 
 got_version:
-	ioctl(me->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
+	ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
 
-	ret = fstat(me->ioctlfd, &st);
+	ret = fstat(ioctlfd, &st);
 	if (ret == -1) {
 		error(ap->logopt,
 		      "failed to stat direct mount trigger %s", me->key);
@@ -399,16 +414,14 @@ got_version:
 	}
 	cache_set_ino_index(me->source->mc, me->key, st.st_dev, st.st_ino);
 
-	close(me->ioctlfd);
-	me->ioctlfd = -1;
+	close(ioctlfd);
 
 	debug(ap->logopt, "mounted trigger %s", me->key);
 
 	return 0;
 
 out_close:
-	close(me->ioctlfd);
-	me->ioctlfd = -1;
+	close(ioctlfd);
 out_umount:
 	/* TODO: maybe force umount (-l) */
 	umount(me->key);
@@ -478,38 +491,55 @@ int mount_autofs_direct(struct autofs_po
 int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
 {
 	char buf[MAX_ERR_BUF];
-	int rv = 1;
+	int ioctlfd, rv = 1;
 
-	if (me->ioctlfd < 0)
-		me->ioctlfd = open(me->key, O_RDONLY);
+	if (me->ioctlfd != -1) {
+		if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) {
+			error(ap->logopt,
+			      "attempt to umount busy offset %s", me->key);
+			return 1;
+		}
+		ioctlfd = me->ioctlfd;
+	} else
+		ioctlfd = open(me->key, O_RDONLY);
 
-	if (me->ioctlfd >= 0) {
+	if (ioctlfd >= 0) {
 		int status = 1;
 
-		rv = ioctl(me->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
+		rv = ioctl(ioctlfd, AUTOFS_IOC_ASKUMOUNT, &status);
 		if (rv) {
 			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 			error(ap->logopt, "ioctl failed: %s", estr);
 			return 1;
 		} else if (!status) {
 			if (ap->state != ST_SHUTDOWN_FORCE) {
-				debug(ap->logopt, "ask umount returned busy");
+				error(ap->logopt,
+				      "ask umount returned busy for %s",
+				      me->key);
 				return 1;
 			} else {
-				ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
-				close(me->ioctlfd);
 				me->ioctlfd = -1;
+				ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+				close(ioctlfd);
 				goto force_umount;
 			}
 		}
-		ioctl(me->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
-		close(me->ioctlfd);
 		me->ioctlfd = -1;
+		ioctl(ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+		close(ioctlfd);
 	} else {
-		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		struct stat st;
+		char *estr;
+		int save_errno = errno;
+
+		/* Non existent directory on remote fs - no mount */
+		if (stat(me->key, &st) == -1 && errno == ENOENT)
+			return 0;
+
+		estr = strerror_r(save_errno, buf, MAX_ERR_BUF);
 		error(ap->logopt,
-		      "couldn't get ioctl fd for offset %s", me->key);
-		debug(ap->logopt, "open: %s", estr);
+		      "couldn't get ioctl fd for offset %s: %s",
+		      me->key, estr);
 		goto force_umount;
 	}
 
@@ -521,7 +551,7 @@ int umount_autofs_offset(struct autofs_p
 			return 0;
 			break;
 		case EBUSY:
-			warn(ap->logopt, "mount point %s is in use", me->key);
+			error(ap->logopt, "mount point %s is in use", me->key);
 			if (ap->state != ST_SHUTDOWN_FORCE)
 				return 1;
 			break;
@@ -548,7 +578,7 @@ int mount_autofs_offset(struct autofs_po
 	struct mnt_params *mp;
 	time_t timeout = ap->exp_timeout;
 	struct stat st;
-	int status, ret;
+	int ioctlfd, status, ret;
 
 	if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
 		if (ap->state != ST_READMAP)
@@ -557,6 +587,11 @@ int mount_autofs_offset(struct autofs_po
 		return 0;
 	}
 
+	if (me->ioctlfd != -1) {
+		error(ap->logopt, "active offset mount %s", me->key);
+		return -1;
+	}
+
 	status = pthread_once(&key_mnt_params_once, key_mnt_params_init);
 	if (status)
 		fatal(status);
@@ -634,15 +669,15 @@ int mount_autofs_offset(struct autofs_po
 	}
 
 	/* Root directory for ioctl()'s */
-	me->ioctlfd = open(me->key, O_RDONLY);
-	if (me->ioctlfd < 0) {
+	ioctlfd = open(me->key, O_RDONLY);
+	if (ioctlfd < 0) {
 		crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
 		goto out_umount;
 	}
 
-	ioctl(me->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
+	ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout);
 
-	ret = fstat(me->ioctlfd, &st);
+	ret = fstat(ioctlfd, &st);
 	if (ret == -1) {
 		error(ap->logopt,
 		     "failed to stat direct mount trigger %s", me->key);
@@ -651,16 +686,14 @@ int mount_autofs_offset(struct autofs_po
 
 	cache_set_ino_index(me->source->mc, me->key, st.st_dev, st.st_ino);
 
-	close(me->ioctlfd);
-	me->ioctlfd = -1;
+	close(ioctlfd);
 
 	debug(ap->logopt, "mounted trigger %s", me->key);
 
 	return 0;
 
 out_close:
-	close(me->ioctlfd);
-	me->ioctlfd = -1;
+	close(ioctlfd);
 out_umount:
 	umount(me->key);
 out_err:
@@ -677,7 +710,7 @@ void *expire_proc_direct(void *arg)
 	struct expire_args *ea;
 	struct autofs_point *ap;
 	struct mapent_cache *mc = NULL;
-	struct mapent *me = NULL;
+	struct mapent *ro, *me = NULL;
 	unsigned int now;
 	int ioctlfd = -1;
 	int status, ret;
@@ -713,12 +746,12 @@ void *expire_proc_direct(void *arg)
 	/* Get a list of real mounts and expire them if possible */
 	mnts = get_mnt_list(_PROC_MOUNTS, "/", 0);
 	for (next = mnts; next; next = next->next) {
-		/* Consider only autofs mounts */
-		if (!strstr(next->fs_type, "autofs"))
+		/* Skip submounts */
+		if (strstr(next->fs_type, "indirect"))
 			continue;
 
-		/* Skip submounts */
-		if (strstr(next->opts, "indirect"))
+		/* Skip offsets */
+		if (strstr(next->opts, "offsets"))
 			continue;
 
 		sched_yield();
@@ -760,7 +793,6 @@ void *expire_proc_direct(void *arg)
 			debug(ap->logopt,
 			      "failed to expire mount %s", next->path);
 			ea->status = 1;
-			break;
 		}
 	}
 	free_mnt_list(mnts);
@@ -802,43 +834,6 @@ void *expire_proc_direct(void *arg)
 	return NULL;
 }
 
-static void kernel_callback_cleanup(void *arg)
-{
-	struct autofs_point *ap;
-	struct pending_args *mt;
-	struct mapent_cache *mc;
-	struct mapent *me;
-
-	mt = (struct pending_args *) arg;
-	ap = mt->ap;
-	mc = mt->mc;
-
-	if (mt->status) {
-		cache_writelock(mc);
-		send_ready(mt->ioctlfd, mt->wait_queue_token);
-		if (mt->type == NFY_EXPIRE) {
-			close(mt->ioctlfd);
-			me = cache_lookup_distinct(mc, mt->name);
-			if (me)
-				me->ioctlfd = -1;
-		}
-		cache_unlock(mc);
-	} else {
-		cache_writelock(mc);
-		send_fail(mt->ioctlfd, mt->wait_queue_token);
-		if (mt->type == NFY_MOUNT) {
-			close(mt->ioctlfd);
-			me = cache_lookup_distinct(mc, mt->name);
-			if (me)
-				me->ioctlfd = -1;
-		}
-		cache_unlock(mc);
-	}
-
-	free(mt);
-	return;
-}
-
 void pending_cleanup(void *arg)
 {
 	struct pending_args *mt;
@@ -859,21 +854,28 @@ void pending_cleanup(void *arg)
 		fatal(status);
 }
 
+static void expire_send_fail(void *arg)
+{
+	struct pending_args *mt = arg;
+	send_fail(mt->ioctlfd, mt->wait_queue_token);
+}
+
 static void *do_expire_direct(void *arg)
 {
 	struct pending_args *mt;
 	struct autofs_point *ap;
 	size_t len;
-	int status;
+	int status, state;
 
 	mt = (struct pending_args *) arg;
 
+	pthread_cleanup_push(expire_send_fail, mt);
+
 	status = pthread_mutex_lock(&mt->mutex);
 	if (status)
 		fatal(status);
 
 	ap = mt->ap;
-	mt->status = 1;
 
 	mt->signaled = 1;
 	status = pthread_cond_signal(&mt->cond);
@@ -884,21 +886,28 @@ static void *do_expire_direct(void *arg)
 	if (status)
 		fatal(status);
 
-	pthread_cleanup_push(kernel_callback_cleanup, mt);
-
 	len = _strlen(mt->name, KEY_MAX_LEN);
 	if (!len) {
 		warn(ap->logopt, "direct key path too long %s", mt->name);
-		mt->status = 0;
 		/* TODO: force umount ?? */
 		pthread_exit(NULL);
 	}
 
 	status = do_expire(ap, mt->name, len);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 	if (status)
-		mt->status = 0;
+		send_fail(mt->ioctlfd, mt->wait_queue_token);
+	else {
+		struct mapent *me;
+		me = lookup_source_mapent(ap, mt->name);
+		me->ioctlfd = -1;
+		cache_unlock(me->source->mc);
+		send_ready(mt->ioctlfd, mt->wait_queue_token);
+		close(mt->ioctlfd);
+	}
+	pthread_setcancelstate(state, NULL);
 
-	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(0);
 	return NULL;
 }
 
@@ -910,7 +919,9 @@ int handle_packet_expire_direct(struct a
 	struct pending_args *mt;
 	char buf[MAX_ERR_BUF];
 	pthread_t thid;
-	int status = 0;
+	int status, state;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	/*
 	 * This is a bit of a big deal.
@@ -942,18 +953,19 @@ int handle_packet_expire_direct(struct a
 		 */
 		crit(ap->logopt, "can't find map entry for (%lu,%lu)",
 		    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
-	pthread_cleanup_push(cache_lock_cleanup, mc);
 
 	mt = malloc(sizeof(struct pending_args));
 	if (!mt) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap->logopt, "malloc: %s", estr);
 		send_fail(me->ioctlfd, pkt->wait_queue_token);
-		status = 1;
-		goto done;
+		cache_unlock(mc);
+		pthread_setcancelstate(state, NULL);
+		return 1;
 	}
 
 	status = pthread_mutex_init(&mt->mutex, NULL);
@@ -985,11 +997,15 @@ int handle_packet_expire_direct(struct a
 		error(ap->logopt, "expire thread create failed");
 		free(mt);
 		send_fail(mt->ioctlfd, pkt->wait_queue_token);
-		status = 1;
-		goto done;
+		cache_unlock(mc);
+		pending_cleanup(mt);
+		pthread_setcancelstate(state, NULL);
+		return 1;
 	}
 
+	cache_unlock(mc);
 	pthread_cleanup_push(pending_cleanup, mt);
+	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
@@ -999,12 +1015,14 @@ int handle_packet_expire_direct(struct a
 	}
 
 	pthread_cleanup_pop(1);
-	pthread_cleanup_pop(1);
-	return status;
+	return 0;
+}
 
-done:
-	cache_lock_cleanup(mc);
-	return status;
+static void mount_send_fail(void *arg)
+{
+	struct pending_args *mt = arg;
+	send_fail(mt->ioctlfd, mt->wait_queue_token);
+	close(mt->ioctlfd);
 }
 
 static void *do_mount_direct(void *arg)
@@ -1021,7 +1039,7 @@ static void *do_mount_direct(void *arg)
 	struct thread_stdenv_vars *tsv;
 	int tmplen;
 	struct stat st;
-	int status;
+	int status, state;
 
 	mt = (struct pending_args *) arg;
 
@@ -1030,7 +1048,6 @@ static void *do_mount_direct(void *arg)
 		fatal(status);
 
 	ap = mt->ap;
-	mt->status = 0;
 
 	mt->signaled = 1;
 	status = pthread_cond_signal(&mt->cond);
@@ -1041,12 +1058,14 @@ static void *do_mount_direct(void *arg)
 	if (status)
 		fatal(status);
 
-	pthread_cleanup_push(kernel_callback_cleanup, mt);
+	pthread_cleanup_push(mount_send_fail, mt);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	status = fstat(mt->ioctlfd, &st);
 	if (status == -1) {
 		error(ap->logopt,
 		      "can't stat direct mount trigger %s", mt->name);
+		pthread_setcancelstate(state, NULL);
 		pthread_exit(NULL);
 	}
 
@@ -1055,9 +1074,12 @@ static void *do_mount_direct(void *arg)
 		error(ap->logopt,
 		     "direct trigger not valid or already mounted %s",
 		     mt->name);
+		pthread_setcancelstate(state, NULL);
 		pthread_exit(NULL);
 	}
 
+	pthread_setcancelstate(state, NULL);
+
 	msg("attempting to mount entry %s", mt->name);
 
 	/*
@@ -1173,13 +1195,22 @@ cont:
 	 * Direct mounts are always a single mount. If it fails there's
 	 * nothing to undo so just complain
 	 */
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 	if (status) {
+		struct mapent *me;
+		me = lookup_source_mapent(ap, mt->name);
+		me->ioctlfd = mt->ioctlfd;
+		cache_unlock(me->source->mc);
+		send_ready(mt->ioctlfd, mt->wait_queue_token);
 		msg("mounted %s", mt->name);
-		mt->status = 1;
-	} else
+	} else {
+		send_fail(mt->ioctlfd, mt->wait_queue_token);
+		close(mt->ioctlfd);
 		msg("failed to mount %s", mt->name);
+	}
+	pthread_setcancelstate(state, NULL);
 
-	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(0);
 	return NULL;
 }
 
@@ -1192,7 +1223,9 @@ int handle_packet_missing_direct(struct 
 	struct pending_args *mt;
 	char buf[MAX_ERR_BUF];
 	int status = 0;
-	int ioctlfd;
+	int ioctlfd, state;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	master_source_readlock(ap->entry);
 	map = ap->entry->first;
@@ -1223,19 +1256,18 @@ int handle_packet_missing_direct(struct 
 		 */
 		crit(ap->logopt, "can't find map entry for (%lu,%lu)",
 		    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
-	pthread_cleanup_push(cache_lock_cleanup, mc);
-
 	ioctlfd = open(me->key, O_RDONLY);
 	if (ioctlfd < 0) {
+		cache_unlock(mc);
+		pthread_setcancelstate(state, NULL);
 		crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
 		/* TODO:  how do we clear wait q in kernel ?? */
-		status = 1;
-		goto done;
+		return 1;
 	}
-	me->ioctlfd = ioctlfd;
 
 	debug(ap->logopt, "token %ld, name %s, request pid %u",
 		  (unsigned long) pkt->wait_queue_token, me->key, pkt->pid);
@@ -1244,21 +1276,22 @@ int handle_packet_missing_direct(struct 
 	if (ap->state == ST_SHUTDOWN_PENDING ||
 	    ap->state == ST_SHUTDOWN_FORCE ||
 	    ap->state == ST_SHUTDOWN) {
-		send_fail(me->ioctlfd, pkt->wait_queue_token);
-		close(me->ioctlfd);
-		me->ioctlfd = -1;
-		status = 1;
-		goto done;
+		send_fail(ioctlfd, pkt->wait_queue_token);
+		close(ioctlfd);
+		cache_unlock(mc);
+		pthread_setcancelstate(state, NULL);
+		return 1;
 	}
 
 	mt = malloc(sizeof(struct pending_args));
 	if (!mt) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap->logopt, "malloc: %s", estr);
-		send_fail(me->ioctlfd, pkt->wait_queue_token);
-		close(me->ioctlfd);
-		me->ioctlfd = -1;
-		goto done;
+		send_fail(ioctlfd, pkt->wait_queue_token);
+		close(ioctlfd);
+		cache_unlock(mc);
+		pthread_setcancelstate(state, NULL);
+		return 1;
 	}
 
 	status = pthread_mutex_init(&mt->mutex, NULL);
@@ -1274,7 +1307,7 @@ int handle_packet_missing_direct(struct 
 		fatal(status);
 
 	mt->ap = ap;
-	mt->ioctlfd = me->ioctlfd;
+	mt->ioctlfd = ioctlfd;
 	mt->mc = mc;
 	/* TODO: check length here */
 	strcpy(mt->name, me->key);
@@ -1288,13 +1321,15 @@ int handle_packet_missing_direct(struct 
 	if (status) {
 		error(ap->logopt, "missing mount thread create failed");
 		free(mt);
-		send_fail(me->ioctlfd, pkt->wait_queue_token);
-		close(me->ioctlfd);
-		me->ioctlfd = -1;
-		status = 1;
-		goto done;
+		send_fail(ioctlfd, pkt->wait_queue_token);
+		close(ioctlfd);
+		cache_unlock(mc);
+		pending_cleanup(mt);
+		pthread_setcancelstate(state, NULL);
+		return 1;
 	}
 
+	cache_unlock(mc);
 	pthread_cleanup_push(pending_cleanup, mt);
 
 	mt->signaled = 0;
@@ -1305,11 +1340,7 @@ int handle_packet_missing_direct(struct 
 	}
 
 	pthread_cleanup_pop(1);
-	pthread_cleanup_pop(1);
-	return status;
 
-done:
-	cache_lock_cleanup(mc);
-	return status;
+	return 0;
 }
 
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 079b278..406bf72 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -281,6 +281,7 @@ int mount_autofs_indirect(struct autofs_
 int umount_autofs_indirect(struct autofs_point *ap)
 {
 	char buf[MAX_ERR_BUF];
+	struct stat st;
 	int ret, rv;
 
 	/*
@@ -300,17 +301,16 @@ int umount_autofs_indirect(struct autofs
 		return 1;
 	} else if (!ret) {
 		error(ap->logopt, "ask umount returned busy %s", ap->path);
+		return 1;
 	}
 
-	if (ap->ioctlfd >= 0) {
-		ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
-		close(ap->ioctlfd);
-		ap->ioctlfd = -1;
-		close(ap->state_pipe[0]);
-		close(ap->state_pipe[1]);
-		ap->state_pipe[0] = -1;
-		ap->state_pipe[1] = -1;
-	}
+	ioctl(ap->ioctlfd, AUTOFS_IOC_CATATONIC, 0);
+	close(ap->ioctlfd);
+	ap->ioctlfd = -1;
+	close(ap->state_pipe[0]);
+	close(ap->state_pipe[1]);
+	ap->state_pipe[0] = -1;
+	ap->state_pipe[1] = -1;
 
 	if (ap->pipefd >= 0)
 		close(ap->pipefd);
@@ -366,7 +366,7 @@ void *expire_proc_indirect(void *arg)
 	struct expire_args *ea;
 	unsigned int now;
 	int offsets, submnts, count;
-	int ioctlfd;
+	int ioctlfd, limit;
 	int status, ret;
 	char buf[MAX_ERR_BUF];
 
@@ -442,7 +442,7 @@ void *expire_proc_indirect(void *arg)
 		if (!me)
 			continue;
 
-		if (me && *me->key == '/') {
+		if (*me->key == '/') {
 			ioctlfd = me->ioctlfd;
 			cache_unlock(mc);
 		} else {
@@ -458,45 +458,29 @@ void *expire_proc_indirect(void *arg)
 			warn(ap->logopt,
 			     "failed to expire mount %s:", next->path, estr);
 			ea->status = 1;
-			break;
 		}
-	}
-	free_mnt_list(mnts);
 
-	count = offsets = submnts = 0;
-	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1);
-	/* Are there any real mounts left */
-	for (next = mnts; next; next = next->next) {
-		if (strcmp(next->fs_type, "autofs"))
-			count++;
-		else {
-			if (strstr(next->opts, "indirect"))
-				submnts++;
-			else
-				offsets++;
-		}
 	}
+	free_mnt_list(mnts);
 
 	/*
 	 * If there are no more real mounts left we could still
 	 * have some offset mounts with no '/' offset so we need to
 	 * umount them here.
 	 */
-	if (mnts) {
-		int ret, tries = (count + submnts + offsets + 2) * 2;
-
-		while (tries--) {
-			ret = ioctl(ap->ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now);
-			if (ret < 0 && errno != EAGAIN) {
-				warn(ap->logopt,
-				      "failed to expire ofsets under %s",
-				      ap->path);
-				ea->status = 1;
+	limit = count_mounts(ap, ap->path);
+	while (limit--) {
+		ret = ioctl(ap->ioctlfd, AUTOFS_IOC_EXPIRE_MULTI, &now);
+		if (ret < 0) {
+			if (errno == EAGAIN)
 				break;
-			}
+			warn(ap->logopt,
+			      "failed to expire offsets under %s",
+			      ap->path);
+			ea->status = 1;
+			break;
 		}
 	}
-	free_mnt_list(mnts);
 
 	count = offsets = submnts = 0;
 	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
@@ -543,30 +527,20 @@ void *expire_proc_indirect(void *arg)
 	return NULL;
 }
 
-static void kernel_callback_cleanup(void *arg)
-{
-	struct autofs_point *ap;
-	struct pending_args *mt;
-
-	mt = (struct pending_args *) arg;
-	ap = mt->ap;
-
-	if (mt->status)
-		send_ready(ap->ioctlfd, mt->wait_queue_token);
-	else
-		send_fail(ap->ioctlfd, mt->wait_queue_token);
-
-	free(mt);
-	return;
-}
-
 /* See direct.c */
 extern void pending_cleanup(void *);
 
+static void expire_send_fail(void *arg)
+{
+	struct pending_args *mt = arg;
+	send_fail(mt->ap->ioctlfd, mt->wait_queue_token);
+}
+
 static void *do_expire_indirect(void *arg)
 {
 	struct pending_args *mt;
-	int status;
+	struct autofs_point *ap;
+	int status, state;
 
 	mt = (struct pending_args *) arg;
 
@@ -574,7 +548,7 @@ static void *do_expire_indirect(void *ar
 	if (status)
 		fatal(status);
 
-	mt->status = 1;
+	ap = mt->ap;
 
 	mt->signaled = 1;
 	status = pthread_cond_signal(&mt->cond);
@@ -585,13 +559,17 @@ static void *do_expire_indirect(void *ar
 	if (status)
 		fatal(status);
 
-	pthread_cleanup_push(kernel_callback_cleanup, mt);
+	pthread_cleanup_push(expire_send_fail, mt);
 
 	status = do_expire(mt->ap, mt->name, mt->len);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 	if (status)
-		mt->status = 0;
+		send_fail(ap->ioctlfd, mt->wait_queue_token);
+	else
+		send_ready(ap->ioctlfd, mt->wait_queue_token);
+	pthread_setcancelstate(state, NULL);
 
-	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(0);
 
 	return NULL;
 }
@@ -601,7 +579,9 @@ int handle_packet_expire_indirect(struct
 	struct pending_args *mt;
 	char buf[MAX_ERR_BUF];
 	pthread_t thid;
-	int status;
+	int status, state;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	debug(ap->logopt, "token %ld, name %s",
 		  (unsigned long) pkt->wait_queue_token, pkt->name);
@@ -611,6 +591,7 @@ int handle_packet_expire_indirect(struct
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap->logopt, "malloc: %s", estr);
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
+		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
@@ -637,9 +618,13 @@ int handle_packet_expire_indirect(struct
 		error(ap->logopt, "expire thread create failed");
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
 		free(mt);
+		pending_cleanup(mt);
+		pthread_setcancelstate(state, NULL);
+		return 1;
 	}
 
 	pthread_cleanup_push(pending_cleanup, mt);
+	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
@@ -653,6 +638,12 @@ int handle_packet_expire_indirect(struct
 	return 0;
 }
 
+static void mount_send_fail(void *arg)
+{
+	struct pending_args *mt = arg;
+	send_fail(mt->ap->ioctlfd, mt->wait_queue_token);
+}
+
 static void *do_mount_indirect(void *arg)
 {
 	struct pending_args *mt;
@@ -667,7 +658,7 @@ static void *do_mount_indirect(void *arg
 	struct group **ppgr = &pgr;
 	char *pw_tmp, *gr_tmp;
 	struct thread_stdenv_vars *tsv;
-	int len, tmplen, status;
+	int len, tmplen, status, state;
 
 	mt = (struct pending_args *) arg;
 
@@ -687,11 +678,13 @@ static void *do_mount_indirect(void *arg
 	if (status)
 		fatal(status);
 
-	pthread_cleanup_push(kernel_callback_cleanup, mt);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	len = ncat_path(buf, sizeof(buf), ap->path, mt->name, mt->len);
 	if (!len) {
 		crit(ap->logopt, "path to be mounted is to long");
+		send_fail(ap->ioctlfd, mt->wait_queue_token);
+		pthread_setcancelstate(state, NULL);
 		pthread_exit(NULL);
 	}
 
@@ -699,9 +692,14 @@ static void *do_mount_indirect(void *arg
 	if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt->dev)) {
 		error(ap->logopt,
 		      "indirect trigger not valid or already mounted %s", buf);
+		send_fail(ap->ioctlfd, mt->wait_queue_token);
+		pthread_setcancelstate(state, NULL);
 		pthread_exit(NULL);
 	}
 
+	pthread_cleanup_push(mount_send_fail, mt);
+	pthread_setcancelstate(state, NULL);
+
 	msg("attempting to mount entry %s", buf);
 
 	/*
@@ -812,13 +810,17 @@ static void *do_mount_indirect(void *arg
 	}
 cont:
 	status = lookup_nss_mount(ap, mt->name, mt->len);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 	if (status) {
-		mt->status = 1;
+		send_ready(ap->ioctlfd, mt->wait_queue_token);
 		msg("mounted %s", buf);
-	} else
+	} else {
+		send_fail(ap->ioctlfd, mt->wait_queue_token);
 		msg("failed to mount %s", buf);
+	}
+	pthread_setcancelstate(state, NULL);
 
-	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(0);
 	return NULL;
 }
 
@@ -827,7 +829,9 @@ int handle_packet_missing_indirect(struc
 	pthread_t thid;
 	char buf[MAX_ERR_BUF];
 	struct pending_args *mt;
-	int status;
+	int status, state;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
 	debug(ap->logopt, "token %ld, name %s, request pid %u",
 		(unsigned long) pkt->wait_queue_token, pkt->name, pkt->pid);
@@ -837,6 +841,7 @@ int handle_packet_missing_indirect(struc
 	    ap->state == ST_SHUTDOWN_FORCE ||
 	    ap->state == ST_SHUTDOWN) {
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
+		pthread_setcancelstate(state, NULL);
 		return 0;
 	}
 
@@ -845,6 +850,7 @@ int handle_packet_missing_indirect(struc
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		error(ap->logopt, "malloc: %s", estr);
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
+		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
@@ -874,10 +880,13 @@ int handle_packet_missing_indirect(struc
 		error(ap->logopt, "expire thread create failed");
 		send_fail(ap->ioctlfd, pkt->wait_queue_token);
 		free(mt);
+		pending_cleanup(mt);
+		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
 	pthread_cleanup_push(pending_cleanup, mt);
+	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
diff --git a/daemon/lookup.c b/daemon/lookup.c
index a8ef518..6942121 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -931,7 +931,9 @@ int lookup_prune_cache(struct autofs_poi
 				free(path);
 				goto next;
 			}
-			status = cache_delete(mc, key);
+			status = CHE_FAIL;
+			if (this->ioctlfd == -1)
+				status = cache_delete(mc, key);
 			cache_unlock(mc);
 
 			if (status != CHE_FAIL) {
@@ -968,7 +970,7 @@ struct mapent *lookup_source_mapent(stru
 	struct master_mapent *entry = ap->entry;
 	struct map_source *map;
 	struct mapent_cache *mc;
-	struct mapent *me;
+	struct mapent *me = NULL;
 
 	pthread_cleanup_push(master_source_lock_cleanup, entry);
 	master_source_readlock(entry);
diff --git a/daemon/state.c b/daemon/state.c
index caeb3e3..67d8031 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -702,7 +702,8 @@ static void *do_run_task(void *arg)
 	struct state_queue *task;
 	struct autofs_point *ap;
 	enum states next_state, state;
-	int status, ret;
+	unsigned long ret = 1;
+	int status;
  
 	status = pthread_mutex_lock(&task_mutex);
 	if (status)
@@ -755,7 +756,7 @@ static void *do_run_task(void *arg)
 
 	state_mutex_unlock(ap);
 
-	return;
+	return (void *) ret;
 }
 
 static int run_state_task(struct state_queue *task)
diff --git a/include/automount.h b/include/automount.h
index b10cfad..4c4d507 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -66,7 +66,9 @@ #define SLOPPYOPT
 #define SLOPPY
 #endif
 
-#define AUTOFS_SUPER_MAGIC 0x0187L
+#define AUTOFS_SUPER_MAGIC 0x00000187L
+#define SMB_SUPER_MAGIC    0x0000517BL
+#define CIFS_MAGIC_NUMBER  0xFF534D42L
 
 /* This sould be enough for at least 20 host aliases */
 #define HOST_ENT_BUF_SIZE	2048
@@ -336,6 +338,7 @@ struct mnt_list {
 	struct mnt_list *right;
 	struct list_head self;
 	struct list_head list;
+	struct list_head sublist;
 	/*
 	 * Offset mount handling ie. add_ordered_list
 	 * and get_offset.
@@ -357,6 +360,7 @@ void add_ordered_list(struct mnt_list *e
 void tree_free_mnt_tree(struct mnt_list *tree);
 struct mnt_list *tree_make_mnt_tree(const char *table, const char *path);
 int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
+int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include);
 int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path);
 int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
 
@@ -448,7 +452,7 @@ struct autofs_point {
 /* Standard functions used by daemon or modules */
 
 void *handle_mounts(void *arg);
-int umount_multi(struct autofs_point *ap, struct mnt_list *mnts, const char *path, int incl);
+int umount_multi(struct autofs_point *ap, const char *path, int incl);
 int send_ready(int ioctlfd, unsigned int wait_queue_token);
 int send_fail(int ioctlfd, unsigned int wait_queue_token);
 int do_expire(struct autofs_point *ap, const char *name, int namelen);
diff --git a/include/parse_subs.h b/include/parse_subs.h
index e87cea5..10c6083 100644
--- a/include/parse_subs.h
+++ b/include/parse_subs.h
@@ -18,6 +18,8 @@
 #ifndef PARSE_SUBS_H
 #define PARSE_SUBS_H
 
+struct mapent;
+
 const char *skipspace(const char *);
 int check_colon(const char *);
 int chunklen(const char *, int);
@@ -25,5 +27,8 @@ int strmcmp(const char *, const char *, 
 char *dequote(const char *, int, unsigned int);
 int span_space(const char *, unsigned int);
 char *sanitize_path(const char *, int, unsigned int, unsigned int);
+int umount_ent(struct autofs_point *, const char *);
+int mount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
+int umount_multi_triggers(struct autofs_point *, char *, struct mapent *, const char *);
 
 #endif
diff --git a/lib/cache.c b/lib/cache.c
index 4d0b196..a047320 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -473,7 +473,6 @@ static void cache_add_ordered_offset(str
 {
 	struct list_head *p;
 	struct mapent *this;
-	int status = CHE_OK;
 
 	list_for_each(p, head) {
 		size_t tlen;
@@ -639,6 +638,18 @@ int cache_delete_offset_list(struct mape
 	while (next != head) {
 		this = list_entry(next, struct mapent, multi_list);
 		next = next->next;
+		if (this->ioctlfd != -1) {
+			error(LOGOPT_ANY,
+			      "active offset mount key %s", this->key);
+			return CHE_FAIL;
+		}
+	}
+
+	head = &me->multi_list;
+	next = head->next;
+	while (next != head) {
+		this = list_entry(next, struct mapent, multi_list);
+		next = next->next;
 		list_del_init(&this->multi_list);
 		this->multi = NULL;
 		debug(LOGOPT_NONE, "deleting offset key %s", this->key);
diff --git a/lib/master.c b/lib/master.c
index d5e58d2..bcda72a 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -296,7 +296,6 @@ struct map_source *master_find_map_sourc
 				int argc, const char **argv)
 {
 	struct map_source *source = NULL;
-	int status;
 
 	master_mutex_lock();
 
@@ -559,7 +558,6 @@ void master_source_current_signal(struct
 struct master_mapent *master_find_mapent(struct master *master, const char *path)
 {
 	struct list_head *head, *p;
-	int status;
 
 	master_mutex_lock();
 
@@ -625,27 +623,18 @@ struct master_mapent *master_new_mapent(
 
 void master_add_mapent(struct master *master, struct master_mapent *entry)
 {
-	int status;
-
 	master_mutex_lock();
 	list_add_tail(&entry->list, &master->mounts);
 	master_mutex_unlock();
-
 	return;
 }
 
 void master_remove_mapent(struct master_mapent *entry)
 {
-	struct autofs_point *ap;
-	int status;
-
 	master_mutex_lock();
-
 	if (!list_empty(&entry->list))
 		list_del_init(&entry->list);
-
 	master_mutex_unlock();
-
 	return;
 }
 
@@ -729,8 +718,6 @@ struct master *master_new(const char *na
 
 int master_read_master(struct master *master, time_t age, int readall)
 {
-	int status;
-
 	if (!lookup_nss_read_master(master, age)) {
 		error(LOGOPT_ANY,
 		      "can't read master map %s", master->name);
@@ -842,7 +829,6 @@ void master_notify_state_change(struct m
 	struct autofs_point *ap;
 	struct list_head *p;
 	int state_pipe;
-	int status;
 
 	master_mutex_lock();
 
@@ -862,8 +848,7 @@ void master_notify_state_change(struct m
 
 		switch (sig) {
 		case SIGTERM:
-			if (ap->state != ST_SHUTDOWN &&
-			    ap->state != ST_SHUTDOWN_PENDING &&
+			if (ap->state != ST_SHUTDOWN_PENDING &&
 			    ap->state != ST_SHUTDOWN_FORCE) {
 				next = ST_SHUTDOWN_PENDING;
 				nextstate(state_pipe, next);
@@ -871,8 +856,7 @@ void master_notify_state_change(struct m
 			break;
 #ifdef ENABLE_FORCED_SHUTDOWN
 		case SIGUSR2:
-			if (ap->state != ST_SHUTDOWN &&
-			    ap->state != ST_SHUTDOWN_FORCE &&
+			if (ap->state != ST_SHUTDOWN_FORCE &&
 			    ap->state != ST_SHUTDOWN_PENDING) {
 				next = ST_SHUTDOWN_FORCE;
 				nextstate(state_pipe, next);
@@ -950,7 +934,7 @@ static int master_do_mount(struct master
 
 static void shutdown_entry(struct master_mapent *entry)
 {
-	int status, state_pipe;
+	int state_pipe;
 	struct autofs_point *ap;
 	struct stat st;
 	int ret;
@@ -977,7 +961,7 @@ next:
 static void check_update_map_sources(struct master_mapent *entry, int readall)
 {
 	struct map_source *source, *last;
-	int status, state_pipe, map_stale = 0;
+	int state_pipe, map_stale = 0;
 	struct autofs_point *ap;
 	struct stat st;
 	int ret;
@@ -1053,7 +1037,6 @@ static void check_update_map_sources(str
 int master_mount_mounts(struct master *master, time_t age, int readall)
 {
 	struct list_head *p, *head;
-	int status;
 
 	master_mutex_lock();
 
@@ -1104,14 +1087,11 @@ int master_mount_mounts(struct master *m
 
 int master_list_empty(struct master *master)
 {
-	int status;
 	int res = 0;
 
 	master_mutex_lock();
-
 	if (list_empty(&master->mounts))
 		res = 1;
-
 	master_mutex_unlock();
 
 	return res;
diff --git a/lib/mounts.c b/lib/mounts.c
index b11c4c7..f446a6a 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -112,7 +112,6 @@ struct mnt_list *get_mnt_list(const char
 	struct mntent *mnt;
 	struct mnt_list *ent, *mptr, *last;
 	struct mnt_list *list = NULL;
-	unsigned long count = 0;
 	char *pgrp;
 	size_t len;
 
@@ -126,7 +125,7 @@ struct mnt_list *get_mnt_list(const char
 		return NULL;
 	}
 
-	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX)) != NULL) {
+	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
 		len = strlen(mnt->mnt_dir);
 
 		if ((!include && len <= pathlen) ||
@@ -198,9 +197,6 @@ struct mnt_list *get_mnt_list(const char
 				*end = '\0';
 			sscanf(pgrp, "pgrp=%d", &ent->owner);
 		}
-
-		if (count++ % 100)
-			sched_yield();
 	}
 	endmntent(tab);
 
@@ -258,7 +254,7 @@ int is_mounted(const char *table, const 
 {
 	struct mntent *mnt;
 	struct mntent mnt_wrk;
-	char buf[PATH_MAX];
+	char buf[PATH_MAX * 3];
 	size_t pathlen = strlen(path);
 	FILE *tab;
 	int ret = 0;
@@ -273,7 +269,7 @@ int is_mounted(const char *table, const 
 		return 0;
 	}
 
-	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX))) {
+	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
 		size_t len = strlen(mnt->mnt_dir);
 
 		if (type) {
@@ -304,7 +300,7 @@ int has_fstab_option(const char *opt)
 {
 	struct mntent *mnt;
 	struct mntent mnt_wrk;
-	char buf[PATH_MAX];
+	char buf[PATH_MAX * 3];
 	FILE *tab;
 	int ret = 0;
 
@@ -318,7 +314,7 @@ int has_fstab_option(const char *opt)
 		return 0;
 	}
 
-	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX))) {
+	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
 		if (hasmntopt(mnt, opt)) {
 			ret = 1;
 			break;
@@ -333,7 +329,7 @@ char *find_mnt_ino(const char *table, de
 {
 	struct mntent mnt_wrk;
 	struct mntent *mnt;
-	char buf[PATH_MAX];
+	char buf[PATH_MAX * 3];
 	char *path = NULL;
 	unsigned long l_dev = (unsigned long) dev;
 	unsigned long l_ino = (unsigned long) ino;
@@ -346,7 +342,7 @@ char *find_mnt_ino(const char *table, de
 		return 0;
 	}
 
-	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX))) {
+	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
 		char *p_dev, *p_ino;
 		unsigned long m_dev, m_ino;
 
@@ -542,7 +538,7 @@ struct mnt_list *tree_make_mnt_tree(cons
 
 	plen = strlen(path);
 
-	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX))) {
+	while ((mnt = getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
 		size_t len = strlen(mnt->mnt_dir);
 
 		/* Not matching path */
@@ -563,6 +559,7 @@ struct mnt_list *tree_make_mnt_tree(cons
 
 		INIT_LIST_HEAD(&ent->self);
 		INIT_LIST_HEAD(&ent->list);
+		INIT_LIST_HEAD(&ent->sublist);
 		INIT_LIST_HEAD(&ent->ordered);
 
 		ent->path = malloc(len + 1);
@@ -700,6 +697,53 @@ skip:
 	return 1;
 }
 
+/*
+ * Get list of mounts under "path" in longest->shortest order
+ */
+int tree_get_mnt_sublist(struct mnt_list *mnts, struct list_head *list, const char *path, int include)
+{
+	size_t mlen, plen;
+
+	if (!mnts)
+		return 0;
+
+	plen = strlen(path);
+	mlen = strlen(mnts->path);
+	if (mlen < plen)
+		return tree_get_mnt_sublist(mnts->right, list, path, include);
+	else {
+		struct list_head *self, *p;
+
+		tree_get_mnt_sublist(mnts->left, list, path, include);
+
+		if ((!include && mlen <= plen) ||
+				strncmp(mnts->path, path, plen))
+			goto skip;
+
+		if (plen > 1 && mlen > plen && mnts->path[plen] != '/')
+			goto skip;
+
+		INIT_LIST_HEAD(&mnts->sublist);
+		list_add(&mnts->sublist, list);
+
+		self = &mnts->self;
+		list_for_each(p, self) {
+			struct mnt_list *this;
+
+			this = list_entry(p, struct mnt_list, self);
+			INIT_LIST_HEAD(&this->sublist);
+			list_add(&this->sublist, list);
+		}
+skip:
+		tree_get_mnt_sublist(mnts->right, list, path, include);
+	}
+
+	if (list_empty(list))
+		return 0;
+
+	return 1;
+}
+
 int tree_find_mnt_ents(struct mnt_list *mnts, struct list_head *list, const char *path)
 {
 	int mlen, plen;
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index 5847eb0..6fb9895 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -16,6 +16,12 @@
  * ----------------------------------------------------------------------- */
 
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/vfs.h>
 #include "automount.h"
 
 /*
@@ -265,3 +271,214 @@ char *sanitize_path(const char *path, in
 	return s_path;
 }
 
+int umount_ent(struct autofs_point *ap, const char *path)
+{
+	struct stat st;
+	struct statfs fs;
+	int sav_errno;
+	int status, is_smbfs = 0;
+	int ret, rv = 1;
+
+	ret = statfs(path, &fs);
+	if (ret == -1) {
+		warn(ap->logopt, "could not stat fs of %s", path);
+		is_smbfs = 0;
+	} else {
+		int cifsfs = fs.f_type == CIFS_MAGIC_NUMBER;
+		int smbfs = fs.f_type == SMB_SUPER_MAGIC;
+		is_smbfs = (cifsfs | smbfs) ? 1 : 0;
+	}
+
+	status = lstat(path, &st);
+	sav_errno = errno;
+
+	if (status < 0)
+		warn(ap->logopt, "lstat of %s failed with %d", path, status);
+
+	/*
+	 * lstat failed and we're an smbfs fs returning an error that is not
+	 * EIO or EBADSLT or the lstat failed so it's a bad path. Return
+	 * a fail.
+	 *
+	 * EIO appears to correspond to an smb mount that has gone away
+	 * and EBADSLT relates to CD changer not responding.
+	 */
+	if (!status && (S_ISDIR(st.st_mode) && st.st_dev != ap->dev)) {
+		rv = spawnll(log_debug, PATH_UMOUNT, PATH_UMOUNT, path, NULL);
+	} else if (is_smbfs && (sav_errno == EIO || sav_errno == EBADSLT)) {
+		rv = spawnll(log_debug, PATH_UMOUNT, PATH_UMOUNT, path, NULL);
+	}
+
+	/* We are doing a forced shutcwdown down so unlink busy mounts */
+	if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
+		ret = stat(path, &st);
+		if (ret == -1 && errno == ENOENT) {
+			warn(ap->logopt, "mount point does not exist");
+			return 0;
+		}
+
+		if (ret == 0 && !S_ISDIR(st.st_mode)) {
+			warn(ap->logopt, "mount point is not a directory");
+			return 0;
+		}
+
+		if (ap->state == ST_SHUTDOWN_FORCE) {
+			msg("forcing umount of %s", path);
+			rv = spawnll(log_debug, PATH_UMOUNT, PATH_UMOUNT, "-l", path, NULL);
+		}
+
+		/*
+		 * Verify that we actually unmounted the thing.  This is a
+		 * belt and suspenders approach to not eating user data.
+		 * We have seen cases where umount succeeds, but there is
+		 * still a file system mounted on the mount point.  How
+		 * this happens has not yet been determined, but we want to
+		 * make sure to return failure here, if that is the case,
+		 * so that we do not try to call rmdir_path on the
+		 * directory.
+		 */
+		if (!rv && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
+			crit(ap->logopt,
+			     "the umount binary reported that %s was "
+			     "unmounted, but there is still something "
+			     "mounted on this path.", path);
+			rv = -1;
+		}
+	}
+
+	return rv;
+}
+
+int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
+{
+	char path[PATH_MAX + 1];
+	char *offset = path;
+	struct mapent *oe;
+	struct list_head *pos = NULL;
+	unsigned int fs_path_len;
+	struct statfs fs;
+	struct stat st;
+	unsigned int is_autofs_fs;
+	int ret, start;
+
+	fs_path_len = strlen(root) + strlen(base);
+	if (fs_path_len > PATH_MAX)
+		return 0;
+
+	strcpy(path, root);
+	strcat(path, base);
+	ret = statfs(path, &fs);
+	if (ret == -1) {
+		/* There's no mount yet - it must be autofs */
+		if (errno == ENOENT)
+			is_autofs_fs = 1;
+		else
+			return 0;
+	} else
+		is_autofs_fs = fs.f_type == AUTOFS_SUPER_MAGIC ? 1 : 0;
+
+	start = strlen(root);
+	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
+	while (offset) {
+		int plen = fs_path_len + strlen(offset);
+
+		if (plen > PATH_MAX) {
+			warn(ap->logopt, "path loo long");
+			goto cont;
+		}
+
+		oe = cache_lookup_offset(base, offset, start, &me->multi_list);
+		if (!oe)
+			goto cont;
+
+		/*
+		 * If the host filesystem is not an autofs fs
+		 * we require the mount point directory exist
+		 * and that permissions are OK.
+		 */
+		if (!is_autofs_fs) {
+			ret = stat(oe->key, &st);
+			if (ret == -1)
+				goto cont;
+		}
+
+		debug(ap->logopt, "mount offset %s", oe->key);
+
+		if (mount_autofs_offset(ap, oe, is_autofs_fs) < 0)
+			warn(ap->logopt, "failed to mount offset");
+cont:
+		offset = cache_get_offset(base,
+				offset, start, &me->multi_list, &pos);
+	}
+
+	return 1;
+}
+
+int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
+{
+	char path[PATH_MAX + 1];
+	char *offset = path;
+	struct mapent *oe;
+	struct list_head *mm_root, *pos = NULL;
+	const char o_root[] = "/";
+	const char *mm_base;
+	int left, start;
+
+	left = 0;
+	start = strlen(root);
+
+	mm_root = &me->multi->multi_list;
+
+	if (!base)
+		mm_base = o_root;
+	else
+		mm_base = base;
+
+	offset = cache_get_offset(mm_base, offset, start, mm_root, &pos);
+	while (offset) {
+		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+		/* root offset is a special case */
+		if (!oe || (strlen(oe->key) - start) == 1)
+			goto cont;
+
+		debug(ap->logopt, "umount offset %s", oe->key);
+
+		if (umount_autofs_offset(ap, oe)) {
+			warn(ap->logopt, "failed to umount offset");
+			left++;
+		}
+cont:
+		offset = cache_get_offset(mm_base,
+				offset, start, &me->multi_list, &pos);
+	}
+
+	if (!left && me->multi == me) {
+		struct mapent_cache *mc = me->source->mc;
+		int status;
+
+		/*
+		 * Special case.
+		 * If we can't umount the root container then we can't
+		 * delete the offsets from the cache and we need to put
+		 * the offset triggers back.
+		 */
+		if (is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
+			if (umount_ent(ap, root)) {
+				if (!mount_multi_triggers(ap, root, me, "/"))
+					warn(ap->logopt,
+					     "failed to remount offset triggers");
+				return left++;
+			}
+		}
+
+		/* We're done - clean out the offsets */
+		cache_multi_lock(mc);
+		status = cache_delete_offset_list(mc, me->key);
+		cache_multi_unlock(mc);
+		if (status != CHE_OK)
+			warn(ap->logopt, "couldn't delete offset list");
+	}
+
+	return left;
+}
+
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 1a3ee13..376da2e 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -113,7 +113,7 @@ int lookup_init(const char *mapfmt, int 
 	return 0;
 }
 
-static int read_one(FILE *f, char *key, unsigned *k_len, char *mapent, unsigned *m_len)
+static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsigned int *m_len)
 {
 	char *kptr, *p;
 	int mapent_len, key_len;
@@ -346,7 +346,8 @@ int lookup_read_master(struct master *ma
 	char *ent;
 	struct stat st;
 	FILE *f;
-	int entry, path_len, ent_len;
+	unsigned int path_len, ent_len;
+	int entry;
 
 	if (master->recurse)
 		return NSS_STATUS_UNAVAIL;
@@ -593,7 +594,8 @@ int lookup_read_map(struct autofs_point 
 	char *mapent;
 	struct stat st;
 	FILE *f;
-	int entry, k_len, m_len;
+	unsigned int k_len, m_len;
+	int entry;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
@@ -720,7 +722,8 @@ static int lookup_one(struct autofs_poin
 	char mapent[MAPENT_MAX_LEN + 1];
 	time_t age = time(NULL);
 	FILE *f;
-	int entry, ret, k_len, m_len;
+	unsigned int k_len, m_len;
+	int entry, ret;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
@@ -817,7 +820,8 @@ static int lookup_wild(struct autofs_poi
 	char mapent[MAPENT_MAX_LEN + 1];
 	time_t age = time(NULL);
 	FILE *f;
-	int entry, ret, k_len, m_len;
+	unsigned int k_len, m_len;
+	int entry, ret;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 8c627b4..4959c12 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1146,9 +1146,9 @@ static int read_one_map(struct autofs_po
 
 	while (e) {
 		char *mapent = NULL;
+		size_t mapent_len = 0;
 		char *k_val;
 		ber_len_t k_len;
-		size_t mapent_len;
 		char *s_key;
 
 		bvKey = ldap_get_values_len(ldap, e, entry);
@@ -1388,10 +1388,10 @@ static int lookup_one(struct autofs_poin
 
 	while (e) {
 		char *mapent = NULL;
+		size_t mapent_len = 0;
 		char *k_val;
 		ber_len_t k_len;
 		char *s_key;
-		size_t mapent_len;
 
 		bvKey = ldap_get_values_len(ldap, e, entry);
 		if (!bvKey || !*bvKey) {
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index dec4a21..483e586 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -248,7 +248,7 @@ int yp_all_callback(int status, char *yp
 	struct map_source *source = cbdata->source;
 	struct mapent_cache *mc = source->mc;
 	time_t age = cbdata->age;
-	char *tmp, *key, *mapent;
+	char *key, *mapent;
 	int ret;
 
 	if (status != YP_TRUE)
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 9bccdd1..c9baf57 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -59,7 +59,6 @@ int mount_mount(struct autofs_point *ap,
 	char buf[MAX_ERR_BUF];
 	char *options, *p;
 	int ret;
-	struct list_head *l;
 
 	fullpath = alloca(strlen(root) + name_len + 2);
 	if (!fullpath) {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 6007828..0f2c3ab 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -661,71 +661,6 @@ add_offset_entry(struct autofs_point *ap
 	return ret;
 }
 
-static int mount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
-{
-	char path[PATH_MAX + 1];
-	char *offset = path;
-	struct mapent *oe;
-	struct list_head *pos = NULL;
-	unsigned int fs_path_len;
-	struct statfs fs;
-	struct stat st;
-	unsigned int is_autofs_fs;
-	int ret, start;
-
-	fs_path_len = strlen(root) + strlen(base);
-	if (fs_path_len > PATH_MAX)
-		return 0;
-
-	strcpy(path, root);
-	strcat(path, base);
-	ret = statfs(path, &fs);
-	if (ret == -1) {
-		/* There's no mount yet - it must be autofs */
-		if (errno == ENOENT)
-			is_autofs_fs = 1;
-		else
-			return 0;
-	} else
-		is_autofs_fs = fs.f_type == AUTOFS_SUPER_MAGIC ? 1 : 0;
-
-	start = strlen(root);
-	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
-	while (offset) {
-		int plen = fs_path_len + strlen(offset);
-
-		if (plen > PATH_MAX) {
-			warn(ap->logopt, MODPREFIX "path loo long");
-			goto cont;
-		}
-
-		oe = cache_lookup_offset(base, offset, start, &me->multi_list);
-		if (!oe)
-			goto cont;
-
-		/*
-		 * If the host filesystem is not an autofs fs
-		 * we require the mount point directory exist
-		 * and that permissions are OK.
-		 */
-		if (!is_autofs_fs) {
-			ret = stat(oe->key, &st);
-			if (ret == -1)
-				goto cont;
-		}
-
-		debug(ap->logopt, MODPREFIX "mount offset %s", oe->key);
-
-		if (mount_autofs_offset(ap, oe, is_autofs_fs) < 0)
-			warn(ap->logopt, MODPREFIX "failed to mount offset");
-cont:
-		offset = cache_get_offset(base,
-				offset, start, &me->multi_list, &pos);
-	}
-
-	return 1;
-}
-
 static int validate_location(char *loc)
 {
 	char *ptr = loc;
@@ -762,7 +697,7 @@ static int parse_mapent(const char *ent,
 {
 	char buf[MAX_ERR_BUF];
 	const char *p;
-	char *tmp, *myoptions, *loc;
+	char *myoptions, *loc;
 	int l;
 
 	p = ent;
@@ -1040,7 +975,6 @@ int parse_mount(struct autofs_point *ap,
 		/* It's a multi-mount; deal with it */
 		do {
 			char *path, *myoptions, *loc;
-			unsigned int s_len = 0;
 			int status;
 
 			if (*p != '/') {
@@ -1272,6 +1206,8 @@ int parse_mount(struct autofs_point *ap,
 		free(loc);
 		free(options);
 
+		if (rv)
+			return rv;
 		/*
 		 * If it's a multi-mount insert the triggers
 		 * These are always direct mount triggers so root = ""
