Blob Blame History Raw
autofs-5.1.7 - refactor umount_multi_triggers()

From: Ian Kent <raven@themaw.net>

Refactor umount_multi_triggers() to try the umount of an offset subtree
in a seperate function.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG    |    1 
 lib/mounts.c |  187 ++++++++++++++++++++++++++++++++--------------------------
 2 files changed, 104 insertions(+), 84 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 3eda995c..5a3bedc1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
 - set offset parent in update_offset_entry().
 - remove redundant variables from mount_autofs_offset().
 - remove unused parameter form do_mount_autofs_offset().
+- refactor umount_multi_triggers().
 
 25/01/2021 autofs-5.1.7
 - make bind mounts propagation slave by default.
diff --git a/lib/mounts.c b/lib/mounts.c
index 8e88182f..5268ba5b 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2496,57 +2496,6 @@ static int do_mount_autofs_offset(struct autofs_point *ap,
 	return mounted;
 }
 
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
-			 const char *root, unsigned int start, const char *base)
-{
-	char path[PATH_MAX + 1];
-	char *offset = path;
-	struct mapent *oe;
-	struct list_head *pos = NULL;
-	unsigned int root_len = strlen(root);
-	int mounted;
-
-	mounted = 0;
-	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
-	while (offset) {
-		char key[PATH_MAX + 1];
-		int key_len = root_len + strlen(offset);
-
-		if (key_len > PATH_MAX) {
-			warn(ap->logopt, "path loo long");
-			goto cont;
-		}
-
-		/* The root offset is always mounted seperately so the
-		 * offset path will always be root + offset.
-		 */
-		strcpy(key, root);
-		strcat(key, offset);
-
-		oe = cache_lookup_distinct(me->mc, key);
-		if (!oe || !oe->mapent)
-			goto cont;
-
-		mounted += do_mount_autofs_offset(ap, oe, root);
-
-		/*
-		 * If re-constructing a multi-mount it's necessary to walk
-		 * into nested mounts, unlike the usual "mount only what's
-		 * needed as you go" behavior.
-		 */
-		if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
-			if (oe->ioctlfd != -1 ||
-			    is_mounted(oe->key, MNTS_REAL))
-				mount_multi_triggers(ap, oe, key, strlen(key), base);
-		}
-cont:
-		offset = cache_get_offset(base,
-				offset, start, &me->multi_list, &pos);
-	}
-
-	return mounted;
-}
-
 static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
 {
 	char *dir, *path;
@@ -2582,7 +2531,10 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
 	return ret;
 }
 
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
+
+static int do_umount_multi_triggers(struct autofs_point *ap,
+				    struct mapent *me, const char *root, const char *base)
 {
 	char path[PATH_MAX + 1];
 	char *offset;
@@ -2612,7 +2564,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
 	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
 		char key[PATH_MAX + 1];
 		int key_len = root_len + strlen(offset);
-		char *oe_base;
 
 		if (mm_base_len > 1)
 			key_len += mm_base_len;
@@ -2632,47 +2583,116 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
 		if (!oe || (strlen(oe->key) - start) == 1)
 			continue;
 
+		left += do_umount_offset(ap, oe, root);
+	}
+
+	return left;
+}
+
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
+{
+	char *oe_base;
+	int left = 0;
+
+	/*
+	 * Check for and umount subtree offsets resulting from
+	 * nonstrict mount fail.
+	 */
+	oe_base = oe->key + strlen(root);
+	left += do_umount_multi_triggers(ap, oe, root, oe_base);
+
+	if (oe->ioctlfd != -1 ||
+	    is_mounted(oe->key, MNTS_REAL)) {
+		left++;
+		return left;
+	}
+
+	debug(ap->logopt, "umount offset %s", oe->key);
+
+	if (umount_autofs_offset(ap, oe)) {
+		warn(ap->logopt, "failed to umount offset");
+		left++;
+	} else {
+		struct stat st;
+		int ret;
+
+		if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
+			return left;
+
 		/*
-		 * Check for and umount subtree offsets resulting from
-		 * nonstrict mount fail.
+		 * An error due to partial directory removal is
+		 * ok so only try and remount the offset if the
+		 * actual mount point still exists.
 		 */
-		oe_base = oe->key + strlen(root);
-		left += umount_multi_triggers(ap, oe, root, oe_base);
+		ret = rmdir_path_offset(ap, oe);
+		if (ret == -1 && !stat(oe->key, &st)) {
+			ret = do_mount_autofs_offset(ap, oe, root);
+			if (ret)
+				left++;
+			/* But we did origianlly create this */
+			oe->flags |= MOUNT_FLAG_DIR_CREATED;
+		}
+	}
+	return left;
+}
 
-		if (oe->ioctlfd != -1 ||
-		    is_mounted(oe->key, MNTS_REAL)) {
-			left++;
-			continue;
+int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
+			 const char *root, unsigned int start, const char *base)
+{
+	char path[PATH_MAX + 1];
+	char *offset = path;
+	struct mapent *oe;
+	struct list_head *pos = NULL;
+	unsigned int root_len = strlen(root);
+	int mounted;
+
+	mounted = 0;
+	offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
+	while (offset) {
+		char key[PATH_MAX + 1];
+		int key_len = root_len + strlen(offset);
+
+		if (key_len > PATH_MAX) {
+			warn(ap->logopt, "path loo long");
+			goto cont;
 		}
 
-		debug(ap->logopt, "umount offset %s", oe->key);
+		/* The root offset is always mounted seperately so the
+		 * offset path will always be root + offset.
+		 */
+		strcpy(key, root);
+		strcat(key, offset);
 
-		if (umount_autofs_offset(ap, oe)) {
-			warn(ap->logopt, "failed to umount offset");
-			left++;
-		} else {
-			struct stat st;
-			int ret;
+		oe = cache_lookup_distinct(me->mc, key);
+		if (!oe || !oe->mapent)
+			goto cont;
 
-			if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
-				continue;
+		mounted += do_mount_autofs_offset(ap, oe, root);
 
-			/*
-			 * An error due to partial directory removal is
-			 * ok so only try and remount the offset if the
-			 * actual mount point still exists.
-			 */
-			ret = rmdir_path_offset(ap, oe);
-			if (ret == -1 && !stat(oe->key, &st)) {
-				ret = do_mount_autofs_offset(ap, oe, root);
-				if (ret)
-					left++;
-				/* But we did origianlly create this */
-				oe->flags |= MOUNT_FLAG_DIR_CREATED;
-			}
+		/*
+		 * If re-constructing a multi-mount it's necessary to walk
+		 * into nested mounts, unlike the usual "mount only what's
+		 * needed as you go" behavior.
+		 */
+		if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
+			if (oe->ioctlfd != -1 ||
+			    is_mounted(oe->key, MNTS_REAL))
+				mount_multi_triggers(ap, oe, key, strlen(key), base);
 		}
+cont:
+		offset = cache_get_offset(base,
+				offset, start, &me->multi_list, &pos);
 	}
 
+	return mounted;
+}
+
+int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
+{
+	int left;
+
+	left = do_umount_multi_triggers(ap, me, root, base);
+
 	if (!left && me->multi == me) {
 		struct mapent_cache *mc = me->mc;
 		int status;
@@ -2871,4 +2891,3 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
 
 	return left;
 }
-