Blame SOURCES/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch

49b67f
autofs-5.1.7 - eliminate cache_lookup_offset() usage
49b67f
49b67f
From: Ian Kent <raven@themaw.net>
49b67f
49b67f
The function cache_lookup_offset() will do a linear search when
49b67f
looking for an offset. If the number of offsets is large this
49b67f
can be a lot of overhead.
49b67f
49b67f
But it's possible to use the information already present where
49b67f
this is called to to do a hashed lookup instead.
49b67f
49b67f
Signed-off-by: Ian Kent <raven@themaw.net>
49b67f
---
49b67f
 CHANGELOG           |    1 
49b67f
 lib/mounts.c        |   82 +++++++++++++++++++++++++++++++++-------------------
49b67f
 modules/parse_sun.c |   77 ++++++++++++++++++++++++++++++------------------
49b67f
 3 files changed, 102 insertions(+), 58 deletions(-)
49b67f
49b67f
--- autofs-5.1.4.orig/CHANGELOG
49b67f
+++ autofs-5.1.4/CHANGELOG
49b67f
@@ -4,6 +4,7 @@
49b67f
 - dont use realloc in host exports list processing.
49b67f
 - use sprintf() when constructing hosts mapent.
49b67f
 - fix mnts_remove_amdmount() uses wrong list.
49b67f
+- eliminate cache_lookup_offset() usage.
49b67f
 
49b67f
 xx/xx/2018 autofs-5.1.5
49b67f
 - fix flag file permission.
49b67f
--- autofs-5.1.4.orig/lib/mounts.c
49b67f
+++ autofs-5.1.4/lib/mounts.c
49b67f
@@ -2489,24 +2489,27 @@ int mount_multi_triggers(struct autofs_p
49b67f
 	char *offset = path;
49b67f
 	struct mapent *oe;
49b67f
 	struct list_head *pos = NULL;
49b67f
-	unsigned int fs_path_len;
49b67f
+	unsigned int root_len = strlen(root);
49b67f
 	int mounted;
49b67f
 
49b67f
-	fs_path_len = start + strlen(base);
49b67f
-	if (fs_path_len > PATH_MAX)
49b67f
-		return -1;
49b67f
-
49b67f
 	mounted = 0;
49b67f
 	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos;;
49b67f
 	while (offset) {
49b67f
-		int plen = fs_path_len + strlen(offset);
49b67f
+		char key[PATH_MAX + 1];
49b67f
+		int key_len = root_len + strlen(offset);
49b67f
 
49b67f
-		if (plen > PATH_MAX) {
49b67f
+		if (key_len > PATH_MAX) {
49b67f
 			warn(ap->logopt, "path loo long");
49b67f
 			goto cont;
49b67f
 		}
49b67f
 
49b67f
-		oe = cache_lookup_offset(base, offset, start, &me->multi_list);
49b67f
+		/* The root offset is always mounted seperately so the
49b67f
+		 * offset path will always be root + offset.
49b67f
+		 */
49b67f
+		strcpy(key, root);
49b67f
+		strcat(key, offset);
49b67f
+
49b67f
+		oe = cache_lookup_distinct(me->mc, key);
49b67f
 		if (!oe || !oe->mapent)
49b67f
 			goto cont;
49b67f
 
49b67f
@@ -2519,12 +2522,8 @@ int mount_multi_triggers(struct autofs_p
49b67f
 		 */
49b67f
 		if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
49b67f
 			if (oe->ioctlfd != -1 ||
49b67f
-			    is_mounted(oe->key, MNTS_REAL)) {
49b67f
-				char oe_root[PATH_MAX + 1];
49b67f
-				strcpy(oe_root, root);
49b67f
-				strcat(oe_root, offset); 
49b67f
-				mount_multi_triggers(ap, oe, oe_root, strlen(oe_root), base);
49b67f
-			}
49b67f
+			    is_mounted(oe->key, MNTS_REAL))
49b67f
+				mount_multi_triggers(ap, oe, key, strlen(key), base);
49b67f
 		}
49b67f
 cont:
49b67f
 		offset = cache_get_offset(base,
49b67f
@@ -2578,6 +2577,8 @@ int umount_multi_triggers(struct autofs_
49b67f
 	const char o_root[] = "/";
49b67f
 	const char *mm_base;
49b67f
 	int left, start;
49b67f
+	unsigned int root_len;
49b67f
+	unsigned int mm_base_len;
49b67f
 
49b67f
 	left = 0;
49b67f
 	start = strlen(root);
49b67f
@@ -2591,11 +2592,28 @@ int umount_multi_triggers(struct autofs_
49b67f
 
49b67f
 	pos = NULL;
49b67f
 	offset = path;
49b67f
+	root_len = start;
49b67f
+	mm_base_len = strlen(mm_base);
49b67f
 
49b67f
 	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
49b67f
+		char key[PATH_MAX + 1];
49b67f
+		int key_len = root_len + strlen(offset);
49b67f
 		char *oe_base;
49b67f
 
49b67f
-		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
49b67f
+		if (mm_base_len > 1)
49b67f
+			key_len += mm_base_len;
49b67f
+
49b67f
+		if (key_len > PATH_MAX) {
49b67f
+			warn(ap->logopt, "path loo long");
49b67f
+			continue;
49b67f
+		}
49b67f
+
49b67f
+		strcpy(key, root);
49b67f
+		if (mm_base_len > 1)
49b67f
+			strcat(key, mm_base);
49b67f
+		strcat(key, offset);
49b67f
+
49b67f
+		oe = cache_lookup_distinct(me->mc, key);
49b67f
 		/* root offset is a special case */
49b67f
 		if (!oe || (strlen(oe->key) - start) == 1)
49b67f
 			continue;
49b67f
@@ -2680,13 +2698,14 @@ int clean_stale_multi_triggers(struct au
49b67f
 	char *root;
49b67f
 	char mm_top[PATH_MAX + 1];
49b67f
 	char path[PATH_MAX + 1];
49b67f
-	char buf[MAX_ERR_BUF];
49b67f
 	char *offset;
49b67f
 	struct mapent *oe;
49b67f
 	struct list_head *mm_root, *pos;
49b67f
 	const char o_root[] = "/";
49b67f
 	const char *mm_base;
49b67f
 	int left, start;
49b67f
+	unsigned int root_len;
49b67f
+	unsigned int mm_base_len;
49b67f
 	time_t age;
49b67f
 
49b67f
 	if (top)
49b67f
@@ -2714,14 +2733,30 @@ int clean_stale_multi_triggers(struct au
49b67f
 
49b67f
 	pos = NULL;
49b67f
 	offset = path;
49b67f
+	root_len = start;
49b67f
+	mm_base_len = strlen(mm_base);
49b67f
 	age = me->multi->age;
49b67f
 
49b67f
 	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
49b67f
+		char key[PATH_MAX + 1];
49b67f
+		int key_len = root_len + strlen(offset);
49b67f
 		char *oe_base;
49b67f
-		char *key;
49b67f
 		int ret;
49b67f
 
49b67f
-		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
49b67f
+		if (mm_base_len > 1)
49b67f
+			key_len += mm_base_len;
49b67f
+
49b67f
+		if (key_len > PATH_MAX) {
49b67f
+			warn(ap->logopt, "path loo long");
49b67f
+			continue;
49b67f
+		}
49b67f
+
49b67f
+		strcpy(key, root);
49b67f
+		if (mm_base_len > 1)
49b67f
+			strcat(key, mm_base);
49b67f
+		strcat(key, offset);
49b67f
+
49b67f
+		oe = cache_lookup_distinct(me->mc, key);
49b67f
 		/* root offset is a special case */
49b67f
 		if (!oe || (strlen(oe->key) - start) == 1)
49b67f
 			continue;
49b67f
@@ -2772,14 +2807,6 @@ int clean_stale_multi_triggers(struct au
49b67f
 			}
49b67f
 		}
49b67f
 
49b67f
-		key = strdup(oe->key);
49b67f
-		if (!key) {
49b67f
-	                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
49b67f
-		        error(ap->logopt, "malloc: %s", estr);
49b67f
-			left++;
49b67f
-			continue;
49b67f
-		}
49b67f
-
49b67f
 		debug(ap->logopt, "umount offset %s", oe->key);
49b67f
 
49b67f
 		if (umount_autofs_offset(ap, oe)) {
49b67f
@@ -2794,7 +2821,6 @@ int clean_stale_multi_triggers(struct au
49b67f
 				if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
49b67f
 					error(ap->logopt,
49b67f
 					     "failed to delete offset key %s", key);
49b67f
-				free(key);
49b67f
 				continue;
49b67f
 			}
49b67f
 
49b67f
@@ -2810,7 +2836,6 @@ int clean_stale_multi_triggers(struct au
49b67f
 					left++;
49b67f
 					/* But we did origianlly create this */
49b67f
 					oe->flags |= MOUNT_FLAG_DIR_CREATED;
49b67f
-					free(key);
49b67f
 					continue;
49b67f
 				}
49b67f
 				/*
49b67f
@@ -2828,7 +2853,6 @@ int clean_stale_multi_triggers(struct au
49b67f
 				error(ap->logopt,
49b67f
 				     "failed to delete offset key %s", key);
49b67f
 		}
49b67f
-		free(key);
49b67f
 	}
49b67f
 
49b67f
 	return left;
49b67f
--- autofs-5.1.4.orig/modules/parse_sun.c
49b67f
+++ autofs-5.1.4/modules/parse_sun.c
49b67f
@@ -1088,6 +1088,8 @@ static void cleanup_multi_triggers(struc
49b67f
 	struct list_head *mm_root, *pos;
49b67f
 	const char o_root[] = "/";
49b67f
 	const char *mm_base;
49b67f
+	unsigned int root_len;
49b67f
+	unsigned int mm_base_len;
49b67f
 
49b67f
 	mm_root = &me->multi->multi_list;
49b67f
 
49b67f
@@ -1097,16 +1099,31 @@ static void cleanup_multi_triggers(struc
49b67f
 		mm_base = base;
49b67f
 
49b67f
 	pos = NULL;
49b67f
+	root_len = strlen(root);
49b67f
+	mm_base_len = strlen(mm_base);
49b67f
 
49b67f
 	/* Make sure "none" of the offsets have an active mount. */
49b67f
 	while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) {
49b67f
-		oe = cache_lookup_offset(mm_base, poffset, start, &me->multi_list);
49b67f
-		/* root offset is a special case */
49b67f
-		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
49b67f
+		unsigned int path_len = root_len + strlen(poffset);
49b67f
+
49b67f
+		if (mm_base_len > 1)
49b67f
+			path_len += mm_base_len;
49b67f
+
49b67f
+		if (path_len > PATH_MAX) {
49b67f
+			warn(ap->logopt, "path loo long");
49b67f
 			continue;
49b67f
+		}
49b67f
 
49b67f
 		strcpy(path, root);
49b67f
+		if (mm_base_len > 1)
49b67f
+			strcat(path, mm_base);
49b67f
 		strcat(path, poffset);
49b67f
+
49b67f
+		oe = cache_lookup_distinct(me->mc, path);
49b67f
+		/* root offset is a special case */
49b67f
+		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
49b67f
+			continue;
49b67f
+
49b67f
 		if (umount(path)) {
49b67f
 			error(ap->logopt, "error recovering from mount fail");
49b67f
 			error(ap->logopt, "cannot umount offset %s", path);
49b67f
@@ -1119,17 +1136,14 @@ static void cleanup_multi_triggers(struc
49b67f
 static int mount_subtree(struct autofs_point *ap, struct mapent *me,
49b67f
 			 const char *name, char *loc, char *options, void *ctxt)
49b67f
 {
49b67f
-	struct mapent *mm;
49b67f
 	struct mapent *ro;
49b67f
 	char *mm_root, *mm_base, *mm_key;
49b67f
-	const char *mnt_root;
49b67f
-	unsigned int mm_root_len, mnt_root_len;
49b67f
+	unsigned int mm_root_len;
49b67f
 	int start, ret = 0, rv;
49b67f
 
49b67f
 	rv = 0;
49b67f
 
49b67f
-	mm = me->multi;
49b67f
-	mm_key = mm->key;
49b67f
+	mm_key = me->multi->key;
49b67f
 
49b67f
 	if (*mm_key == '/') {
49b67f
 		mm_root = mm_key;
49b67f
@@ -1143,20 +1157,26 @@ static int mount_subtree(struct autofs_p
49b67f
 	}
49b67f
 	mm_root_len = strlen(mm_root);
49b67f
 
49b67f
-	mnt_root = mm_root;
49b67f
-	mnt_root_len = mm_root_len;
49b67f
-
49b67f
 	if (me == me->multi) {
49b67f
+		char key[PATH_MAX + 1];
49b67f
+
49b67f
+		if (mm_root_len + 1 > PATH_MAX) {
49b67f
+			warn(ap->logopt, "path loo long");
49b67f
+			return 1;
49b67f
+		}
49b67f
+
49b67f
 		/* name = NULL */
49b67f
 		/* destination = mm_root */
49b67f
 		mm_base = "/";
49b67f
 
49b67f
+		strcpy(key, mm_root);
49b67f
+		strcat(key, mm_base);
49b67f
+
49b67f
 		/* Mount root offset if it exists */
49b67f
-		ro = cache_lookup_offset(mm_base, mm_base, strlen(mm_root), &me->multi_list);
49b67f
+		ro = cache_lookup_distinct(me->mc, key);
49b67f
 		if (ro) {
49b67f
-			char *myoptions, *ro_loc, *tmp;
49b67f
+			char *myoptions, *ro_loc;
49b67f
 			int namelen = name ? strlen(name) : 0;
49b67f
-			const char *root;
49b67f
 			int ro_len;
49b67f
 
49b67f
 			myoptions = NULL;
49b67f
@@ -1174,13 +1194,7 @@ static int mount_subtree(struct autofs_p
49b67f
 			if (ro_loc)
49b67f
 				ro_len = strlen(ro_loc);
49b67f
 
49b67f
-			tmp = alloca(mnt_root_len + 2);
49b67f
-			strcpy(tmp, mnt_root);
49b67f
-			tmp[mnt_root_len] = '/';
49b67f
-			tmp[mnt_root_len + 1] = '\0';
49b67f
-			root = tmp;
49b67f
-
49b67f
-			rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt);
49b67f
+			rv = sun_mount(ap, key, name, namelen, ro_loc, ro_len, myoptions, ctxt);
49b67f
 
49b67f
 			free(myoptions);
49b67f
 			if (ro_loc)
49b67f
@@ -1188,11 +1202,11 @@ static int mount_subtree(struct autofs_p
49b67f
 		}
49b67f
 
49b67f
 		if (ro && rv == 0) {
49b67f
-			ret = mount_multi_triggers(ap, me, mnt_root, start, mm_base);
49b67f
+			ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
49b67f
 			if (ret == -1) {
49b67f
 				error(ap->logopt, MODPREFIX
49b67f
 					 "failed to mount offset triggers");
49b67f
-				cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
49b67f
+				cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
49b67f
 				return 1;
49b67f
 			}
49b67f
 		} else if (rv <= 0) {
49b67f
@@ -1208,24 +1222,29 @@ static int mount_subtree(struct autofs_p
49b67f
 		int loclen = strlen(loc);
49b67f
 		int namelen = strlen(name);
49b67f
 
49b67f
-		mnt_root = name;
49b67f
-
49b67f
 		/* name = mm_root + mm_base */
49b67f
 		/* destination = mm_root + mm_base = name */
49b67f
 		mm_base = &me->key[start];
49b67f
 
49b67f
-		rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt);
49b67f
+		rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt);
49b67f
 		if (rv == 0) {
49b67f
-			ret = mount_multi_triggers(ap, me->multi, mnt_root, start, mm_base);
49b67f
+			ret = mount_multi_triggers(ap, me->multi, name, start, mm_base);
49b67f
 			if (ret == -1) {
49b67f
 				error(ap->logopt, MODPREFIX
49b67f
 					 "failed to mount offset triggers");
49b67f
-				cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
49b67f
+				cleanup_multi_triggers(ap, me, name, start, mm_base);
49b67f
 				return 1;
49b67f
 			}
49b67f
 		} else if (rv < 0) {
49b67f
-			char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
49b67f
+			char mm_root_base[PATH_MAX + 1];
49b67f
+			unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1;
49b67f
 	
49b67f
+			if (mm_root_base_len > PATH_MAX) {
49b67f
+				warn(ap->logopt, MODPREFIX "path too long");
49b67f
+				cache_delete_offset_list(me->mc, name);
49b67f
+				return 1;
49b67f
+			}
49b67f
+
49b67f
 			strcpy(mm_root_base, mm_root);
49b67f
 			strcat(mm_root_base, mm_base);
49b67f