Blob Blame History Raw
autofs-5.0.5 - fix cache_init() on source re-read

From: Ian Kent <raven@themaw.net>

The master map entry cache is released and re-allocated for each
map source upon master map re-read. This is done without holding
the master map entry write lock and, when there are many master
map entries, could lead to a race because other activities can be
underway concurrently. In this case then we must either use
additional expensive exclusive locking or not do the cache
re-recreate.

So the question really becomes what do we have to gain by releasing
and re-creating the cache since we spend a fairly significant amount
of effort on pruning stale entries during ongoing operation already.

This patch moves the allocation of the map entry cache (belonging to
the map source) into the function used to add the map source to the
master map entry and does not release and re-create the cache if the
source already exists for the given master map entry.
---

 CHANGELOG              |    1 +
 lib/master.c           |    6 ++++++
 lib/master_parse.y     |   10 ----------
 modules/mount_autofs.c |    8 --------
 4 files changed, 7 insertions(+), 18 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -38,6 +38,7 @@
 - fix parse_sun() module init.
 - dont check null cache on expire.
 - fix null cache race.
+- fix cache_init() on source re-read.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/lib/master.c
+++ autofs-5.0.5/lib/master.c
@@ -188,6 +188,12 @@ master_add_map_source(struct master_mape
 	source->argc = argc;
 	source->argv = tmpargv;
 
+	source->mc = cache_init(entry->ap, source);
+	if (!source->mc) {
+		master_free_map_source(source, 0);
+		return NULL;
+	}
+
 	master_source_writelock(entry);
 
 	if (!entry->maps) {
--- autofs-5.0.5.orig/lib/master_parse.y
+++ autofs-5.0.5/lib/master_parse.y
@@ -830,16 +830,6 @@ int master_parse_entry(const char *buffe
 		return 0;
 	}
 
-	if (!source->mc) {
-		source->mc = cache_init(entry->ap, source);
-		if (!source->mc) {
-			error(m_logopt, "failed to init source cache");
-			if (new)
-				master_free_mapent(new);
-			local_free_vars();
-			return 0;
-		}
-	}
 	source->master_line = lineno;
 
 	entry->age = age;
--- autofs-5.0.5.orig/modules/mount_autofs.c
+++ autofs-5.0.5/modules/mount_autofs.c
@@ -200,14 +200,6 @@ int mount_mount(struct autofs_point *ap,
 	}
 	free_map_type_info(info);
 
-	source->mc = cache_init(entry->ap, source);
-	if (!source->mc) {
-		error(ap->logopt, MODPREFIX "failed to init source cache");
-		master_free_map_source(source, 0);
-		master_free_mapent(entry);
-		return 1;
-	}
-
 	mounts_mutex_lock(ap);
 
 	if (handle_mounts_startup_cond_init(&suc)) {