All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Kent <raven@themaw.net>
To: autofs mailing list <autofs@vger.kernel.org>
Subject: [PATCH 28/37] autofs-5.1.2 - add ref counting to struct map_source
Date: Tue, 25 Oct 2016 09:19:54 +0800	[thread overview]
Message-ID: <20161025011954.7778.82851.stgit@pluto.themaw.net> (raw)
In-Reply-To: <20161025010014.7778.69274.stgit@pluto.themaw.net>

amd map format maps that are type "auto" frequently refer to the
current map in their map entries.

While this isn't a problem for relatively small maps it can be very
wasteful for large maps and even more so for maps that have multi-
component keys that trigger type "auto" mounts as they progress down
the directory tree.

So add a reference count in order for amd type "auto" mounts to use
the parent map if it matches.

sun format maps are much less likley to use the same map and if they
do they are usually trivial, one line maps, so it isn't a problem.

But, more importantly, sun format maps need to track recursive inclusion
and inclusion depth for a given map source when plus map inclusion is
used which prevents the map soucre from being shared.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG              |    1 +
 daemon/indirect.c      |    7 +++++-
 include/master.h       |    3 ++
 lib/master.c           |   22 +++++++++++++++++
 modules/mount_autofs.c |   61 ++++++++++++++++++++++++++++++++----------------
 5 files changed, 73 insertions(+), 21 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 6b097ff..5b3d0d1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@ xx/xx/2016 autofs-5.1.3
 - work around sss startup delay.
 - add sss master map wait config option.
 - fix typos in README.amd-maps.
+- add ref counting to struct map_source.
 
 15/06/2016 autofs-5.1.2
 =======================
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 4c32bdb..5d84b89 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -97,7 +97,12 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
 	int ret;
 	int err;
 
-	ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+	/* If the map is being shared the exp_timeout can't be inherited
+	 * from the map source since it may be different so the autofs
+	 * point exp_runfreq must have already been set.
+	 */
+	if (ap->entry->maps->ref <= 1)
+		ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
 
 	if (ops->version && !do_force_unlink) {
 		ap->flags |= MOUNT_FLAG_REMOUNT;
diff --git a/include/master.h b/include/master.h
index 3f97acd..3947cd5 100644
--- a/include/master.h
+++ b/include/master.h
@@ -23,6 +23,7 @@
 #define MAP_FLAG_FORMAT_AMD	0x0001
 
 struct map_source {
+	unsigned int ref;
 	unsigned int flags;
 	char *type;
 	char *format;
@@ -89,6 +90,8 @@ struct map_source *
 master_add_map_source(struct master_mapent *, char *, char *, time_t, int, const char **);
 struct map_source *
 master_find_map_source(struct master_mapent *, const char *, const char *, int, const char **);
+struct map_source *
+master_get_map_source(struct master_mapent *, const char *, const char *, int, const char **);
 void master_free_map_source(struct map_source *, unsigned int);
 struct map_source *
 master_find_source_instance(struct map_source *, const char *, const char *, int, const char **);
diff --git a/lib/master.c b/lib/master.c
index 4c6e79b..fceb5dd 100644
--- a/lib/master.c
+++ b/lib/master.c
@@ -181,6 +181,7 @@ master_add_map_source(struct master_mapent *entry,
 	if (!source)
 		return NULL;
 	memset(source, 0, sizeof(struct map_source));
+	source->ref = 1;
 
 	if (type) {
 		ntype = strdup(type);
@@ -232,6 +233,8 @@ master_add_map_source(struct master_mapent *entry,
 
 		this = __master_find_map_source(entry, type, format, argc, tmpargv);
 		if (this) {
+			error(entry->ap->logopt,
+			      "map source used without taking reference");
 			this->age = age;
 			master_free_map_source(source, 0);
 			master_source_unlock(entry);
@@ -330,8 +333,27 @@ struct map_source *master_find_map_source(struct master_mapent *entry,
 	return source;
 }
 
+struct map_source *
+master_get_map_source(struct master_mapent *entry,
+		      const char *type, const char *format,
+		      int argc, const char **argv)
+{
+	struct map_source *source = NULL;
+
+	master_source_readlock(entry);
+	source = __master_find_map_source(entry, type, format, argc, argv);
+	if (source)
+		source->ref++;
+	master_source_unlock(entry);
+
+	return source;
+}
+
 static void __master_free_map_source(struct map_source *source, unsigned int free_cache)
 {
+	/* instance map sources are not ref counted */
+	if (source->ref && --source->ref)
+		return;
 	if (source->type)
 		free(source->type);
 	if (source->format)
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 0476a09..3ba5271 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -208,18 +208,37 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
 	}
 	if (info->map)
 		argv[0] = info->map;
+
+	if (options) {
+		p = options;
+		while ((p = strchr(p, ',')) != NULL) {
+			if (*p == ',') {
+				*p = '\0';
+				p++;
+			}
+			argv[argc++] = p;
+		}
+	}
+	argv[argc] = NULL;
+
 	/*
-	 * If the parent map format is amd and the format isn't
-	 * specified in the map entry set it from the parent map
-	 * source.
+	 * For amd type "auto" the map is often re-used so check
+	 * if the the parent map can be used and use it if it
+	 * matches.
+	 *
+	 * Also if the parent map format is amd and the format
+	 * isn't specified in the map entry set it from the parent
+	 * map source.
 	 */
-	if (!info->format && ap->entry->maps) {
+	source = NULL;
+	if (ap->entry->maps && ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD) {
 		struct map_source *s = ap->entry->maps;
+
 		/*
 		 * For amd maps, if the format and source type aren't
 		 * specified try and set them from the parent.
 		 */
-		if (s->flags & MAP_FLAG_FORMAT_AMD) {
+		if (!info->format) {
 			info->format = strdup("amd");
 			if (!info->format)
 				warn(ap->logopt, MODPREFIX
@@ -231,23 +250,19 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
 					     "failed to set amd map type");
 			}
 		}
-	}
 
-	if (options) {
-		p = options;
-		while ((p = strchr(p, ',')) != NULL) {
-			if (*p == ',') {
-				*p = '\0';
-				p++;
-			}
-			argv[argc++] = p;
-		}
+		source = master_get_map_source(ap->entry,
+					       info->type, info->format,
+					       argc, argv);
+		if (source)
+			entry->maps = source;
 	}
-	argv[argc] = NULL;
 
-	source = master_add_map_source(entry,
-				       info->type, info->format,
-				       monotonic_time(NULL), argc, argv);
+	if (!source)
+		source = master_add_map_source(entry,
+					       info->type, info->format,
+					       monotonic_time(NULL),
+					       argc, argv);
 	if (!source) {
 		error(ap->logopt,
 		      MODPREFIX "failed to add map source to entry");
@@ -256,7 +271,13 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
 		return 1;
 	}
 	free_map_type_info(info);
-	source->exp_timeout = timeout;
+	/* The exp_timeout can't be inherited if the map is shared, so
+	 * the autofs point exp_runfreq must be set here.
+	 */
+	if (source->ref <= 1)
+		source->exp_timeout = timeout;
+	else
+		nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
 
 	mounts_mutex_lock(ap);
 

--
To unsubscribe from this list: send the line "unsubscribe autofs" in

  parent reply	other threads:[~2016-10-25  1:19 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-25  1:17 [PATCH 00/37] Current patch queue for review Ian Kent
2016-10-25  1:17 ` [PATCH 01/37] autofs-5.1.2 - fix release date in CHANGELOG Ian Kent
2016-10-25  1:17 ` [PATCH 02/37] autofs-5.1.2 - build: check for clock_gettime in librt Ian Kent
2016-10-25  1:17 ` [PATCH 03/37] autofs-5.1.2 - Fix compiler warning in try_remount() Ian Kent
2016-10-25  1:17 ` [PATCH 04/37] autofs-5.1.2 - Drop redundant \n in logerr() Ian Kent
2016-10-25  1:17 ` [PATCH 05/37] autofs-5.1.2 - Fix size arg of fgets(3) Ian Kent
2016-10-25  1:17 ` [PATCH 06/37] autofs-5.1.2 - fix libtirpc detection with -Wl, --as-needed Ian Kent
2016-10-25  1:18 ` [PATCH 07/37] autofs-5.1.2 - Fix a typo in CREDITS Ian Kent
2016-10-25  1:18 ` [PATCH 08/37] autofs-5.1.2 - Change .requestor to .requester for consistency Ian Kent
2016-10-25  1:18 ` [PATCH 09/37] autofs-5.1.2 - fix file map changed check Ian Kent
2016-10-25  1:18 ` [PATCH 10/37] autofs-5.1.2 - Remove unused local 2KB buffer Ian Kent
2016-10-25  1:18 ` [PATCH 11/37] autofs-5.1.2 - Fix typos in error messages Ian Kent
2016-10-25  1:18 ` [PATCH 12/37] autofs-5.1.2 - Fix fgets(3) size argument (another one) Ian Kent
2016-10-25  1:18 ` [PATCH 13/37] autofs-5.1.2 - fix short memory allocation in lookup_amd_instance() Ian Kent
2016-10-25  1:18 ` [PATCH 14/37] autofs-5.1.2 - fix count_mounts() function Ian Kent
2016-10-25  1:18 ` [PATCH 15/37] autofs-5.1.2 - configure: add cache variable for Linux proc filesystem check Ian Kent
2016-10-25  1:18 ` [PATCH 16/37] autofs-5.1.2 - Avoid local variable name shadowing another Ian Kent
2016-10-25  1:18 ` [PATCH 17/37] autofs-5.1.2 - fix typo in MOUNT_FLAG_GHOST comment Ian Kent
2016-10-25  1:19 ` [PATCH 18/37] autofs-5.1.2 - fix cachefs parse message not being logged Ian Kent
2016-10-25  1:19 ` [PATCH 19/37] autofs-5.1.2 - fix argc off by one in mount_autofs.c Ian Kent
2016-10-25  1:19 ` [PATCH 20/37] autofs-5.1.2 - fix _strncmp() usage Ian Kent
2016-10-25  1:19 ` [PATCH 21/37] autofs-5.1.1 - fix create_client() RPC client handling Ian Kent
2016-10-25  1:19 ` [PATCH 22/37] autofs-5.1.2 - update and add README for old autofs schema Ian Kent
2016-10-25  1:19 ` [PATCH 23/37] autofs-5.1.2 - wait for master map available at start Ian Kent
2016-10-25  1:19 ` [PATCH 24/37] autofs-5.1.2 - add master read wait option Ian Kent
2016-10-25  1:19 ` [PATCH 25/37] autofs-5.1.2 - work around sss startup delay Ian Kent
2016-10-25  1:19 ` [PATCH 26/37] autofs-5.1.2 - add sss master map wait config option Ian Kent
2016-10-25  1:19 ` [PATCH 27/37] autofs-5.1.2 - fix typos in README.amd-maps Ian Kent
2016-10-25  1:19 ` Ian Kent [this message]
2016-10-25  1:19 ` [PATCH 29/37] autofs-5.1.2 - add support for amd browsable option Ian Kent
2016-10-25  1:20 ` [PATCH 30/37] autofs-5.1.2 - add function conf_amd_get_map_name() Ian Kent
2016-10-25  1:20 ` [PATCH 31/37] autofs-5.1.2 - add function conf_amd_get_mount_paths() Ian Kent
2016-10-25  1:20 ` [PATCH 32/37] autofs-5.1.2 - include amd mount section mounts in master mounts list Ian Kent
2016-10-25  1:20 ` [PATCH 33/37] autofs-5.1.2 - check for conflicting amd section mounts Ian Kent
2016-10-25  1:20 ` [PATCH 34/37] autofs-5.1.2 - add function conf_get_map_options() Ian Kent
2016-10-25  1:20 ` [PATCH 35/37] autofs-5.1.2 - capture cache option and its settings during parsing Ian Kent
2016-10-25  1:20 ` [PATCH 36/37] autofs-5.1.2 - handle map_option cache for top level mounts Ian Kent
2016-10-25  1:20 ` [PATCH 37/37] autofs-5.1.2 - handle amd cache option all in amd type auto mounts Ian Kent
2016-11-04  8:53 ` [PATCH 00/37] Current patch queue for review Ian Kent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161025011954.7778.82851.stgit@pluto.themaw.net \
    --to=raven@themaw.net \
    --cc=autofs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.