diff --git a/CHANGELOG b/CHANGELOG
index 8e4a8c1..bfc36c8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,6 +31,7 @@
 - allow hostname to start with numeric when validating.
 - fix included map lookup.
 - fix directory cleanup on expire.
+- fix task cancelation at shutdown.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index 14b385c..8195349 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -614,8 +614,12 @@ static int get_pkt(struct autofs_point *
 
 			state_mutex_unlock(ap);
 
-			if (post_state != ST_INVAL)
+			if (post_state != ST_INVAL) {
+				if (post_state == ST_SHUTDOWN_PENDING ||
+				    post_state == ST_SHUTDOWN_FORCE)
+					st_remove_tasks(ap);
 				st_add_task(ap, post_state);
+			}
 
 			if (next_state == ST_SHUTDOWN)
 				return -1;
@@ -1064,7 +1068,6 @@ static void handle_mounts_cleanup(void *
 	/* If we have been canceled then we may hold the state mutex. */
 	mutex_operation_wait(&ap->state_mutex);
 
-	st_remove_tasks(ap);
 	umount_autofs(ap, 1);
 
 	master_signal_submount(ap, MASTER_SUBMNT_JOIN);
diff --git a/daemon/direct.c b/daemon/direct.c
index ffb3009..b08cbdd 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -761,6 +761,13 @@ static int expire_direct(int ioctlfd, co
 	return (retries >= 0);
 }
 
+static void mnts_cleanup(void *arg)
+{
+	struct mnt_list *mnts = (struct mnt_list *) arg;
+	free_mnt_list(mnts);
+	return;
+}
+
 void *expire_proc_direct(void *arg)
 {
 	struct mnt_list *mnts, *next;
@@ -768,8 +775,8 @@ void *expire_proc_direct(void *arg)
 	struct autofs_point *ap;
 	struct mapent *me = NULL;
 	unsigned int now;
-	int ioctlfd = -1;
-	int status, ret;
+	int ioctlfd, cur_state;
+	int status, ret, left;
 
 	ea = (struct expire_args *) arg;
 
@@ -779,7 +786,7 @@ void *expire_proc_direct(void *arg)
 
 	ap = ea->ap;
 	now = ea->when;
-	ea->status = 0;
+	ea->status = 1;
 
 	ea->signaled = 1;
 	status = pthread_cond_signal(&ea->cond);
@@ -797,18 +804,24 @@ void *expire_proc_direct(void *arg)
 	if (status)
 		fatal(status);
 
+	left = 0;
+
 	/* Get a list of real mounts and expire them if possible */
 	mnts = get_mnt_list(_PROC_MOUNTS, "/", 0);
+	pthread_cleanup_push(mnts_cleanup, mnts);
 	for (next = mnts; next; next = next->next) {
 		if (!strcmp(next->fs_type, "autofs")) {
 			/*
 			 * If we have submounts check if this path lives below
 			 * one of them and pass on state change.
 			 */
+			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 			if (strstr(next->opts, "indirect")) {
 				master_notify_submount(ap, next->path, ap->state);
+				pthread_setcancelstate(cur_state, NULL);
 				continue;
 			}
+			pthread_setcancelstate(cur_state, NULL);
 
 			/* Skip offsets */
 			if (strstr(next->opts, "offset"))
@@ -834,11 +847,15 @@ void *expire_proc_direct(void *arg)
 
 		debug(ap->logopt, "send expire to trigger %s", next->path);
 
+		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 		ret = expire_direct(ioctlfd, next->path, now, ap->logopt);
 		if (!ret)
-			ea->status++;
+			left++;
+		pthread_setcancelstate(cur_state, NULL);
 	}
-	free_mnt_list(mnts);
+	pthread_cleanup_pop(1);
+
+	ea->status = left;
 
 	pthread_cleanup_pop(1);
 
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 729c9de..cff4f1c 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -402,6 +402,13 @@ static int expire_indirect(struct autofs
 	return (retries >= 0);
 }
 
+static void mnts_cleanup(void *arg)
+{
+	struct mnt_list *mnts = (struct mnt_list *) arg;
+	free_mnt_list(mnts);
+	return;
+}
+
 void *expire_proc_indirect(void *arg)
 {
 	struct autofs_point *ap;
@@ -410,8 +417,8 @@ void *expire_proc_indirect(void *arg)
 	struct expire_args *ea;
 	unsigned int now;
 	int offsets, submnts, count;
-	int ioctlfd;
-	int status, ret;
+	int ioctlfd, cur_state;
+	int status, ret, left;
 
 	ea = (struct expire_args *) arg;
 
@@ -421,7 +428,7 @@ void *expire_proc_indirect(void *arg)
 
 	ap = ea->ap;
 	now = ea->when;
-	ea->status = 0;
+	ea->status = 1;
 
 	ea->signaled = 1;
 	status = pthread_cond_signal(&ea->cond);
@@ -439,8 +446,11 @@ void *expire_proc_indirect(void *arg)
 	if (status)
 		fatal(status);
 
+	left = 0;
+
 	/* Get a list of real mounts and expire them if possible */
 	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
+	pthread_cleanup_push(mnts_cleanup, mnts);
 	for (next = mnts; next; next = next->next) {
 		char *ind_key;
 		int ret;
@@ -450,8 +460,10 @@ void *expire_proc_indirect(void *arg)
 			 * If we have submounts check if this path lives below
 			 * one of them and pass on the state change.
 			 */
+			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 			if (strstr(next->opts, "indirect"))
 				master_notify_submount(ap, next->path, ap->state);
+			pthread_setcancelstate(cur_state, NULL);
 
 			continue;
 		}
@@ -486,11 +498,13 @@ void *expire_proc_indirect(void *arg)
 
 		debug(ap->logopt, "expire %s", next->path);
 
+		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 		ret = expire_indirect(ap, ioctlfd, next->path, now);
 		if (!ret)
-			ea->status++;
+			left++;
+		pthread_setcancelstate(cur_state, NULL);
 	}
-	free_mnt_list(mnts);
+	pthread_cleanup_pop(1);
 
 	/*
 	 * If there are no more real mounts left we could still
@@ -498,13 +512,16 @@ void *expire_proc_indirect(void *arg)
 	 * umount them here.
 	 */
 	if (mnts) {
+		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 		ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
 		if (!ret)
-			ea->status++;
+			left++;
+		pthread_setcancelstate(cur_state, NULL);
 	}
 
 	count = offsets = submnts = 0;
 	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
+	pthread_cleanup_push(mnts_cleanup, mnts);
 	/* Are there any real mounts left */
 	for (next = mnts; next; next = next->next) {
 		if (strcmp(next->fs_type, "autofs"))
@@ -516,7 +533,7 @@ void *expire_proc_indirect(void *arg)
 				offsets++;
 		}
 	}
-	free_mnt_list(mnts);
+	pthread_cleanup_pop(1);
 
 	if (submnts)
 		debug(ap->logopt,
@@ -531,12 +548,12 @@ void *expire_proc_indirect(void *arg)
 
 	/* If we are trying to shutdown make sure we can umount */
 	if (!ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
-		if (!ret) {
+		if (!ret)
 			msg("mount still busy %s", ap->path);
-			ea->status++;
-		}
 	}
 
+	ea->status = left;
+
 	pthread_cleanup_pop(1);
 
 	return NULL;
diff --git a/daemon/lookup.c b/daemon/lookup.c
index dd620cf..dacb678 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -71,6 +71,14 @@ static int check_nss_result(struct nss_s
 	return -1;
 }
 
+static void nsslist_cleanup(void *arg)
+{
+	struct list_head *nsslist = (struct list_head *) arg;
+	if (!list_empty(nsslist))
+		free_sources(nsslist);
+	return;
+}
+
 static int do_read_master(struct master *master, char *type, time_t age)
 {
 	struct lookup_mod *lookup;
@@ -313,6 +321,14 @@ static int read_source_instance(struct a
 	return do_read_map(ap, instance, age);
 }
 
+static void argv_cleanup(void *arg)
+{
+	struct map_source *tmap = (struct map_source *) arg;
+	/* path is freed in free_argv */
+	free_argv(tmap->argc, tmap->argv);
+	return;
+}
+
 static enum nsswitch_status read_map_source(struct nss_source *this,
 		struct autofs_point *ap, struct map_source *map, time_t age)
 {
@@ -380,10 +396,9 @@ static enum nsswitch_status read_map_sou
 		return NSS_STATUS_UNKNOWN;
 	}
 
+	pthread_cleanup_push(argv_cleanup, &tmap);
 	result = read_file_source_instance(ap, &tmap, age);
-
-	/* path is freed in free_argv */
-	free_argv(tmap.argc, tmap.argv);
+	pthread_cleanup_pop(1);
 
 	return result;
 }
@@ -413,8 +428,6 @@ int lookup_nss_read_map(struct autofs_po
 			continue;
 		}
 
-		sched_yield();
-
 		if (map->type) {
 			debug(ap->logopt,
 			      "reading map %s %s", map->type, map->argv[0]);
@@ -446,7 +459,9 @@ int lookup_nss_read_map(struct autofs_po
 
 		INIT_LIST_HEAD(&nsslist);
 
+		pthread_cleanup_push(nsslist_cleanup, &nsslist);
 		status = nsswitch_parse(&nsslist);
+		pthread_cleanup_pop(0);
 		if (status) {
 			error(ap->logopt,
 			      "can't to read name service switch config.");
@@ -454,6 +469,7 @@ int lookup_nss_read_map(struct autofs_po
 			break;
 		}
 
+		pthread_cleanup_push(nsslist_cleanup, &nsslist);
 		head = &nsslist;
 		list_for_each(p, head) {
 			this = list_entry(p, struct nss_source, list);
@@ -472,9 +488,7 @@ int lookup_nss_read_map(struct autofs_po
 				break;
 			}
 		}
-
-		if (!list_empty(&nsslist))
-			free_sources(&nsslist);
+		pthread_cleanup_pop(1);
 
 		if (!map)
 			break;
@@ -876,6 +890,7 @@ int lookup_prune_cache(struct autofs_poi
 	char *path;
 	int status = CHE_FAIL;
 
+	pthread_cleanup_push(master_source_lock_cleanup, entry);
 	master_source_readlock(entry);
 
 	map = entry->first;
@@ -885,6 +900,7 @@ int lookup_prune_cache(struct autofs_poi
 			continue;
 		}
 		mc = map->mc;
+		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_readlock(mc);
 		me = cache_enumerate(mc, NULL);
 		while (me) {
@@ -958,12 +974,12 @@ next:
 			free(path);
 			free(next_key);
 		}
-		cache_unlock(mc);
+		pthread_cleanup_pop(1);
 		map->stale = 0;
 		map = map->next;
 	}
 
-	master_source_unlock(entry);
+	pthread_cleanup_pop(1);
 
 	return 1;
 }
@@ -976,7 +992,6 @@ struct mapent *lookup_source_valid_mapen
 	struct mapent_cache *mc;
 	struct mapent *me = NULL;
 
-	pthread_cleanup_push(master_source_lock_cleanup, entry);
 	master_source_readlock(entry);
 	map = entry->first;
 	while (map) {
@@ -1000,7 +1015,7 @@ struct mapent *lookup_source_valid_mapen
 		cache_unlock(mc);
 		map = map->next;
 	}
-	pthread_cleanup_pop(1);
+	master_source_unlock(entry);
 
 	return me;
 }
@@ -1013,7 +1028,6 @@ struct mapent *lookup_source_mapent(stru
 	struct mapent_cache *mc;
 	struct mapent *me = NULL;
 
-	pthread_cleanup_push(master_source_lock_cleanup, entry);
 	master_source_readlock(entry);
 	map = entry->first;
 	while (map) {
@@ -1028,7 +1042,7 @@ struct mapent *lookup_source_mapent(stru
 		cache_unlock(mc);
 		map = map->next;
 	}
-	pthread_cleanup_pop(1);
+	master_source_unlock(entry);
 
 	return me;
 }
diff --git a/daemon/state.c b/daemon/state.c
index d38a64f..47fee39 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -30,15 +30,11 @@ struct state_queue {
 
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static unsigned int signaled = 0;
 static LIST_HEAD(state_queue);
 
-static unsigned int signaled = 0;
 static void st_set_thid(struct autofs_point *, pthread_t);
 
-static pthread_mutex_t task_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t task_cond = PTHREAD_COND_INITIALIZER;
-static unsigned int task_signaled;
-
 #define st_mutex_lock() \
 do { \
 	int status = pthread_mutex_lock(&mutex); \
@@ -53,20 +49,6 @@ do { \
 		fatal(status); \
 } while (0)
 
-#define task_mutex_lock() \
-do { \
-	int status = pthread_mutex_lock(&task_mutex); \
-	if (status) \
-		fatal(status); \
-} while (0)
-
-#define task_mutex_unlock() \
-do { \
-	int status = pthread_mutex_unlock(&task_mutex); \
-	if (status) \
-		fatal(status); \
-} while (0)
-
 int do_mount_autofs_direct(struct autofs_point *, struct mnt_list *, struct mapent *);
 
 void dump_state_queue(void)
@@ -116,12 +98,14 @@ void expire_cleanup(void *arg)
 	struct autofs_point *ap;
 	int statefd;
 	enum states next = ST_INVAL;
-	int success, ret;
+	int success, ret, cur_state;
 
 	ea = (struct expire_args *) arg;
 	ap = ea->ap;
 	success = ea->status;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
+
 	state_mutex_lock(ap);
 
 	debug(ap->logopt,
@@ -195,6 +179,8 @@ #endif
 
 	free(ea);
 
+	pthread_setcancelstate(cur_state, NULL);
+
 	return;
 }
 
@@ -333,13 +319,20 @@ static void do_readmap_cleanup(void *arg
 	return;
 }
 
+static void tree_mnts_cleanup(void *arg)
+{
+	struct mnt_list *mnts = (struct mnt_list *) arg;
+	tree_free_mnt_tree(mnts);
+	return;
+}
+
 static void *do_readmap(void *arg)
 {
 	struct autofs_point *ap;
 	struct map_source *map;
 	struct mapent_cache *mc;
 	struct readmap_args *ra;
-	struct  mnt_list *mnts;
+	struct mnt_list *mnts;
 	int status;
 	time_t now;
 
@@ -378,6 +371,7 @@ static void *do_readmap(void *arg)
 	} else {
 		struct mapent *me;
 		mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
+		pthread_cleanup_push(tree_mnts_cleanup, mnts);
 		pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
 		master_source_readlock(ap->entry);
 		map = ap->entry->first;
@@ -406,7 +400,7 @@ static void *do_readmap(void *arg)
 			pthread_cleanup_pop(1);
 			map = map->next;
 		}
-		tree_free_mnt_tree(mnts);
+		pthread_cleanup_pop(1);
 		pthread_cleanup_pop(1);
 		lookup_prune_cache(ap, now);
 	}
@@ -617,12 +611,10 @@ int st_add_task(struct autofs_point *ap,
 	unsigned int empty = 1;
 	int status;
 
-	state_mutex_lock(ap);
-
 	/* Task termination marker, poke state machine */
 	if (state == ST_READY) {
+		state_mutex_lock(ap);
 		st_ready(ap);
-
 		state_mutex_unlock(ap);
 
 		st_mutex_lock();
@@ -637,11 +629,11 @@ int st_add_task(struct autofs_point *ap,
 		return 1;
 	}
 
+	state_mutex_lock(ap);
 	if (ap->state == ST_SHUTDOWN) {
 		state_mutex_unlock(ap);
 		return 1;
 	}
-
 	state_mutex_unlock(ap);
 
 	new = malloc(sizeof(struct state_queue));
@@ -710,8 +702,13 @@ void st_remove_tasks(struct autofs_point
 		if (task->ap != ap)
 			continue;
 
-		if (task->busy)
-			task->cancel = 1;
+		if (task->busy) {
+			/* We only cancel readmap, prune and expire */
+			if (task->state == ST_EXPIRE ||
+			    task->state == ST_PRUNE ||
+			    task->state == ST_READMAP)
+				task->cancel = 1;
+		}
 
 		q = (&task->pending)->next;
 		while(q != &task->pending) {
@@ -734,27 +731,15 @@ void st_remove_tasks(struct autofs_point
 
 }
 
-static void *do_run_task(void *arg)
+static int run_state_task(struct state_queue *task)
 {
-	struct state_queue *task;
 	struct autofs_point *ap;
 	enum states next_state, state;
 	unsigned long ret = 1;
-	int status;
  
-	task_mutex_lock();
-
-	task = (struct state_queue *) arg;
 	ap = task->ap;
 	next_state = task->state;
 
-	task_signaled = 1;
-	status = pthread_cond_signal(&task_cond);
-	if (status)
-		fatal(status);
-
-	task_mutex_unlock();
-
 	state_mutex_lock(ap);
 
 	state = ap->state;
@@ -789,33 +774,7 @@ static void *do_run_task(void *arg)
 
 	state_mutex_unlock(ap);
 
-	return (void *) ret;
-}
-
-static int run_state_task(struct state_queue *task)
-{
-	pthread_t thid;
-	int status;
-
-	task_mutex_lock();
-
-	status = pthread_create(&thid, &thread_attr, do_run_task, task);
-	if (status) {
-		error(task->ap->logopt, "error running task");
-		task_mutex_unlock();
-		return 0;
-	}
-
-	task_signaled = 0;
-	while (!task_signaled) {
-		status = pthread_cond_wait(&task_cond, &task_mutex);
-		if (status)
-			fatal(status);
-	}
-
-	task_mutex_unlock();
-
-	return 1;
+	return ret;
 }
 
 static void st_set_thid(struct autofs_point *ap, pthread_t thid)
@@ -838,12 +797,10 @@ static void *st_queue_handler(void *arg)
 	struct list_head *head;
 	struct list_head *p;
 	struct timespec wait;
-	int status;
+	int status, ret;
 
 	st_mutex_lock();
 
-	head = &state_queue;
-
 	while (1) {
 		/*
 		 * If the state queue list is empty, wait until an
@@ -862,24 +819,25 @@ static void *st_queue_handler(void *arg)
 			}
 		}
 
-		list_for_each(p, head) {
+		p = head->next;
+		while(p != head) {
 			struct state_queue *task;
 
 			task = list_entry(p, struct state_queue, list);
+			p = p->next;
 /*
 			debug(LOGOPT_NONE,
 			      "task %p ap %p state %d next %d busy %d",
 			      task, task->ap, task->ap->state,
 			      task->state, task->busy);
 */
-
 			task->busy = 1;
-			/*
-			 * TODO: field return code and delete immediately
-			 * 	 on fail
-			 */
-			/* TODO: field return code and delete immediately on fail */
-			run_state_task(task);
+
+			ret = run_state_task(task);
+			if (!ret) {
+				list_del(&task->list);
+				free(task);
+			}
 		}
 
 		while (1) {
@@ -912,24 +870,30 @@ static void *st_queue_handler(void *arg)
 				if (!task->busy) {
 					/* Start a new task */
 					task->busy = 1;
-					/*
-					 * TODO: field return code and delete
-					 *	 immediately on fail
-					 */
-					run_state_task(task);
+
+					ret = run_state_task(task);
+					if (!ret)
+						goto remove;
 					continue;
 				}
-/*
-				if (task->thid && task->cancel)
+
+				/* Still starting up */
+				if (!task->thid)
+					continue;
+
+				if (task->cancel) {
 					pthread_cancel(task->thid);
-*/
+					task->cancel = 0;
+					continue;
+				}
+
 				/* Still busy */
 				if (task->thid) {
 					status = pthread_kill(task->thid, 0);
 					if (status != ESRCH)
 						continue;
 				}
-
+remove:
 				/* No more tasks for this queue */
 				if (list_empty(&task->pending)) {
 					list_del(&task->list);
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 47a208b..028c1ec 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -67,31 +67,31 @@ int lookup_init(const char *mapfmt, int 
 	}
 
 	if (argc < 1) {
-		crit(LOGOPT_ANY, MODPREFIX "No map name");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "No map name");
 		return 1;
 	}
 
 	ctxt->mapname = argv[0];
 
 	if (ctxt->mapname[0] != '/') {
-		msg(MODPREFIX "file map %s is not an absolute pathname",
-		    ctxt->mapname);
 		free(ctxt);
+		msg(MODPREFIX "file map %s is not an absolute pathname",
+		    argv[0]);
 		return 1;
 	}
 
 	if (access(ctxt->mapname, R_OK)) {
-		msg(MODPREFIX "file map %s missing or not readable",
-		    ctxt->mapname);
 		free(ctxt);
+		msg(MODPREFIX "file map %s missing or not readable",
+		    argv[0]);
 		return 1;
 	}
 
 	if (stat(ctxt->mapname, &st)) {
-		crit(LOGOPT_ANY, MODPREFIX "file map %s, could not stat",
-		     ctxt->mapname);
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "file map %s, could not stat",
+		     argv[0]);
 		return 1;
 	}
 		
@@ -102,8 +102,8 @@ int lookup_init(const char *mapfmt, int 
 
 	ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
 	if (!ctxt->parse) {
-		crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
 		return 1;
 	}
 	*context = ctxt;
@@ -345,7 +345,7 @@ int lookup_read_master(struct master *ma
 	struct stat st;
 	FILE *f;
 	unsigned int path_len, ent_len;
-	int entry;
+	int entry, cur_state;
 
 	if (master->recurse)
 		return NSS_STATUS_UNAVAIL;
@@ -357,18 +357,17 @@ int lookup_read_master(struct master *ma
 		return NSS_STATUS_UNAVAIL;
 	}
 
-	path = malloc(KEY_MAX_LEN + 1);
+	path = alloca(KEY_MAX_LEN + 1);
 	if (!path) {
 		error(LOGOPT_ANY,
 		      MODPREFIX "could not malloc storage for path");
 		return NSS_STATUS_UNAVAIL;
 	}
 
-	ent = malloc(MAPENT_MAX_LEN + 1);
+	ent = alloca(MAPENT_MAX_LEN + 1);
 	if (!ent) {
 		error(LOGOPT_ANY,
 		      MODPREFIX "could not malloc storage for mapent");
-		free(path);
 		return NSS_STATUS_UNAVAIL;
 	}
 
@@ -377,8 +376,6 @@ int lookup_read_master(struct master *ma
 		error(LOGOPT_ANY,
 		      MODPREFIX "could not open master map file %s",
 		      ctxt->mapname);
-		free(path);
-		free(ent);
 		return NSS_STATUS_UNAVAIL;
 	}
 
@@ -425,8 +422,6 @@ int lookup_read_master(struct master *ma
 			if (!buffer) {
 				error(LOGOPT_ANY,
 				      MODPREFIX "could not malloc parse buffer");
-				free(path);
-				free(ent);
 				return NSS_STATUS_UNAVAIL;
 			}
 			memset(buffer, 0, blen);
@@ -435,9 +430,10 @@ int lookup_read_master(struct master *ma
 			strcat(buffer, " ");
 			strcat(buffer, ent);
 
+			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 			master_parse_entry(buffer, timeout, logging, age);
-
 			free(buffer);
+			pthread_setcancelstate(cur_state, NULL);
 		}
 
 		if (feof(f))
@@ -447,17 +443,12 @@ int lookup_read_master(struct master *ma
 	if (fstat(fileno(f), &st)) {
 		crit(LOGOPT_ANY, MODPREFIX "file map %s, could not stat",
 		       ctxt->mapname);
-		free(path);
-		free(ent);
 		return NSS_STATUS_UNAVAIL;
 	}
 	ctxt->mtime = st.st_mtime;
 
 	fclose(f);
 
-	free(path);
-	free(ent);
-
 	return NSS_STATUS_SUCCESS;
 }
 
@@ -515,9 +506,9 @@ prepare_plus_include(struct autofs_point
 
 	ret = master_add_autofs_point(entry, timeout, logopt, ghost, 0);
 	if (!ret) {
+		master_free_mapent(entry);
 		error(ap->logopt,
 		      MODPREFIX "failed to add autofs_point to entry");
-		master_free_mapent(entry);
 		return NULL;
 	}
 	iap = entry->ap;
@@ -536,8 +527,8 @@ prepare_plus_include(struct autofs_point
 	/* skip plus */
 	buf = strdup(key + 1);
 	if (!buf) {
-		error(ap->logopt, MODPREFIX "failed to strdup key");
 		master_free_mapent(entry);
+		error(ap->logopt, MODPREFIX "failed to strdup key");
 		return NULL;
 	}
 
@@ -569,9 +560,9 @@ prepare_plus_include(struct autofs_point
 
 	source = master_add_map_source(entry, type, fmt, age, argc, argv);
 	if (!source) {
-		error(ap->logopt, "failed to creat map_source");
 		master_free_mapent(entry);
 		free(buf);
+		error(ap->logopt, "failed to creat map_source");
 		return NULL;
 	}
 	source->mc = current->mc;
@@ -611,18 +602,17 @@ int lookup_read_map(struct autofs_point 
 		return NSS_STATUS_UNAVAIL;
 	}
 
-	key = malloc(KEY_MAX_LEN + 1);
+	key = alloca(KEY_MAX_LEN + 1);
 	if (!key) {
 		error(ap->logopt,
 		      MODPREFIX "could not malloc storage for key");
 		return NSS_STATUS_UNAVAIL;
 	}
 
-	mapent = malloc(MAPENT_MAX_LEN + 1);
+	mapent = alloca(MAPENT_MAX_LEN + 1);
 	if (!mapent) {
 		error(ap->logopt,
 		      MODPREFIX "could not malloc storage for mapent");
-		free(key);
 		return NSS_STATUS_UNAVAIL;
 	}
 
@@ -630,8 +620,6 @@ int lookup_read_map(struct autofs_point 
 	if (!f) {
 		error(ap->logopt,
 		      MODPREFIX "could not open map file %s", ctxt->mapname);
-		free(key);
-		free(mapent);
 		return NSS_STATUS_UNAVAIL;
 	}
 
@@ -696,8 +684,6 @@ int lookup_read_map(struct autofs_point 
 		crit(ap->logopt,
 		     MODPREFIX "file map %s, could not stat",
 		     ctxt->mapname);
-		free(key);
-		free(mapent);
 		return NSS_STATUS_UNAVAIL;
 	}
 	ctxt->mtime = st.st_mtime;
@@ -705,9 +691,6 @@ int lookup_read_map(struct autofs_point 
 
 	fclose(f);
 
-	free(key);
-	free(mapent);
-
 	return NSS_STATUS_SUCCESS;
 }
 
@@ -793,11 +776,12 @@ static int lookup_one(struct autofs_poin
 
 				free(s_key);
 
-				fclose(f);
 				cache_writelock(mc);
 				ret = cache_update(mc, key, mapent, age);
 				cache_unlock(mc);
 
+				fclose(f);
+
 				return ret;
 			}
 		}
@@ -876,10 +860,12 @@ static int lookup_wild(struct autofs_poi
 				if (eq == 0)
 					continue;
 
-				fclose(f);
 				cache_writelock(mc);
 				ret = cache_update(mc, "*", mapent, age);
 				cache_unlock(mc);
+
+				fclose(f);
+
 				return ret;
 			}
 		}
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 855cb95..c0ced9e 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -1280,16 +1280,19 @@ int lookup_read_map(struct autofs_point 
 {
 	struct lookup_context *ctxt = (struct lookup_context *) context;
 	int rv = LDAP_SUCCESS;
-	int ret;
+	int ret, cur_state;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	ret = read_one_map(ap, ctxt, age, &rv);
 	if (ret != NSS_STATUS_SUCCESS) {
 		switch (rv) {
 		case LDAP_SIZELIMIT_EXCEEDED:
 		case LDAP_UNWILLING_TO_PERFORM:
+			pthread_setcancelstate(cur_state, NULL);
 			return NSS_STATUS_UNAVAIL;
 		}
 	}
+	pthread_setcancelstate(cur_state, NULL);
 
 	return ret;
 }
@@ -1507,7 +1510,7 @@ static int check_map_indirect(struct aut
 	struct mapent *me, *exists;
 	time_t now = time(NULL);
 	time_t t_last_read;
-	int ret, need_map = 0;
+	int ret, cur_state, need_map = 0;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
@@ -1524,9 +1527,13 @@ static int check_map_indirect(struct aut
 	master_source_current_wait(ap->entry);
 	ap->entry->current = source;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	ret = lookup_one(ap, key, key_len, ctxt);
-	if (ret == CHE_FAIL)
+	if (ret == CHE_FAIL) {
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_NOTFOUND;
+	}
+	pthread_setcancelstate(cur_state, NULL);
 
 	cache_readlock(mc);
 	me = cache_lookup_first(mc);
@@ -1540,8 +1547,8 @@ static int check_map_indirect(struct aut
 	}
 
 	if (ret == CHE_MISSING) {
-		cache_writelock(mc);
 		pthread_cleanup_push(cache_lock_cleanup, mc);
+		cache_writelock(mc);
 		if (cache_delete(mc, key))
 			rmdir_path(ap, key, ap->dev);
 		pthread_cleanup_pop(1);
@@ -1641,12 +1648,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me) {
-		pthread_cleanup_push(cache_lock_cleanup, mc);
+	if (me && me->mapent) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);
-		pthread_cleanup_pop(0);
 	}
 	cache_unlock(mc);
 
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 500bc53..b0fe4a6 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -46,8 +46,8 @@ int lookup_init(const char *mapfmt, int 
 	}
 
 	if (argc < 1) {
-		crit(LOGOPT_ANY, MODPREFIX "No map name");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "No map name");
 		return 1;
 	}
 	ctxt->mapname = argv[0];
@@ -58,8 +58,8 @@ int lookup_init(const char *mapfmt, int 
 	 */
 	ctxt->domainname = nis_local_directory();
 	if (!ctxt->domainname) {
-		crit(LOGOPT_ANY, MODPREFIX "NIS+ domain not set");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "NIS+ domain not set");
 		return 1;
 	}
 
@@ -68,8 +68,8 @@ int lookup_init(const char *mapfmt, int 
 
 	ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
 	if (!ctxt->parse) {
-		crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
 		return 1;
 	}
 	*context = ctxt;
@@ -89,11 +89,14 @@ int lookup_read_master(struct master *ma
 	char *path, *ent;
 	char *buffer;
 	char buf[MAX_ERR_BUF];
+	int cur_state;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
 	if (!tablename) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_UNAVAIL;
 	}
 	sprintf(tablename, "%s.org_dir.%s", ctxt->mapname, ctxt->domainname);
@@ -104,6 +107,7 @@ int lookup_read_master(struct master *ma
 		nis_freeresult(result);
 		crit(LOGOPT_ANY,
 		     MODPREFIX "couldn't locat nis+ table %s", ctxt->mapname);
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_NOTFOUND;
 	}
 
@@ -114,6 +118,7 @@ int lookup_read_master(struct master *ma
 		nis_freeresult(result);
 		crit(LOGOPT_ANY,
 		     MODPREFIX "couldn't enumrate nis+ map %s", ctxt->mapname);
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_UNAVAIL;
 	}
 
@@ -149,6 +154,7 @@ int lookup_read_master(struct master *ma
 	}
 
 	nis_freeresult(result);
+	pthread_setcancelstate(cur_state, NULL);
 
 	return NSS_STATUS_SUCCESS;
 }
@@ -164,6 +170,7 @@ int lookup_read_map(struct autofs_point 
 	unsigned int current, result_count;
 	char *key, *mapent;
 	char buf[MAX_ERR_BUF];
+	int cur_state;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
@@ -171,10 +178,12 @@ int lookup_read_map(struct autofs_point 
 
 	mc = source->mc;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
 	if (!tablename) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_UNAVAIL;
 	}
 	sprintf(tablename, "%s.org_dir.%s", ctxt->mapname, ctxt->domainname);
@@ -185,6 +194,7 @@ int lookup_read_map(struct autofs_point 
 		nis_freeresult(result);
 		crit(ap->logopt,
 		     MODPREFIX "couldn't locat nis+ table %s", ctxt->mapname);
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_NOTFOUND;
 	}
 
@@ -195,6 +205,7 @@ int lookup_read_map(struct autofs_point 
 		nis_freeresult(result);
 		crit(ap->logopt,
 		     MODPREFIX "couldn't enumrate nis+ map %s", ctxt->mapname);
+		pthread_setcancelstate(cur_state, NULL);
 		return NSS_STATUS_UNAVAIL;
 	}
 
@@ -233,6 +244,8 @@ int lookup_read_map(struct autofs_point 
 
 	source->age = age;
 
+	pthread_setcancelstate(cur_state, NULL);
+
 	return NSS_STATUS_SUCCESS;
 }
 
@@ -247,7 +260,7 @@ static int lookup_one(struct autofs_poin
 	nis_object *this;
 	char *mapent;
 	time_t age = time(NULL);
-	int ret;
+	int ret, cur_state;
 	char buf[MAX_ERR_BUF];
 
 	source = ap->entry->current;
@@ -256,11 +269,13 @@ static int lookup_one(struct autofs_poin
 
 	mc = source->mc;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	tablename = alloca(strlen(key) +
 			strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
 	if (!tablename) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
+		pthread_setcancelstate(cur_state, NULL);
 		return -1;
 	}
 	sprintf(tablename, "[key=%s],%s.org_dir.%s", key, ctxt->mapname,
@@ -269,6 +284,7 @@ static int lookup_one(struct autofs_poin
 	result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 	if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
 		nis_freeresult(result);
+		pthread_setcancelstate(cur_state, NULL);
 		if (result->status == NIS_NOTFOUND ||
 		    result->status == NIS_S_NOTFOUND)
 			return CHE_MISSING;
@@ -284,6 +300,7 @@ static int lookup_one(struct autofs_poin
 	cache_unlock(mc);
 
 	nis_freeresult(result);
+	pthread_setcancelstate(cur_state, NULL);
 
 	return ret;
 }
@@ -297,7 +314,7 @@ static int lookup_wild(struct autofs_poi
 	nis_object *this;
 	char *mapent;
 	time_t age = time(NULL);
-	int ret;
+	int ret, cur_state;
 	char buf[MAX_ERR_BUF];
 
 	source = ap->entry->current;
@@ -306,10 +323,12 @@ static int lookup_wild(struct autofs_poi
 
 	mc = source->mc;
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	tablename = alloca(strlen(ctxt->mapname) + strlen(ctxt->domainname) + 20);
 	if (!tablename) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
 		crit(LOGOPT_ANY, MODPREFIX "alloca: %s", estr);
+		pthread_setcancelstate(cur_state, NULL);
 		return -1;
 	}
 	sprintf(tablename, "[key=*],%s.org_dir.%s", ctxt->mapname,
@@ -318,6 +337,7 @@ static int lookup_wild(struct autofs_poi
 	result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 	if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
 		nis_freeresult(result);
+		pthread_setcancelstate(cur_state, NULL);
 		if (result->status == NIS_NOTFOUND ||
 		    result->status == NIS_S_NOTFOUND)
 			return CHE_MISSING;
@@ -332,6 +352,7 @@ static int lookup_wild(struct autofs_poi
 	cache_unlock(mc);
 
 	nis_freeresult(result);
+	pthread_setcancelstate(cur_state, NULL);
 
 	return ret;
 }
@@ -493,12 +514,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me) {
-		pthread_cleanup_push(cache_lock_cleanup, mc);
+	if (me && me->mapent) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);
-		pthread_cleanup_pop(0);
 	}
 	cache_unlock(mc);
 
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index ccf6d60..275610a 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -117,8 +117,8 @@ int lookup_init(const char *mapfmt, int 
 	memset(ctxt, 0, sizeof(struct lookup_context));
 
 	if (argc < 1) {
-		crit(LOGOPT_ANY, MODPREFIX "no map name");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "no map name");
 		return 1;
 	}
 	ctxt->mapname = argv[0];
@@ -128,9 +128,9 @@ int lookup_init(const char *mapfmt, int 
 	/* This should, but doesn't, take a const char ** */
 	err = yp_get_default_domain((char **) &ctxt->domainname);
 	if (err) {
+		free(ctxt);
 		debug(LOGOPT_NONE, MODPREFIX "map %s: %s", ctxt->mapname,
 		       yperr_string(err));
-		free(ctxt);
 		return 1;
 	}
 
@@ -141,8 +141,8 @@ int lookup_init(const char *mapfmt, int 
 
 	ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
 	if (!ctxt->parse) {
-		crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
 		free(ctxt);
+		crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
 		return 1;
 	}
 	*context = ctxt;
@@ -176,7 +176,7 @@ int yp_all_master_callback(int status, c
 
 	len = ypkeylen + 1 + vallen + 1;
 
-	buffer = malloc(len);
+	buffer = alloca(len);
 	if (!buffer) {
 		error(LOGOPT_ANY, MODPREFIX "could not malloc parse buffer");
 		return 0;
@@ -189,8 +189,6 @@ int yp_all_master_callback(int status, c
 
 	master_parse_entry(buffer, timeout, logging, age);
 
-	free(buffer);
-
 	return 0;
 }
 
@@ -600,12 +598,10 @@ int lookup_mount(struct autofs_point *ap
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	if (me) {
-		pthread_cleanup_push(cache_lock_cleanup, mc);
+	if (me && me->mapent) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);
-		pthread_cleanup_pop(0);
 	}
 	cache_unlock(mc);
 
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index b3f5d67..c132422 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -407,7 +407,9 @@ static char *concat_options(char *left, 
 		return NULL;
 	}
 
-	sprintf(ret, "%s,%s", left, right);
+	strcpy(ret, left);
+	strcat(ret, ",");
+	strcat(ret, right);
 
 	free(left);
 	free(right);
@@ -422,7 +424,7 @@ static int sun_mount(struct autofs_point
 {
 	char *fstype = "nfs";	/* Default filesystem type */
 	int nonstrict = 1;
-	int rv;
+	int rv, cur_state;
 	char *mountpoint;
 	char *what;
 
@@ -520,6 +522,7 @@ static int sun_mount(struct autofs_point
 	    "mounting root %s, mountpoint %s, what %s, fstype %s, options %s",
 	    root, mountpoint, what, fstype, options);
 
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 	if (!strcmp(fstype, "nfs")) {
 		rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint),
 					    what, fstype, options, mount_nfs->context);
@@ -528,6 +531,7 @@ static int sun_mount(struct autofs_point
 		rv = do_mount(ap, root, mountpoint, strlen(mountpoint), what, fstype,
 			      options);
 	}
+	pthread_setcancelstate(cur_state, NULL);
 
 	if (nonstrict && rv)
 		return -rv;
@@ -878,7 +882,7 @@ int parse_mount(struct autofs_point *ap,
 	char *pmapent, *options;
 	const char *p;
 	int mapent_len, rv = 0;
-	int optlen;
+	int optlen, cur_state;
 	int slashify = ctxt->slashify_colons;
 
 	source = ap->entry->current;
@@ -962,8 +966,8 @@ int parse_mount(struct autofs_point *ap,
 			m_root = alloca(m_root_len + 1);
 			if (!m_root) {
 				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-				error(ap->logopt, MODPREFIX "alloca: %s", estr);
 				free(options);
+				error(ap->logopt, MODPREFIX "alloca: %s", estr);
 				return 1;
 			}
 			strcpy(m_root, name);
@@ -972,8 +976,8 @@ int parse_mount(struct autofs_point *ap,
 			m_root = alloca(m_root_len + 1);
 			if (!m_root) {
 				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-				error(ap->logopt, MODPREFIX "alloca: %s", estr);
 				free(options);
+				error(ap->logopt, MODPREFIX "alloca: %s", estr);
 				return 1;
 			}
 			strcpy(m_root, ap->path);
@@ -1007,13 +1011,14 @@ int parse_mount(struct autofs_point *ap,
 		}
 
 		if (!me) {
-			error(ap->logopt,
-			      MODPREFIX "can't find multi root %s", name);
 			free(options);
 			cache_unlock(mc);
+			error(ap->logopt,
+			      MODPREFIX "can't find multi root %s", name);
 			return 1;
 		}
 
+		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 		cache_multi_lock(me);
 		/* It's a multi-mount; deal with it */
 		do {
@@ -1038,6 +1043,7 @@ int parse_mount(struct autofs_point *ap,
 				cache_multi_unlock(me);
 				cache_unlock(mc);
 				free(options);
+				pthread_setcancelstate(cur_state, NULL);
 				return 1;
 			}
 
@@ -1051,6 +1057,7 @@ int parse_mount(struct autofs_point *ap,
 				cache_unlock(mc);
 				free(path);
 				free(options);
+				pthread_setcancelstate(cur_state, NULL);
 				return 1;
 			}
 
@@ -1073,6 +1080,7 @@ int parse_mount(struct autofs_point *ap,
 				free(options);
 				free(myoptions);
 				free(loc);
+				pthread_setcancelstate(cur_state, NULL);
 				return 1;
 			}
 
@@ -1101,6 +1109,7 @@ int parse_mount(struct autofs_point *ap,
 				cache_multi_unlock(me);
 				cache_unlock(mc);
 				free(options);
+				pthread_setcancelstate(cur_state, NULL);
 				return 1;
 			}
 
@@ -1118,6 +1127,7 @@ int parse_mount(struct autofs_point *ap,
 				cache_multi_unlock(me);
 				cache_unlock(mc);
 				free(options);
+				pthread_setcancelstate(cur_state, NULL);
 				return rv;
 			}
 		}
@@ -1128,6 +1138,7 @@ int parse_mount(struct autofs_point *ap,
 			cache_multi_unlock(me);
 			cache_unlock(mc);
 			free(options);
+			pthread_setcancelstate(cur_state, NULL);
 			return 1;
 		}
 
@@ -1135,6 +1146,7 @@ int parse_mount(struct autofs_point *ap,
 		cache_unlock(mc);
 
 		free(options);
+		pthread_setcancelstate(cur_state, NULL);
 
 		return rv;
 	} else {
@@ -1145,24 +1157,24 @@ int parse_mount(struct autofs_point *ap,
 
 		/* Location can't begin with a '/' */
 		if (*p == '/') {
+			free(options);
 			warn(ap->logopt,
 			      MODPREFIX "error location begins with \"/\"");
-			free(options);
 			return 1;
 		}
 
 		l = chunklen(p, check_colon(p));
 		loc = dequote(p, l, ap->logopt);
 		if (!loc) {
-			warn(ap->logopt, MODPREFIX "null location or out of memory");
 			free(options);
+			warn(ap->logopt, MODPREFIX "null location or out of memory");
 			return 1;
 		}
 
 		if (!validate_location(loc)) {
-			warn(ap->logopt, MODPREFIX "invalid location");
 			free(loc);
 			free(options);
+			warn(ap->logopt, MODPREFIX "invalid location");
 			return 1;
 		}
 
@@ -1178,18 +1190,18 @@ int parse_mount(struct autofs_point *ap,
 			l = chunklen(p, check_colon(p));
 			ent = dequote(p, l, ap->logopt);
 			if (!ent) {
-				warn(ap->logopt,
-				     MODPREFIX "null location or out of memory");
 				free(loc);
 				free(options);
+				warn(ap->logopt,
+				     MODPREFIX "null location or out of memory");
 				return 1;
 			}
 
 			if (!validate_location(ent)) {
-				warn(ap->logopt, MODPREFIX "invalid location");
 				free(ent);
 				free(loc);
 				free(options);
+				warn(ap->logopt, MODPREFIX "invalid location");
 				return 1;
 			}
 
@@ -1198,10 +1210,10 @@ int parse_mount(struct autofs_point *ap,
 
 			loc = realloc(loc, strlen(loc) + l + 2);
 			if (!loc) {
-				error(ap->logopt, MODPREFIX "out of memory");
 				free(ent);
 				free(loc);
 				free(options);
+				error(ap->logopt, MODPREFIX "out of memory");
 				return 1;
 			}
 
@@ -1216,10 +1228,10 @@ int parse_mount(struct autofs_point *ap,
 
 		loclen = strlen(loc);
 		if (loclen == 0) {
-			error(ap->logopt,
-			      MODPREFIX "entry %s is empty!", name);
 			free(loc);
 			free(options);
+			error(ap->logopt,
+			      MODPREFIX "entry %s is empty!", name);
 			return 1;
 		}
 
@@ -1242,12 +1254,14 @@ int parse_mount(struct autofs_point *ap,
 		 * If it's a multi-mount insert the triggers
 		 * These are always direct mount triggers so root = ""
 		 */
+		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
 		cache_readlock(mc);
 		me = cache_lookup_distinct(mc, name);
 		if (me) {
 			mount_subtree_offsets(ap, mc, me);
 		}
 		cache_unlock(mc);
+		pthread_setcancelstate(cur_state, NULL);
 	}
 	return rv;
 }