autofs-5.0.5 - check negative cache much earlier

From: Ian Kent <raven@themaw.net>

There is no need to perform the mount thread create and all the
subsequent code execution if we're only going to exit when we
finally get around to checking the negative cache.
---

 CHANGELOG         |    1 +
 daemon/direct.c   |   13 +++++++++++++
 daemon/indirect.c |   15 +++++++++++++++
 3 files changed, 29 insertions(+), 0 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 6d5f289..aafc69c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -65,6 +65,7 @@
 - fix systemd argument passing.
 - fix get_nfs_info() can incorrectly fail.
 - fix offset directory removal.
+- check negative cache much earlier.
 
 28/06/2011 autofs-5.0.6
 -----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index ddf6cee..7e2f0d7 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1327,6 +1327,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 		logerr("can't find map entry for (%lu,%lu)",
 		    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
 		master_source_unlock(ap->entry);
+		master_mutex_unlock();
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
@@ -1363,6 +1364,18 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 		return 1;
 	}
 
+	/* Check if we recorded a mount fail for this key */
+	if (me->status >= time(NULL)) {
+		ops->send_fail(ap->logopt,
+			       ioctlfd, pkt->wait_queue_token, -ENOENT);
+		ops->close(ap->logopt, ioctlfd);
+		cache_unlock(me->mc);
+		master_source_unlock(ap->entry);
+		master_mutex_unlock();
+		pthread_setcancelstate(state, NULL);
+		return 0;
+	}
+
 	len = strlen(me->key);
 	if (len >= PATH_MAX) {
 		error(ap->logopt, "direct mount path too long %s", me->key);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 909eb1d..f4476dc 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -800,6 +800,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
 	struct pending_args *mt;
 	struct timespec wait;
 	struct timeval now;
+	struct mapent *me;
 	int status, state;
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
@@ -818,6 +819,20 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
 		return 0;
 	}
 
+	/* Check if we recorded a mount fail for this key anywhere */
+	me = lookup_source_mapent(ap, pkt->name, LKP_DISTINCT);
+	if (me) {
+		if (me->status >= time(NULL)) {
+			ops->send_fail(ap->logopt, ap->ioctlfd,
+				       pkt->wait_queue_token, -ENOENT);
+			cache_unlock(me->mc);
+			master_mutex_unlock();
+			pthread_setcancelstate(state, NULL);
+			return 0;
+		}
+		cache_unlock(me->mc);
+	}
+
 	mt = malloc(sizeof(struct pending_args));
 	if (!mt) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
