Ian Kent c17a252
autofs-5.1.7 - fix hosts map offset order
Ian Kent c17a252
Ian Kent c17a252
From: Ian Kent <raven@themaw.net>
Ian Kent c17a252
Ian Kent c17a252
Map entry offset paths to be in shortest to longest order but exports
Ian Kent c17a252
from a server could come in any order. If there are a large number of
Ian Kent c17a252
exports this can result in a lot of overhead when adding the offset
Ian Kent c17a252
to the ordered list use to mount the offset during parsing since the
Ian Kent c17a252
path length of exports can cary a lot.
Ian Kent c17a252
Ian Kent c17a252
So leverage the tree implemention to sort the export offsets into
Ian Kent c17a252
shortest to longest order as we go when constructing the mapent from
Ian Kent c17a252
the exports list.
Ian Kent c17a252
Ian Kent c17a252
Signed-off-by: Ian Kent <raven@themaw.net>
Ian Kent c17a252
---
Ian Kent c17a252
 CHANGELOG              |    1 
Ian Kent c17a252
 include/automount.h    |    2 -
Ian Kent c17a252
 include/mounts.h       |    8 +++++
Ian Kent c17a252
 include/rpc_subs.h     |    3 ++
Ian Kent c17a252
 lib/mounts.c           |   57 +++++++++++++++++++++++++++++++++++++--
Ian Kent c17a252
 modules/lookup_hosts.c |   71 ++++++++++++++++++++++++++++++++++++++-----------
Ian Kent c17a252
 6 files changed, 124 insertions(+), 18 deletions(-)
Ian Kent c17a252
Ian Kent c17a252
--- autofs-5.1.7.orig/CHANGELOG
Ian Kent c17a252
+++ autofs-5.1.7/CHANGELOG
Ian Kent c17a252
@@ -74,6 +74,7 @@
Ian Kent c17a252
 - fix offset entries order.
Ian Kent c17a252
 - use mapent tree root for tree_mapent_add_node().
Ian Kent c17a252
 - eliminate redundant cache lookup in tree_mapent_add_node().
Ian Kent c17a252
+- fix hosts map offset order.
Ian Kent c17a252
 
Ian Kent c17a252
 25/01/2021 autofs-5.1.7
Ian Kent c17a252
 - make bind mounts propagation slave by default.
Ian Kent c17a252
--- autofs-5.1.7.orig/include/automount.h
Ian Kent c17a252
+++ autofs-5.1.7/include/automount.h
Ian Kent c17a252
@@ -31,9 +31,9 @@
Ian Kent c17a252
 #include "master.h"
Ian Kent c17a252
 #include "macros.h"
Ian Kent c17a252
 #include "log.h"
Ian Kent c17a252
+#include "mounts.h"
Ian Kent c17a252
 #include "rpc_subs.h"
Ian Kent c17a252
 #include "parse_subs.h"
Ian Kent c17a252
-#include "mounts.h"
Ian Kent c17a252
 #include "dev-ioctl-lib.h"
Ian Kent c17a252
 #include "parse_amd.h"
Ian Kent c17a252
 
Ian Kent c17a252
--- autofs-5.1.7.orig/include/mounts.h
Ian Kent c17a252
+++ autofs-5.1.7/include/mounts.h
Ian Kent c17a252
@@ -52,6 +52,7 @@ extern const unsigned int t_direct;
Ian Kent c17a252
 extern const unsigned int t_offset;
Ian Kent c17a252
 
Ian Kent c17a252
 struct mnt_list;
Ian Kent c17a252
+struct exportinfo;
Ian Kent c17a252
 struct mapent;
Ian Kent c17a252
 
Ian Kent c17a252
 struct tree_ops;
Ian Kent c17a252
@@ -66,6 +67,9 @@ struct tree_node {
Ian Kent c17a252
 #define MNT_LIST(n)		(container_of(n, struct mnt_list, node))
Ian Kent c17a252
 #define MNT_LIST_NODE(ptr)	((struct tree_node *) &((struct mnt_list *) ptr)->node)
Ian Kent c17a252
 
Ian Kent c17a252
+#define EXPORTINFO(n)		(container_of(n, struct exportinfo, node))
Ian Kent c17a252
+#define EXPORT_NODE(ptr)	((struct tree_node *) &((struct exportinfo *) ptr)->node)
Ian Kent c17a252
+
Ian Kent c17a252
 #define MAPENT(n)		(container_of(n, struct mapent, node))
Ian Kent c17a252
 #define MAPENT_NODE(p)		((struct tree_node *) &((struct mapent *) p)->node)
Ian Kent c17a252
 #define MAPENT_ROOT(p)		((struct tree_node *) ((struct mapent *) p)->mm_root)
Ian Kent c17a252
@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct a
Ian Kent c17a252
 void mnts_remove_mount(const char *mp, unsigned int flags);
Ian Kent c17a252
 struct mnt_list *get_mnt_list(const char *path, int include);
Ian Kent c17a252
 unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
Ian Kent c17a252
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr);
Ian Kent c17a252
+void tree_free(struct tree_node *root);
Ian Kent c17a252
 void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
Ian Kent c17a252
 void mnts_put_expire_list(struct list_head *mnts);
Ian Kent c17a252
 void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
Ian Kent c17a252
+struct tree_node *tree_host_root(struct exportinfo *exp);
Ian Kent c17a252
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp);
Ian Kent c17a252
 struct tree_node *tree_mapent_root(struct mapent *me);
Ian Kent c17a252
 int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
Ian Kent c17a252
 int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
Ian Kent c17a252
--- autofs-5.1.7.orig/include/rpc_subs.h
Ian Kent c17a252
+++ autofs-5.1.7/include/rpc_subs.h
Ian Kent c17a252
@@ -23,6 +23,8 @@
Ian Kent c17a252
 #include <linux/nfs2.h>
Ian Kent c17a252
 #include <linux/nfs3.h>
Ian Kent c17a252
 
Ian Kent c17a252
+#include "automount.h"
Ian Kent c17a252
+
Ian Kent c17a252
 #define NFS4_VERSION		4
Ian Kent c17a252
 
Ian Kent c17a252
 /* rpc helper subs */
Ian Kent c17a252
@@ -57,6 +59,7 @@ struct exportinfo {
Ian Kent c17a252
 	char *dir;
Ian Kent c17a252
 	struct hostinfo *hosts;
Ian Kent c17a252
 	struct exportinfo *next;
Ian Kent c17a252
+	struct tree_node node;
Ian Kent c17a252
 };
Ian Kent c17a252
 
Ian Kent c17a252
 struct conn_info {
Ian Kent c17a252
--- autofs-5.1.7.orig/lib/mounts.c
Ian Kent c17a252
+++ autofs-5.1.7/lib/mounts.c
Ian Kent c17a252
@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = {
Ian Kent c17a252
 };
Ian Kent c17a252
 static struct tree_ops *tree_mnt_ops = &mnt_ops;
Ian Kent c17a252
 
Ian Kent c17a252
+static struct tree_node *tree_host_new(void *ptr);
Ian Kent c17a252
+static int tree_host_cmp(struct tree_node *n, void *ptr);
Ian Kent c17a252
+static void tree_host_free(struct tree_node *n);
Ian Kent c17a252
+
Ian Kent c17a252
+static struct tree_ops host_ops = {
Ian Kent c17a252
+	.new = tree_host_new,
Ian Kent c17a252
+	.cmp = tree_host_cmp,
Ian Kent c17a252
+	.free = tree_host_free,
Ian Kent c17a252
+};
Ian Kent c17a252
+static struct tree_ops *tree_host_ops = &host_ops;
Ian Kent c17a252
+
Ian Kent c17a252
 static struct tree_node *tree_mapent_new(void *ptr);
Ian Kent c17a252
 static int tree_mapent_cmp(struct tree_node *n, void *ptr);
Ian Kent c17a252
 static void tree_mapent_free(struct tree_node *n);
Ian Kent c17a252
@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(s
Ian Kent c17a252
 	return NULL;
Ian Kent c17a252
 }
Ian Kent c17a252
 
Ian Kent c17a252
-static void tree_free(struct tree_node *root)
Ian Kent c17a252
+void tree_free(struct tree_node *root)
Ian Kent c17a252
 {
Ian Kent c17a252
 	struct tree_ops *ops = root->ops;
Ian Kent c17a252
 
Ian Kent c17a252
@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node *
Ian Kent c17a252
 	ops->free(root);
Ian Kent c17a252
 }
Ian Kent c17a252
 
Ian Kent c17a252
-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
Ian Kent c17a252
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
Ian Kent c17a252
 {
Ian Kent c17a252
 	int ret;
Ian Kent c17a252
 
Ian Kent c17a252
@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_he
Ian Kent c17a252
 	mnts_hash_mutex_unlock();
Ian Kent c17a252
 }
Ian Kent c17a252
 
Ian Kent c17a252
+struct tree_node *tree_host_root(struct exportinfo *exp)
Ian Kent c17a252
+{
Ian Kent c17a252
+	return tree_root(tree_host_ops, exp);
Ian Kent c17a252
+}
Ian Kent c17a252
+
Ian Kent c17a252
+static struct tree_node *tree_host_new(void *ptr)
Ian Kent c17a252
+{
Ian Kent c17a252
+	struct tree_node *n = EXPORT_NODE(ptr);
Ian Kent c17a252
+
Ian Kent c17a252
+	n->ops = tree_host_ops;
Ian Kent c17a252
+	n->left = NULL;
Ian Kent c17a252
+	n->right = NULL;
Ian Kent c17a252
+
Ian Kent c17a252
+	return n;
Ian Kent c17a252
+}
Ian Kent c17a252
+
Ian Kent c17a252
+static int tree_host_cmp(struct tree_node *n, void *ptr)
Ian Kent c17a252
+{
Ian Kent c17a252
+	struct exportinfo *n_exp = EXPORTINFO(n);
Ian Kent c17a252
+	size_t n_exp_len = strlen(n_exp->dir);
Ian Kent c17a252
+	struct exportinfo *exp = ptr;
Ian Kent c17a252
+	size_t exp_len = strlen(exp->dir);
Ian Kent c17a252
+	int eq;
Ian Kent c17a252
+
Ian Kent c17a252
+	eq = strcmp(exp->dir, n_exp->dir);
Ian Kent c17a252
+	if (!eq)
Ian Kent c17a252
+		return 0;
Ian Kent c17a252
+	return (exp_len < n_exp_len) ? -1 : 1;
Ian Kent c17a252
+}
Ian Kent c17a252
+
Ian Kent c17a252
+static void tree_host_free(struct tree_node *n)
Ian Kent c17a252
+{
Ian Kent c17a252
+	n->ops = NULL;
Ian Kent c17a252
+	n->left = NULL;
Ian Kent c17a252
+	n->right = NULL;
Ian Kent c17a252
+}
Ian Kent c17a252
+
Ian Kent c17a252
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp)
Ian Kent c17a252
+{
Ian Kent c17a252
+	return tree_add_node(root, exp);
Ian Kent c17a252
+}
Ian Kent c17a252
+
Ian Kent c17a252
 struct tree_node *tree_mapent_root(struct mapent *me)
Ian Kent c17a252
 {
Ian Kent c17a252
 	return tree_root(tree_mapent_ops, me);
Ian Kent c17a252
--- autofs-5.1.7.orig/modules/lookup_hosts.c
Ian Kent c17a252
+++ autofs-5.1.7/modules/lookup_hosts.c
Ian Kent c17a252
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma
Ian Kent c17a252
 	return NSS_STATUS_UNKNOWN;
Ian Kent c17a252
 }
Ian Kent c17a252
 
Ian Kent c17a252
+struct work_info {
Ian Kent c17a252
+	char *mapent;
Ian Kent c17a252
+	const char *host;
Ian Kent c17a252
+	int pos;
Ian Kent c17a252
+};
Ian Kent c17a252
+
Ian Kent c17a252
+static int tree_host_work(struct tree_node *n, void *ptr)
Ian Kent c17a252
+{
Ian Kent c17a252
+	struct exportinfo *exp = EXPORTINFO(n);
Ian Kent c17a252
+	struct work_info *wi = ptr;
Ian Kent c17a252
+	int len;
Ian Kent c17a252
+
Ian Kent c17a252
+	if (!wi->pos)
Ian Kent c17a252
+		len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"",
Ian Kent c17a252
+				exp->dir, wi->host, exp->dir);
Ian Kent c17a252
+	else
Ian Kent c17a252
+		len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"",
Ian Kent c17a252
+				exp->dir, wi->host, exp->dir);
Ian Kent c17a252
+	wi->pos += len;
Ian Kent c17a252
+
Ian Kent c17a252
+	return 1;
Ian Kent c17a252
+}
Ian Kent c17a252
+
Ian Kent c17a252
 static char *get_exports(struct autofs_point *ap, const char *host)
Ian Kent c17a252
 {
Ian Kent c17a252
 	char buf[MAX_ERR_BUF];
Ian Kent c17a252
 	char *mapent;
Ian Kent c17a252
 	struct exportinfo *exp, *this;
Ian Kent c17a252
+	struct tree_node *tree = NULL;
Ian Kent c17a252
+	struct work_info wi;
Ian Kent c17a252
 	size_t hostlen = strlen(host);
Ian Kent c17a252
 	size_t mapent_len;
Ian Kent c17a252
-	int len, pos;
Ian Kent c17a252
 
Ian Kent c17a252
 	debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
Ian Kent c17a252
 
Ian Kent c17a252
@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_p
Ian Kent c17a252
 	this = exp;
Ian Kent c17a252
 	mapent_len = 0;
Ian Kent c17a252
 	while (this) {
Ian Kent c17a252
+		struct tree_node *n;
Ian Kent c17a252
+
Ian Kent c17a252
 		mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
Ian Kent c17a252
+
Ian Kent c17a252
+		if (!tree) {
Ian Kent c17a252
+			tree = tree_host_root(this);
Ian Kent c17a252
+			if (!tree) {
Ian Kent c17a252
+				error(ap->logopt, "failed to create exports tree root");
Ian Kent c17a252
+				rpc_exports_free(exp);
Ian Kent c17a252
+				return NULL;
Ian Kent c17a252
+			}
Ian Kent c17a252
+			goto next;
Ian Kent c17a252
+		}
Ian Kent c17a252
+
Ian Kent c17a252
+		n = tree_host_add_node(tree, this);
Ian Kent c17a252
+		if (!n) {
Ian Kent c17a252
+			error(ap->logopt, "failed to add exports tree node");
Ian Kent c17a252
+			tree_free(tree);
Ian Kent c17a252
+			rpc_exports_free(exp);
Ian Kent c17a252
+			return NULL;
Ian Kent c17a252
+		}
Ian Kent c17a252
+next:
Ian Kent c17a252
 		this = this->next;
Ian Kent c17a252
 	}
Ian Kent c17a252
 
Ian Kent c17a252
@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_p
Ian Kent c17a252
 	}
Ian Kent c17a252
 	*mapent = 0;
Ian Kent c17a252
 
Ian Kent c17a252
-	pos = 0;
Ian Kent c17a252
-	this = exp;
Ian Kent c17a252
-	if (this) {
Ian Kent c17a252
-		len = sprintf(mapent, "\"%s\" \"%s:%s\"",
Ian Kent c17a252
-				this->dir, host, this->dir);
Ian Kent c17a252
-		pos += len;
Ian Kent c17a252
-		this = this->next;
Ian Kent c17a252
-	}
Ian Kent c17a252
-
Ian Kent c17a252
-	while (this) {
Ian Kent c17a252
-		len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
Ian Kent c17a252
-				this->dir, host, this->dir);
Ian Kent c17a252
-		pos += len;
Ian Kent c17a252
-		this = this->next;
Ian Kent c17a252
+	wi.mapent = mapent;
Ian Kent c17a252
+	wi.host = host;
Ian Kent c17a252
+	wi.pos = 0;
Ian Kent c17a252
+
Ian Kent c17a252
+	if (!tree) {
Ian Kent c17a252
+		free(mapent);
Ian Kent c17a252
+		mapent = NULL;
Ian Kent c17a252
+	} else {
Ian Kent c17a252
+		tree_traverse_inorder(tree, tree_host_work, &wi;;
Ian Kent c17a252
+		tree_free(tree);
Ian Kent c17a252
 	}
Ian Kent c17a252
 	rpc_exports_free(exp);
Ian Kent c17a252