rpms/autofs/devel autofs-5.0.1-rc1-allow-initial-numeric-in-hostname.patch, NONE, 1.1 autofs-5.0.1-rc1-check-offset-mounts-before-umount.patch, NONE, 1.1 autofs-5.0.1-rc1-expire-individual-submounts.patch, NONE, 1.1 autofs-5.0.1-rc1-ino_index-locking.patch, NONE, 1.1 autofs-5.0.1-rc1-more-expire-rework.patch, NONE, 1.1 autofs-5.0.1-rc1-premature-submount-expire.patch, NONE, 1.1 autofs.spec, 1.140, 1.141

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Aug 16 07:27:54 UTC 2006


Author: ikent

Update of /cvs/dist/rpms/autofs/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv10881

Modified Files:
	autofs.spec 
Added Files:
	autofs-5.0.1-rc1-allow-initial-numeric-in-hostname.patch 
	autofs-5.0.1-rc1-check-offset-mounts-before-umount.patch 
	autofs-5.0.1-rc1-expire-individual-submounts.patch 
	autofs-5.0.1-rc1-ino_index-locking.patch 
	autofs-5.0.1-rc1-more-expire-rework.patch 
	autofs-5.0.1-rc1-premature-submount-expire.patch 
Log Message:
* Thu Aug 16 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.15
- expire individual submounts.
- add ino_index locking.
- fix nested submount expiring away when pwd is base of submount.
- more expire re-work to cope better with shutdown following cthon tests.
- allow hostname to start with numeric when validating.


autofs-5.0.1-rc1-allow-initial-numeric-in-hostname.patch:
 CHANGELOG           |    1 +
 modules/parse_sun.c |    3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-allow-initial-numeric-in-hostname.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 1969912..559f087 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,7 @@
 - add ino_index locking.
 - fix nested submount expiring away when pwd is base of submount.
 - more expire re-work to cope better with shutdown following cthon tests.
+- allow hostname to start with numeric when validating.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 08fd34d..1f1bc3c 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -666,9 +666,6 @@ static int validate_location(char *loc)
 
 	/* If a ':' is present now it must be a host name */
 	if (check_colon(ptr)) {
-		if (!isalpha(*ptr++))
-			return 0;
-
 		while (*ptr && *ptr != ':') {
 			if (!(isalnum(*ptr) ||
 			    *ptr == '-' || *ptr == '.' ||

autofs-5.0.1-rc1-check-offset-mounts-before-umount.patch:
 parse_subs.c |   33 +++++++++++++++++++++++++--------
 1 files changed, 25 insertions(+), 8 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-check-offset-mounts-before-umount.patch ---
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index 68bdf8d..a782146 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -417,9 +417,9 @@ cont:
 int umount_multi_triggers(struct autofs_point *ap, char *root, struct mapent *me, const char *base)
 {
 	char path[PATH_MAX + 1];
-	char *offset = path;
+	char *offset;
 	struct mapent *oe;
-	struct list_head *mm_root, *pos = NULL;
+	struct list_head *mm_root, *pos;
 	const char o_root[] = "/";
 	const char *mm_base;
 	int left, start;
@@ -434,12 +434,32 @@ int umount_multi_triggers(struct autofs_
 	else
 		mm_base = base;
 
-	offset = cache_get_offset(mm_base, offset, start, mm_root, &pos);
-	while (offset) {
+	pos = NULL;
+	offset = path;
+
+	/* Make sure "none" of the offsets have an active mount. */
+	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
 		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;
+			continue;
+
+		if (oe->ioctlfd != -1)
+			left++;
+	}
+
+	if (left)
+		return left;
+
+	pos = NULL;
+	offset = path;
+
+	/* Make sure "none" of the offsets have an active mount. */
+	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+		/* root offset is a special case */
+		if (!oe || (strlen(oe->key) - start) == 1)
+			continue;
 
 		debug(ap->logopt, "umount offset %s", oe->key);
 
@@ -447,9 +467,6 @@ int umount_multi_triggers(struct autofs_
 			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) {

autofs-5.0.1-rc1-expire-individual-submounts.patch:
 CHANGELOG           |    1 
 daemon/direct.c     |   31 ++++++++++++-------
 daemon/indirect.c   |   14 ++++++--
 include/automount.h |    1 
 include/master.h    |    3 +
 lib/master.c        |   81 +++++++++++++++++++++++++++++++++++++---------------
 lib/mounts.c        |    2 -
 7 files changed, 92 insertions(+), 41 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-expire-individual-submounts.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 6fe9697..fe73ab8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,7 @@
 - review verbose message feedback and update.
 - correction for expire of multi-mounts.
 - spelling corrections to release notes (Jeff Moyer).
+- expire individual submounts.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 4b6162b..b9c0f04 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -786,18 +786,23 @@ void *expire_proc_direct(void *arg)
 	if (status)
 		fatal(status);
 
-	master_notify_submounts(ap, ap->state);
-
 	/* 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) {
-		/* Skip submounts */
-		if (strstr(next->fs_type, "indirect"))
-			continue;
+		if (!strcmp(next->fs_type, "autofs")) {
+			/*
+			 * If we have submounts check if this path lives below
+			 * one of them and pass on state change.
+			 */
+			if (strstr(next->opts, "indirect")) {
+				master_notify_submount(ap, next->path, ap->state);
+				continue;
+			}
 
-		/* Skip offsets */
-		if (strstr(next->opts, "offset"))
-			continue;
+			/* Skip offsets */
+			if (strstr(next->opts, "offset"))
+				continue;
+		}
 
 		/*
 		 * All direct mounts must be present in the map
@@ -896,9 +901,10 @@ static void *do_expire_direct(void *arg)
 		send_fail(mt->ioctlfd, mt->wait_queue_token);
 	else {
 		struct mapent *me;
-		me = lookup_source_mapent(ap, mt->name, LKP_DISTINCT);
+		cache_readlock(mt->mc);
+		me = cache_lookup_distinct(mt->mc, mt->name);
 		me->ioctlfd = -1;
-		cache_unlock(me->source->mc);
+		cache_unlock(mt->mc);
 		send_ready(mt->ioctlfd, mt->wait_queue_token);
 		close(mt->ioctlfd);
 	}
@@ -1195,9 +1201,10 @@ cont:
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 	if (status) {
 		struct mapent *me;
-		me = lookup_source_mapent(ap, mt->name, LKP_DISTINCT);
+		cache_readlock(mt->mc);
+		me = cache_lookup_distinct(mt->mc, mt->name);
 		me->ioctlfd = mt->ioctlfd;
-		cache_unlock(me->source->mc);
+		cache_unlock(mt->mc);
 		send_ready(mt->ioctlfd, mt->wait_queue_token);
 		msg("mounted %s", mt->name);
 	} else {
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 8748413..dadb9ee 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -430,16 +430,22 @@ void *expire_proc_indirect(void *arg)
 	if (status)
 		fatal(status);
 
-	master_notify_submounts(ap, ap->state);
-
 	/* Get a list of real mounts and expire them if possible */
 	mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 0);
 	for (next = mnts; next; next = next->next) {
 		char *ind_key;
 		int ret;
 
-		if (!strcmp(next->fs_type, "autofs"))
+		if (!strcmp(next->fs_type, "autofs")) {
+			/*
+			 * If we have submounts check if this path lives below
+			 * one of them and pass on the state change.
+			 */
+			if (strstr(next->opts, "indirect"))
+				master_notify_submount(ap, next->path, ap->state);
+
 			continue;
+		}
 
 		/*
 		 * If the mount corresponds to an offset trigger then
@@ -458,7 +464,7 @@ void *expire_proc_indirect(void *arg)
 		 */
 		me = lookup_source_mapent(ap, next->path, LKP_DISTINCT);
 		if (!me && ind_key)
-			lookup_source_mapent(ap, ind_key, LKP_NORMAL);
+			me = lookup_source_mapent(ap, ind_key, LKP_NORMAL);
 		if (!me)
 			continue;
 
diff --git a/include/automount.h b/include/automount.h
index 90a9c7a..267c7d1 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -437,7 +437,6 @@ struct autofs_point {
 	pthread_t exp_thread;		/* Thread that is expiring */
 	pthread_t readmap_thread;	/* Thread that is reading maps */
 	pthread_mutex_t state_mutex;	/* Protect state changes */
-	struct list_head state_queue;	/* Pending state transitions */
 	enum states state;		/* Current state */
 	int state_pipe[2];		/* State change router pipe */
 	unsigned dir_created;		/* Directory created for this mount? */
diff --git a/include/master.h b/include/master.h
index ada18d4..e25626d 100644
--- a/include/master.h
+++ b/include/master.h
@@ -97,7 +97,8 @@ void master_free_mapent_sources(struct m
 void master_free_mapent(struct master_mapent *);
 struct master *master_new(const char *, unsigned int, unsigned int);
 int master_read_master(struct master *, time_t, int);
-void master_notify_submounts(struct autofs_point *, enum states);
+int master_submount_list_empty(struct autofs_point *ap);
+int master_notify_submount(struct autofs_point *, const char *path, enum states);
 void master_signal_submount(struct autofs_point *, unsigned int);
 void master_notify_state_change(struct master *, int);
 int master_mount_mounts(struct master *, time_t, int);
diff --git a/lib/master.c b/lib/master.c
index d76ffac..1d66542 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -95,7 +95,6 @@ int master_add_autofs_point(struct maste
 		free(ap);
 		return 0;
 	}
-	INIT_LIST_HEAD(&ap->state_queue);
 
 	status = pthread_mutex_init(&ap->mounts_mutex, NULL);
 	if (status) {
@@ -735,34 +734,68 @@ int master_read_master(struct master *ma
 	return 1;
 }
 
-void master_notify_submounts(struct autofs_point *ap, enum states state)
+int master_submount_list_empty(struct autofs_point *ap)
+{
+	int res = 0;
+
+	mounts_mutex_lock(ap);
+	if (list_empty(&ap->submounts))
+		res = 1;
+	mounts_mutex_unlock(ap);
+
+	return res;
+}
+
+int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
 {
 	struct list_head *head, *p;
 	struct autofs_point *this;
 	pthread_t thid;
-	int status;
-
-	/* Initiate from master entries only */
-	if (ap->submount || list_empty(&ap->submounts))
-		return;
+	size_t plen = strlen(path);
+	int status, ret = 1;
 
 	mounts_mutex_lock(ap);
 
 	head = &ap->submounts;
-	p = head->next;
+	p = head->prev;
 	while (p != head) {
+		size_t len;
+
 		this = list_entry(p, struct autofs_point, mounts);
+		p = p->prev;
 
-		p = p->next;
+		if (!master_submount_list_empty(this)) {
+			if (!master_notify_submount(this, path, state)) {
+				ret = 0;
+				break;
+			}
+		}
+
+		len = strlen(this->path);
 
-		if (!list_empty(&this->submounts))
-			master_notify_submounts(this, state);
+		/* Initial path not the same */
+		if (strncmp(this->path, path, len))
+			continue;
+
+		/*
+		 * Part of submount tree?
+		 * We must wait till we get to submount itself.
+		 * If it is tell caller by returning true.
+		 */
+		if (plen > len) {
+			/* Not part of this directory tree */
+			if (path[len] != '/')
+				continue;
+			break;
+		}
+
+		/* Now we have a submount to expire */
 
 		state_mutex_lock(this);
 
 		if (this->state == ST_SHUTDOWN) {
 			state_mutex_unlock(this);
-			continue;
+			break;
 		}
 
 		nextstate(this->state_pipe[1], state);
@@ -775,17 +808,21 @@ void master_notify_submounts(struct auto
 			status = pthread_cond_wait(&ap->mounts_cond, &ap->mounts_mutex);
 			if (status)
 				fatal(status);
-			if (ap->mounts_signaled == MASTER_SUBMNT_JOIN) {
-				status = pthread_join(thid, NULL);
-				if (status)
-					fatal(status);
-			}
 		}
+
+		if (ap->mounts_signaled == MASTER_SUBMNT_JOIN) {
+			status = pthread_join(thid, NULL);
+			if (status)
+				fatal(status);
+		} else
+			ret = 0;
+
+		break;
 	}
 
 	mounts_mutex_unlock(ap);
 
-	return;
+	return ret;
 }
 
 void master_signal_submount(struct autofs_point *ap, unsigned int join)
@@ -797,13 +834,13 @@ void master_signal_submount(struct autof
 
 	mounts_mutex_lock(ap->parent);
 
-	if (join) {
+	ap->parent->mounts_signaled = join;
+
+	if (join == MASTER_SUBMNT_JOIN) {
 		/* We are finishing up */
 		ap->parent->submnt_count--;
 		list_del(&ap->mounts);
-		ap->parent->mounts_signaled = 1;
-	} else
-		ap->parent->mounts_signaled = 2;
+	}
 
 	status = pthread_cond_signal(&ap->parent->mounts_cond);
 	if (status)
diff --git a/lib/mounts.c b/lib/mounts.c
index f446a6a..46131cd 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -149,7 +149,7 @@ struct mnt_list *get_mnt_list(const char
 		mptr = list;
 		last = NULL;
 		while (mptr) {
-			if (len > strlen(mptr->path))
+			if (len >= strlen(mptr->path))
 				break;
 			last = mptr;
 			mptr = mptr->next;

autofs-5.0.1-rc1-ino_index-locking.patch:
 CHANGELOG           |    1 +
 include/automount.h |    1 +
 lib/cache.c         |   49 ++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 46 insertions(+), 5 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-ino_index-locking.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index fe73ab8..b469121 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@
 - correction for expire of multi-mounts.
 - spelling corrections to release notes (Jeff Moyer).
 - expire individual submounts.
+- add ino_index locking.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/include/automount.h b/include/automount.h
index 267c7d1..3192c92 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -129,6 +129,7 @@ #define EXPIRE_RETRIES		25
 struct mapent_cache {
 	pthread_rwlock_t rwlock;
 	unsigned int size;
+	pthread_mutex_t ino_index_mutex;
 	struct list_head *ino_index;
 	struct mapent **hash;
 };
diff --git a/lib/cache.c b/lib/cache.c
index 432270b..35dfa5a 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -96,6 +96,7 @@ void cache_lock_cleanup(void *arg)
 	struct mapent_cache *mc = (struct mapent_cache *) arg;
 
 	cache_unlock(mc);
+	return;
 }
 
 void cache_multi_lock(struct mapent *me)
@@ -128,6 +129,29 @@ void cache_multi_unlock(struct mapent *m
 	return;
 }
 
+void cache_multi_lock_cleanup(void *arg)
+{
+	struct mapent *me = (struct mapent *) arg;
+	cache_multi_unlock(me);
+	return;
+}
+
+static inline void ino_index_lock(struct mapent_cache *mc)
+{
+	int status = pthread_mutex_lock(&mc->ino_index_mutex);
+	if (status)
+		fatal(status);
+	return;
+}
+
+static inline void ino_index_unlock(struct mapent_cache *mc)
+{
+	int status = pthread_mutex_unlock(&mc->ino_index_mutex);
+	if (status)
+		fatal(status);
+	return;
+}
+
 struct mapent_cache *cache_init(struct map_source *map)
 {
 	struct mapent_cache *mc;
@@ -156,6 +180,10 @@ struct mapent_cache *cache_init(struct m
 		return NULL;
 	}
 
+	status = pthread_mutex_init(&mc->ino_index_mutex, NULL);
+	if (status)
+		fatal(status);
+
 	status = pthread_rwlock_init(&mc->rwlock, NULL);
 	if (status)
 		fatal(status);
@@ -201,10 +229,12 @@ int cache_set_ino_index(struct mapent_ca
 	if (!me)
 		return 0;
 
+	ino_index_lock(mc);
+	list_del_init(&me->ino_index);
 	list_add(&me->ino_index, &mc->ino_index[ino_index]);
-
 	me->dev = dev;
 	me->ino = ino;
+	ino_index_unlock(mc);
 
 	return 1;
 }
@@ -216,6 +246,7 @@ struct mapent *cache_lookup_ino(struct m
 	struct list_head *head, *p;
 	unsigned int ino_index;
 
+	ino_index_lock(mc);
 	ino_index = ino_hash(dev, ino);
 	head = &mc->ino_index[ino_index];
 
@@ -225,8 +256,10 @@ struct mapent *cache_lookup_ino(struct m
 		if (me->dev != dev || me->ino != ino)
 			continue;
 
+		ino_index_unlock(mc);
 		return me;
 	}
+	ino_index_unlock(mc);
 	return NULL;
 }
 
@@ -647,8 +680,9 @@ int cache_delete(struct mapent_cache *mc
 			status = pthread_mutex_destroy(&me->multi_mutex);
 			if (status)
 				fatal(status);
-			if (!list_empty(&me->ino_index))
-				list_del(&me->ino_index);
+			ino_index_lock(mc);
+			list_del(&me->ino_index);
+			ino_index_unlock(mc);
 			free(me->key);
 			if (me->mapent)
 				free(me->mapent);
@@ -670,8 +704,9 @@ int cache_delete(struct mapent_cache *mc
 		status = pthread_mutex_destroy(&me->multi_mutex);
 		if (status)
 			fatal(status);
-		if (!list_empty(&me->ino_index))
-			list_del(&me->ino_index);
+		ino_index_lock(mc);
+		list_del(&me->ino_index);
+		ino_index_unlock(mc);
 		free(me->key);
 		if (me->mapent)
 			free(me->mapent);
@@ -774,6 +809,10 @@ void cache_release(struct map_source *ma
 
 	cache_unlock(mc);
 
+	status = pthread_mutex_destroy(&mc->ino_index_mutex);
+	if (status)
+		fatal(status);
+
 	status = pthread_rwlock_destroy(&mc->rwlock);
 	if (status)
 		fatal(status);

autofs-5.0.1-rc1-more-expire-rework.patch:
 CHANGELOG           |    1 
 daemon/automount.c  |  104 ++++++++++++++++++++++++++++++----------------------
 daemon/direct.c     |   25 ++++++++----
 daemon/indirect.c   |   41 +++++++++++---------
 daemon/lookup.c     |   45 +++++++++++++++++++++-
 include/automount.h |    7 ++-
 lib/alarm.c         |    6 +--
 modules/parse_sun.c |  104 ++++++++++++++++++++++++++--------------------------
 8 files changed, 203 insertions(+), 130 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-more-expire-rework.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index fc939ad..1969912 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,7 @@
 - expire individual submounts.
 - add ino_index locking.
 - fix nested submount expiring away when pwd is base of submount.
+- more expire re-work to cope better with shutdown following cthon tests.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/daemon/automount.c b/daemon/automount.c
index cc6e9e0..446c184 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -304,12 +304,12 @@ static int counter_fn(const char *file, 
 }
 
 /* Count mounted filesystems and symlinks */
-int count_mounts(struct autofs_point *ap, const char *path)
+int count_mounts(const char *path, dev_t dev)
 {
 	struct counter_args counter;
 
 	counter.count = 0;
-	counter.dev = ap->dev;
+	counter.dev = dev;
 	
 	if (walk_tree(path, counter_fn, 0, &counter) == -1)
 		return -1;
@@ -366,26 +366,12 @@ static void update_map_cache(struct auto
 	return;
 }
 
-/* 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, const char *path, int incl)
+static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsigned int is_autofs_fs)
 {
 	struct mapent_cache *mc;
 	struct mapent *me;
-	struct statfs fs;
-	int is_autofs_fs;
-	int ret, left;
 	unsigned int is_mm_root;
-
-	debug(ap->logopt, "path %s incl %d", path, incl);
-
-	ret = statfs(path, &fs);
-	if (ret == -1) {
-		error(ap->logopt, "could not stat fs of %s", path);
-		return 1;
-	}
-
-	is_autofs_fs = fs.f_type == AUTOFS_SUPER_MAGIC ? 1 : 0;
+	int left;
 
 	me = lookup_source_mapent(ap, path, LKP_DISTINCT);
 	if (!me) {
@@ -395,74 +381,104 @@ int umount_multi(struct autofs_point *ap
 		if (ind_key)
 			ind_key++;
 
-		me = lookup_source_mapent(ap, ind_key, LKP_DISTINCT);
-		if (!me) {
-			warn(ap->logopt, "map entry not found for %s", path);
+		me = lookup_source_mapent(ap, ind_key, LKP_NORMAL);
+		if (!me)
 			return 0;
-		}
 	}
 
-	cache_multi_lock(me->parent);
-
 	mc = me->source->mc;
 	is_mm_root = (me->multi == me);
 
 	left = 0;
 
 	if (me->multi) {
-		struct autofs_point *oap = ap;
 		char *root, *base;
+		size_t ap_len;
 
-		if (ap->submount)
-			oap = ap->parent;
+		ap_len = strlen(ap->path);
 
-		if (is_mm_root && !strchr(me->key, '/')) {
+		if (!strchr(me->multi->key, '/')) {
 			/* Indirect multi-mount root */
-			root = alloca(strlen(ap->path) + strlen(me->key) + 2);
+			root = alloca(ap_len + strlen(me->multi->key) + 2);
 			strcpy(root, ap->path);
 			strcat(root, "/");
-			strcat(root, me->key);
-			base = NULL;
-		} else {
+			strcat(root, me->multi->key);
+		} else
 			root = me->multi->key;
+
+		if (is_mm_root)
+			base = NULL;
+		else
 			base = me->key + strlen(root);
-		}
 
-		if (umount_multi_triggers(oap, root, me, base)) {
+		/* Lock the closest parent nesting point for umount */
+		cache_multi_lock(me->parent);
+		if (umount_multi_triggers(ap, root, me, base)) {
 			warn(ap->logopt,
 			     "could not umount some offsets under %s", path);
 			left++;
 		}
+		cache_multi_unlock(me->parent);
 	}
 
-	if (left || is_autofs_fs) {
-		cache_multi_unlock(me->parent);
-		cache_unlock(mc);
+	cache_unlock(mc);
+
+	if (left || is_autofs_fs)
 		return left;
-	}
 
 	/*
 	 * 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
+	 * it already to ensure it's ok to remove any offset triggers.
 	 */
-	if (!is_mm_root) {
+	if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) {
 		msg("unmounting dir = %s", path);
-
 		if (umount_ent(ap, path)) {
 			warn(ap->logopt, "could not umount dir %s", path);
 			left++;
 		}
 	}
 
+	return left;
+}
+
+/* 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, const char *path, int incl)
+{
+	struct statfs fs;
+	int is_autofs_fs;
+	int ret, left;
+
+	debug(ap->logopt, "path %s incl %d", path, incl);
+
+	ret = statfs(path, &fs);
+	if (ret == -1) {
+		error(ap->logopt, "could not stat fs of %s", path);
+		return 1;
+	}
+
+	is_autofs_fs = fs.f_type == AUTOFS_SUPER_MAGIC ? 1 : 0;
+
+	left = 0;
+
+	/*
+	 * If we are a submount we need to umount any offsets our
+	 * parent may have mounted over top of us.
+	 */
+	/*if (ap->submount)
+		left += umount_subtree_mounts(ap->parent, path, is_autofs_fs);*/
+
+	left += umount_subtree_mounts(ap, path, is_autofs_fs);
+
+	if (left || is_autofs_fs)
+		return left;
+
 	/* Delete detritus like unwanted mountpoints and symlinks */
 	if (left == 0) {
 		update_map_cache(ap, path);
 		check_rm_dirs(ap, path, incl);
 	}
 
-	cache_multi_unlock(me->parent);
-	cache_unlock(mc);
-
 	return left;
 }
 
diff --git a/daemon/direct.c b/daemon/direct.c
index b9c0f04..18b56fe 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -33,6 +33,7 @@ #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/poll.h>
 #include <sys/mount.h>
+#include <sys/vfs.h>
 #include <sched.h>
 #include <pwd.h>
 #include <grp.h>
@@ -114,7 +115,7 @@ int do_umount_autofs_direct(struct autof
 	char buf[MAX_ERR_BUF];
 	int ioctlfd, rv, left, retries;
 
-	left = umount_multi(ap, me->key, 1);
+	left = umount_multi(ap, me->key, 0);
 	if (left) {
 		warn(ap->logopt, "could not unmount %d dirs under %s",
 		     left, me->key);
@@ -258,9 +259,9 @@ static int unlink_mount_tree(struct auto
 	struct list_head *p;
 	int rv, ret;
 	pid_t pgrp = getpgrp();
-	char spgrp[10];
+	char spgrp[20];
 
-	sprintf(spgrp, "%d", pgrp);
+	sprintf(spgrp, "pgrp=%d", pgrp);
 
 	ret = 1;
 	list_for_each(p, list) {
@@ -727,7 +728,17 @@ out_err:
 
 static int expire_direct(int ioctlfd, const char *path, unsigned int when, unsigned int logopt)
 {
-	int ret, retries = EXPIRE_RETRIES;
+	char buf[MAX_ERR_BUF];
+	int ret, retries;
+	struct stat st;
+
+	if (fstat(ioctlfd, &st) == -1) {
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		error(logopt, "fstat failed: %s", estr);
+		return 0;
+	}
+
+	retries = (count_mounts(path, st.st_dev) + 1) * EXPIRE_RETRIES;
 
 	while (retries--) {
 		struct timespec tm = {0, 100000000};
@@ -747,7 +758,7 @@ static int expire_direct(int ioctlfd, co
 		nanosleep(&tm, NULL);
 	}
 
-	return 1;
+	return (retries >= 0);
 }
 
 void *expire_proc_direct(void *arg)
@@ -824,10 +835,8 @@ void *expire_proc_direct(void *arg)
 		debug(ap->logopt, "send expire to trigger %s", next->path);
 
 		ret = expire_direct(ioctlfd, next->path, now, ap->logopt);
-		if (!ret) {
-			msg("mount apparently busy %s", next->path);
+		if (!ret)
 			ea->status++;
-		}
 	}
 	free_mnt_list(mnts);
 
diff --git a/daemon/indirect.c b/daemon/indirect.c
index dadb9ee..e04f164 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -82,9 +82,9 @@ static int unlink_mount_tree(struct auto
 	struct mnt_list *this;
 	int rv, ret;
 	pid_t pgrp = getpgrp();
-	char spgrp[10];
+	char spgrp[20];
 
-	sprintf(spgrp, "%d", pgrp);
+	sprintf(spgrp, "pgrp=%d", pgrp);
 
 	ret = 1;
 	this = mnts;
@@ -367,9 +367,19 @@ force_umount:
 	return rv;
 }
 
-static int expire_indirect(int ioctlfd, const char *path, unsigned int when, unsigned int count, unsigned int logopt)
+static int expire_indirect(struct autofs_point *ap, int ioctlfd, const char *path, unsigned int when)
 {
-	int ret, retries = count;
+	char buf[MAX_ERR_BUF];
+	int ret, retries;
+	struct stat st;
+
+	if (fstat(ioctlfd, &st) == -1) {
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		error(ap->logopt, "fstat failed: %s", estr);
+		return 0;
+	}
+
+	retries = (count_mounts(path, st.st_dev) + 1) * EXPIRE_RETRIES;
 
 	while (retries--) {
 		struct timespec tm = {0, 100000000};
@@ -389,7 +399,7 @@ static int expire_indirect(int ioctlfd, 
 		nanosleep(&tm, NULL);
 	}
 
-	return 1;
+	return (retries >= 0);
 }
 
 void *expire_proc_indirect(void *arg)
@@ -400,9 +410,8 @@ void *expire_proc_indirect(void *arg)
 	struct expire_args *ea;
 	unsigned int now;
 	int offsets, submnts, count;
-	int ioctlfd, limit;
+	int ioctlfd;
 	int status, ret;
-	unsigned int retries = EXPIRE_RETRIES;
 
 	ea = (struct expire_args *) arg;
 
@@ -477,11 +486,9 @@ void *expire_proc_indirect(void *arg)
 
 		debug(ap->logopt, "expire %s", next->path);
 
-		ret = expire_indirect(ioctlfd, next->path, now, retries, ap->logopt);
-		if (!ret) {
-			msg("mount apparently busy %s", next->path);
+		ret = expire_indirect(ap, ioctlfd, next->path, now);
+		if (!ret)
 			ea->status++;
-		}
 	}
 	free_mnt_list(mnts);
 
@@ -490,12 +497,10 @@ void *expire_proc_indirect(void *arg)
 	 * have some offset mounts with no '/' offset so we need to
 	 * umount them here.
 	 */
-	limit = count_mounts(ap, ap->path) * 2;
-	ret = expire_indirect(ap->ioctlfd, ap->path, now, limit, ap->logopt);
-	if (!ret) {
-		debug(ap->logopt,
-		      "failed to expire offsets under %s", ap->path);
-		ea->status++;
+	if (mnts) {
+		ret = expire_indirect(ap, ap->ioctlfd, ap->path, now);
+		if (!ret)
+			ea->status++;
 	}
 
 	count = offsets = submnts = 0;
@@ -527,7 +532,7 @@ 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) {
-			warn(ap->logopt, "mount still busy %s", ap->path);
+			msg("mount still busy %s", ap->path);
 			ea->status++;
 		}
 	}
diff --git a/daemon/lookup.c b/daemon/lookup.c
index aeda909..dd620cf 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -969,7 +969,7 @@ next:
 }
 
 /* Return with cache readlock held */
-struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type)
+struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type)
 {
 	struct master_mapent *entry = ap->entry;
 	struct map_source *map;
@@ -980,12 +980,49 @@ struct mapent *lookup_source_mapent(stru
 	master_source_readlock(entry);
 	map = entry->first;
 	while (map) {
+		/*
+		 * Only consider map sources that have been read since
+		 * the map entry was last updated.
+		 */
+		if (ap->entry->age > map->age) {
+			map = map->next;
+			continue;
+		}
+
 		mc = map->mc;
 		cache_readlock(mc);
 		if (type == LKP_DISTINCT)
 			me = cache_lookup_distinct(mc, key);
 		else
+			me = cache_lookup(mc, key);
+		if (me)
+			break;
+		cache_unlock(mc);
+		map = map->next;
+	}
+	pthread_cleanup_pop(1);
+
+	return me;
+}
+
+/* Return with cache readlock held */
+struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type)
+{
+	struct master_mapent *entry = ap->entry;
+	struct map_source *map;
+	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) {
+		mc = map->mc;
+		cache_readlock(mc);
+		if (type == LKP_DISTINCT)
 			me = cache_lookup_distinct(mc, key);
+		else
+			me = cache_lookup(mc, key);
 		if (me)
 			break;
 		cache_unlock(mc);
@@ -1012,8 +1049,10 @@ int lookup_source_close_ioctlfd(struct a
 		cache_readlock(mc);
 		me = cache_lookup_distinct(mc, key);
 		if (me) {
-			close(me->ioctlfd);
-			me->ioctlfd = -1;
+			if (me->ioctlfd != -1) {
+				close(me->ioctlfd);
+				me->ioctlfd = -1;
+			}
 			cache_unlock(mc);
 			ret = 1;
 			break;
diff --git a/include/automount.h b/include/automount.h
index 3192c92..e3ecc75 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -123,8 +123,8 @@ #define CHE_DUPLICATE	0x0020
 
 #define HASHSIZE		77
 #define NEGATIVE_TIMEOUT	10
-#define UMOUNT_RETRIES		50
-#define EXPIRE_RETRIES		25
+#define UMOUNT_RETRIES		6
+#define EXPIRE_RETRIES		3
 
 struct mapent_cache {
 	pthread_rwlock_t rwlock;
@@ -229,6 +229,7 @@ int lookup_ghost(struct autofs_point *ap
 int lookup_nss_mount(struct autofs_point *ap, const char *name, int name_len);
 void lookup_close_lookup(struct autofs_point *ap);
 int lookup_prune_cache(struct autofs_point *ap, time_t age);
+struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type);
 struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type);
 int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key);
 
@@ -475,7 +476,7 @@ int handle_packet_expire_direct(struct a
 int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missing_indirect_t *pkt);
 int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_direct_t *pkt);
 void rm_unwanted(const char *path, int incl, dev_t dev);
-int count_mounts(struct autofs_point *ap, const char *path);
+int count_mounts(const char *path, dev_t dev);
 
 #define state_mutex_lock(ap) \
 do { \
diff --git a/lib/alarm.c b/lib/alarm.c
index 8124796..89c9bc8 100755
--- a/lib/alarm.c
+++ b/lib/alarm.c
@@ -236,9 +236,9 @@ static void *alarm_handler(void *arg)
 			list_del(&current->list);
 			free(current);
 
-			alarm_unlock();
-			st_add_task(ap, ST_EXPIRE);
-			alarm_lock();
+			state_mutex_lock(ap);
+			nextstate(ap->state_pipe[1], ST_EXPIRE);
+			state_mutex_unlock(ap);
 
 			break;
 		}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 3f489ed..08fd34d 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -810,6 +810,54 @@ static int parse_mapent(const char *ent,
 	return (p - ent);
 }
 
+static int mount_subtree_offsets(struct autofs_point *ap, struct mapent_cache *mc, struct mapent *me)
+{
+	struct mapent *mm;
+	char *m_key;
+	int start;
+	char *base, *m_root;
+	char buf[MAX_ERR_BUF];
+
+	mm = me->multi;
+
+	if (!mm)
+		return 1;
+
+	cache_multi_lock(me->parent);
+
+	m_key = mm->key;
+
+	if (*m_key == '/') {
+		m_root = m_key;
+		start = strlen(m_key);
+	} else {
+		start = strlen(ap->path) + strlen(m_key) + 1;
+		m_root = alloca(start + 1);
+		if (!m_root) {
+			char *estr;
+			cache_multi_unlock(me->parent);
+			estr = strerror_r(errno, buf, MAX_ERR_BUF);
+			error(ap->logopt, MODPREFIX "alloca: %s", estr);
+			return 0;
+		}
+		strcpy(m_root, ap->path);
+		strcat(m_root, "/");
+		strcat(m_root, m_key);
+	}
+
+	base = &me->key[start];
+
+	if (!mount_multi_triggers(ap, m_root, me->multi, base)) {
+		cache_multi_unlock(me->parent);
+		error(ap->logopt, MODPREFIX "failed to mount offset triggers");
+		return 0;
+	}
+
+	cache_multi_unlock(me->parent);
+
+	return 1;
+}
+
 /*
  * syntax is:
  *	[-options] location [location] ...
@@ -1085,6 +1133,7 @@ int parse_mount(struct autofs_point *ap,
 			free(options);
 			return 1;
 		}
+
 		cache_multi_unlock(me);
 		cache_unlock(mc);
 
@@ -1093,7 +1142,6 @@ int parse_mount(struct autofs_point *ap,
 		return rv;
 	} else {
 		/* Normal (and non-root multi-mount) entries */
-		struct autofs_point *oap = ap;
 		char *loc;
 		int loclen;
 		int l;
@@ -1197,58 +1245,12 @@ int parse_mount(struct autofs_point *ap,
 		 * If it's a multi-mount insert the triggers
 		 * These are always direct mount triggers so root = ""
 		 */
-		if (ap->submount)
-			oap = ap->parent;
-
-		me = lookup_source_mapent(oap, name, LKP_DISTINCT);
+		cache_readlock(mc);
+		me = cache_lookup_distinct(mc, name);
 		if (me) {
-			struct mapent *mm;
-			char *m_key;
-			int start;
-			char *base, *m_root;
-
-			mc = me->source->mc;
-			mm = me->multi;
-
-			if (!me->multi) {
-				cache_unlock(mc);
-				return rv;
-			}
-
-			m_key = me->multi->key;
-
-			if (*m_key == '/') {
-				m_root = m_key;
-				start = strlen(m_key);
-			} else {
-				start = strlen(ap->path) + strlen(m_key) + 1;
-				pthread_cleanup_push(cache_lock_cleanup, mc);
-				m_root = alloca(start + 1);
-				pthread_cleanup_pop(0);
-				if (!m_root) {
-					char *estr;
-					cache_unlock(mc);
-					estr = strerror_r(errno, buf, MAX_ERR_BUF);
-					error(ap->logopt,
-					      MODPREFIX "alloca: %s", estr);
-					return 1;
-				}
-				strcpy(m_root, ap->path);
-				strcat(m_root, "/");
-				strcat(m_root, m_key);
-			}
-
-			base = &me->key[start];
-
-			cache_multi_lock(mm);
-			if (!mount_multi_triggers(oap, m_root, me->multi, base)) {
-				error(ap->logopt,
-				      MODPREFIX "failed to mount offset triggers");
-				rv = 1;
-			}
-			cache_multi_unlock(mm);
-			cache_unlock(mc);
+			mount_subtree_offsets(ap, mc, me);
 		}
+		cache_unlock(mc);
 	}
 	return rv;
 }

autofs-5.0.1-rc1-premature-submount-expire.patch:
 CHANGELOG       |    1 
 daemon/state.c  |  104 ++++++++++++++++++++++++++++++++++++--------------------
 include/state.h |   14 -------
 3 files changed, 68 insertions(+), 51 deletions(-)

--- NEW FILE autofs-5.0.1-rc1-premature-submount-expire.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index b469121..fc939ad 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,7 @@
 - spelling corrections to release notes (Jeff Moyer).
 - expire individual submounts.
 - add ino_index locking.
+- fix nested submount expiring away when pwd is base of submount.
 
 13/7/2006 autofs-5.0.1 rc1
 --------------------------
diff --git a/daemon/state.c b/daemon/state.c
index 67d8031..d38a64f 100644
--- a/daemon/state.c
+++ b/daemon/state.c
@@ -12,6 +12,8 @@
  *
  * ----------------------------------------------------------------------- */
 
+#include <sys/ioctl.h>
+
 #include "automount.h"
 
 extern pthread_attr_t thread_attr;
@@ -37,6 +39,34 @@ static pthread_mutex_t task_mutex = PTHR
 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); \
+	if (status) \
+		fatal(status); \
+} while (0)
+
+#define st_mutex_unlock() \
+do { \
+	int status = pthread_mutex_unlock(&mutex); \
+	if (status) \
+		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)
@@ -86,7 +116,7 @@ void expire_cleanup(void *arg)
 	struct autofs_point *ap;
 	int statefd;
 	enum states next = ST_INVAL;
-	int success;
+	int success, ret;
 
 	ea = (struct expire_args *) arg;
 	ap = ea->ap;
@@ -112,7 +142,10 @@ void expire_cleanup(void *arg)
 			   pruned or expired everything away,
 			   try to shut down */
 			if (ap->submount && !success) {
-				next = ST_SHUTDOWN_PENDING;
+				if (!ioctl(ap->ioctlfd, AUTOFS_IOC_ASKUMOUNT, &ret)) {
+					if (ret)
+						next = ST_SHUTDOWN_PENDING;
+				}
 				break;
 			}
 
@@ -415,11 +448,14 @@ static unsigned int st_readmap(struct au
 	debug(ap->logopt, "state %d path %s", ap->state, ap->path);
 
 	assert(ap->state == ST_READY);
+	assert(ap->readmap_thread == 0);
+
 	ap->state = ST_READMAP;
 
 	ra = malloc(sizeof(struct readmap_args));
 	if (!ra) {
 		error(ap->logopt, "failed to malloc reamap cond struct");
+		nextstate(ap->state_pipe[1], ST_READY);
 		return 0;
 	}
 
@@ -448,6 +484,8 @@ static unsigned int st_readmap(struct au
 	ap->readmap_thread = thid;
 	st_set_thid(ap, thid);
 
+	pthread_cleanup_push(st_readmap_cleanup, ra);
+
 	ra->signaled = 0;
 	while (!ra->signaled) {
 		status = pthread_cond_wait(&ra->cond, &ra->mutex);
@@ -455,6 +493,8 @@ static unsigned int st_readmap(struct au
 			fatal(status);
 	}
 
+	pthread_cleanup_pop(1);
+
 	return 1;
 }
 
@@ -653,16 +693,12 @@ void st_remove_tasks(struct autofs_point
 	struct state_queue *task, *waiting;
 	int status;
 
-	status = pthread_mutex_lock(&mutex);
-	if (status)
-		fatal(status);
+	st_mutex_lock();
 
 	head = &state_queue;
 
 	if (list_empty(head)) {
-		status = pthread_mutex_unlock(&mutex);
-		if (status)
-			fatal(status);
+		st_mutex_unlock();
 		return;
 	}
 
@@ -692,9 +728,10 @@ void st_remove_tasks(struct autofs_point
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&mutex);
-	if (status)
-		fatal(status);
+	st_mutex_unlock();
+
+	return;
+
 }
 
 static void *do_run_task(void *arg)
@@ -705,9 +742,7 @@ static void *do_run_task(void *arg)
 	unsigned long ret = 1;
 	int status;
  
-	status = pthread_mutex_lock(&task_mutex);
-	if (status)
-		fatal(status);
+	task_mutex_lock();
 
 	task = (struct state_queue *) arg;
 	ap = task->ap;
@@ -718,9 +753,7 @@ static void *do_run_task(void *arg)
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_unlock(&task_mutex);
-	if (status)
-		fatal(status);
+	task_mutex_unlock();
 
 	state_mutex_lock(ap);
 
@@ -764,16 +797,12 @@ static int run_state_task(struct state_q
 	pthread_t thid;
 	int status;
 
-	status = pthread_mutex_lock(&task_mutex);
-	if (status)
-		fatal(status);
+	task_mutex_lock();
 
 	status = pthread_create(&thid, &thread_attr, do_run_task, task);
 	if (status) {
 		error(task->ap->logopt, "error running task");
-		status = pthread_mutex_unlock(&task_mutex);
-		if (status)
-			fatal(status);
+		task_mutex_unlock();
 		return 0;
 	}
 
@@ -784,9 +813,7 @@ static int run_state_task(struct state_q
 			fatal(status);
 	}
 
-	status = pthread_mutex_unlock(&task_mutex);
-	if (status)
-		fatal(status);
+	task_mutex_unlock();
 
 	return 1;
 }
@@ -810,11 +837,10 @@ static void *st_queue_handler(void *arg)
 {
 	struct list_head *head;
 	struct list_head *p;
+	struct timespec wait;
 	int status;
 
-	status = pthread_mutex_lock(&mutex);
-	if (status)
-		fatal(status);
+	st_mutex_lock();
 
 	head = &state_queue;
 
@@ -823,10 +849,17 @@ static void *st_queue_handler(void *arg)
 		 * If the state queue list is empty, wait until an
 		 * entry is added.
 		 */
+		head = &state_queue;
+		wait.tv_sec = time(NULL) + 1;
+		wait.tv_nsec = 0;
+
 		while (list_empty(head)) {
-			status = pthread_cond_wait(&cond, &mutex);
-			if (status)
+			status = pthread_cond_timedwait(&cond, &mutex, &wait);
+			if (status) {
+				if (status == ETIMEDOUT)
+					break;
 				fatal(status);
+			}
 		}
 
 		list_for_each(p, head) {
@@ -850,11 +883,10 @@ static void *st_queue_handler(void *arg)
 		}
 
 		while (1) {
-			struct timespec wait;
-
 			wait.tv_sec = time(NULL) + 1;
 			wait.tv_nsec = 0;
 
+			signaled = 0;
 			while (!signaled) {
 				status = pthread_cond_timedwait(&cond, &mutex, &wait);
 				if (status) {
@@ -863,8 +895,8 @@ static void *st_queue_handler(void *arg)
 					fatal(status);
 				}
 			}
-			signaled = 0;
 
+			head = &state_queue;
 			p = head->next;
 			while (p != head) {
 				struct state_queue *task, *next;
@@ -901,7 +933,6 @@ static void *st_queue_handler(void *arg)
 				/* No more tasks for this queue */
 				if (list_empty(&task->pending)) {
 					list_del(&task->list);
-					/* debug("task complete %p", task); */
 					free(task);
 					continue;
 				}
@@ -911,10 +942,9 @@ static void *st_queue_handler(void *arg)
 							struct state_queue, pending);
 
 				list_del_init(&next->pending);
-				list_add_tail(&next->list, head);
+				list_add_tail(&next->list, p);
 
 				list_del(&task->list);
-				/* debug("task complete %p", task); */
 				free(task);
 			}
 
diff --git a/include/state.h b/include/state.h
index ea4c62a..c756338 100644
--- a/include/state.h
+++ b/include/state.h
@@ -89,18 +89,4 @@ int st_add_task(struct autofs_point *, e
 void st_remove_tasks(struct autofs_point *);
 int st_start_handler(void);
 
-#define st_mutex_lock() \
-do { \
-	int status = pthread_mutex_lock(&mutex); \
-	if (status) \
-		fatal(status); \
-} while (0)
-
-#define st_mutex_unlock() \
-do { \
-	int status = pthread_mutex_unlock(&mutex); \
-	if (status) \
-		fatal(status); \
-} while (0)
-
 #endif


Index: autofs.spec
===================================================================
RCS file: /cvs/dist/rpms/autofs/devel/autofs.spec,v
retrieving revision 1.140
retrieving revision 1.141
diff -u -r1.140 -r1.141
--- autofs.spec	7 Aug 2006 04:59:41 -0000	1.140
+++ autofs.spec	16 Aug 2006 07:27:49 -0000	1.141
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems.
 Name: autofs
 %define version 5.0.1
-%define release 0.rc1.14
+%define release 0.rc1.15
 Version: %{version}
 Release: %{release}
 Epoch: 1
@@ -35,6 +35,12 @@
 Patch22: autofs-5.0.1-rc1-expire-multi-correction.patch
 Patch23: autofs-5.0.1-rc1-sloppyopt-nfs.patch
 Patch24: autofs-5.0.1-rc1-release-notes-spelling.patch
+Patch25: autofs-5.0.1-rc1-expire-individual-submounts.patch
+Patch26: autofs-5.0.1-rc1-ino_index-locking.patch
+Patch27: autofs-5.0.1-rc1-check-offset-mounts-before-umount.patch
+Patch28: autofs-5.0.1-rc1-premature-submount-expire.patch
+Patch29: autofs-5.0.1-rc1-more-expire-rework.patch
+Patch30: autofs-5.0.1-rc1-allow-initial-numeric-in-hostname.patch
 Buildroot: /var/tmp/autofs-tmp
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel
 Prereq: chkconfig
@@ -98,6 +104,12 @@
 %patch22 -p1
 %patch23 -p1
 %patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -154,6 +166,13 @@
 %{_libdir}/autofs/*
 
 %changelog
+* Thu Aug 16 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.15
+- expire individual submounts.
+- add ino_index locking.
+- fix nested submount expiring away when pwd is base of submount.
+- more expire re-work to cope better with shutdown following cthon tests.
+- allow hostname to start with numeric when validating.
+
 * Thu Aug 7 2006 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc1.14
 - remove SIGCHLD handler because it is no longer needed and was
   causing expire problems.




More information about the fedora-cvs-commits mailing list