Blame SOURCES/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch

beb904
autofs-5.1.7 - dont use realloc in host exports list processing
beb904
beb904
From: Ian Kent <raven@themaw.net>
beb904
beb904
If a server exports list is very large calling realloc(3) for each
beb904
export is slow. It's better to traverse the exports list twice, once
beb904
to calculate the length of the mapent then allocate the memory and
beb904
traverse the exports list again to construct the mapent.
beb904
beb904
Signed-off-by: Ian Kent <raven@themaw.net>
beb904
---
beb904
 CHANGELOG              |    1 +
beb904
 modules/lookup_hosts.c |   59 +++++++++++++++++++++---------------------------
beb904
 2 files changed, 27 insertions(+), 33 deletions(-)
beb904
beb904
--- autofs-5.1.4.orig/CHANGELOG
beb904
+++ autofs-5.1.4/CHANGELOG
beb904
@@ -1,6 +1,7 @@
beb904
 
beb904
 - add xdr_exports().
beb904
 - remove mount.x and rpcgen dependencies.
beb904
+- dont use realloc in host exports list processing.
beb904
 
beb904
 xx/xx/2018 autofs-5.1.5
beb904
 - fix flag file permission.
beb904
--- autofs-5.1.4.orig/modules/lookup_hosts.c
beb904
+++ autofs-5.1.4/modules/lookup_hosts.c
beb904
@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_p
beb904
 	char buf[MAX_ERR_BUF];
beb904
 	char *mapent;
beb904
 	struct exportinfo *exp, *this;
beb904
+	size_t hostlen = strlen(host);
beb904
+	size_t mapent_len;
beb904
 
beb904
 	debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
beb904
 
beb904
 	exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);
beb904
 
beb904
-	mapent = NULL;
beb904
 	this = exp;
beb904
+	mapent_len = 0;
beb904
 	while (this) {
beb904
-		if (mapent) {
beb904
-			int len = strlen(mapent) + 1;
beb904
+		mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
beb904
+		this = this->next;
beb904
+	}
beb904
 
beb904
-			len += strlen(host) + 2*(strlen(this->dir) + 2) + 3;
beb904
-			mapent = realloc(mapent, len);
beb904
-			if (!mapent) {
beb904
-				char *estr;
beb904
-				estr = strerror_r(errno, buf, MAX_ERR_BUF);
beb904
-				error(ap->logopt, MODPREFIX "malloc: %s", estr);
beb904
-				rpc_exports_free(exp);
beb904
-				return NULL;
beb904
-			}
beb904
-			strcat(mapent, " \"");
beb904
-			strcat(mapent, this->dir);
beb904
-			strcat(mapent, "\"");
beb904
-		} else {
beb904
-			int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3;
beb904
-
beb904
-			mapent = malloc(len);
beb904
-			if (!mapent) {
beb904
-				char *estr;
beb904
-				estr = strerror_r(errno, buf, MAX_ERR_BUF);
beb904
-				error(ap->logopt, MODPREFIX "malloc: %s", estr);
beb904
-				rpc_exports_free(exp);
beb904
-				return NULL;
beb904
-			}
beb904
+	mapent = malloc(mapent_len + 1);
beb904
+	if (!mapent) {
beb904
+		char *estr;
beb904
+		estr = strerror_r(errno, buf, MAX_ERR_BUF);
beb904
+		error(ap->logopt, MODPREFIX "malloc: %s", estr);
beb904
+		error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
beb904
+		rpc_exports_free(exp);
beb904
+		return NULL;
beb904
+	}
beb904
+	*mapent = 0;
beb904
+
beb904
+	this = exp;
beb904
+	while (this) {
beb904
+		if (!*mapent)
beb904
 			strcpy(mapent, "\"");
beb904
-			strcat(mapent, this->dir);
beb904
-			strcat(mapent, "\"");
beb904
-		}
beb904
+		else
beb904
+			strcat(mapent, " \"");
beb904
+		strcat(mapent, this->dir);
beb904
+		strcat(mapent, "\"");
beb904
+
beb904
 		strcat(mapent, " \"");
beb904
 		strcat(mapent, host);
beb904
 		strcat(mapent, ":");
beb904
@@ -137,9 +133,6 @@ static char *get_exports(struct autofs_p
beb904
 	}
beb904
 	rpc_exports_free(exp);
beb904
 
beb904
-	if (!mapent)
beb904
-		error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
beb904
-
beb904
 	return mapent;
beb904
 }
beb904