Blame SOURCES/autofs-5.1.7-fix-hosts-map-offset-order.patch

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