Blame SOURCES/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch

29d2b9
autofs-5.1.7 - eliminate count_mounts() from expire_proc_indirect()
29d2b9
29d2b9
From: Ian Kent <raven@themaw.net>
29d2b9
29d2b9
The count_mounts() function traverses the directory tree under a given
29d2b9
automount in order to count the number of mounts.
29d2b9
29d2b9
If there are many directories (such as when there is a very large
29d2b9
number of offset trigger mounts) this can take a long time.
29d2b9
29d2b9
Eliminate the call in expire_proc_indirect() by changing the expire
29d2b9
ioctl function to better use the expire return from the kernel.
29d2b9
29d2b9
Signed-off-by: Ian Kent <raven@themaw.net>
29d2b9
---
29d2b9
 CHANGELOG           |    1 +
29d2b9
 daemon/direct.c     |    4 ++--
29d2b9
 daemon/indirect.c   |   10 +++++-----
29d2b9
 lib/dev-ioctl-lib.c |   21 +++++++++++++--------
29d2b9
 4 files changed, 21 insertions(+), 15 deletions(-)
29d2b9
29d2b9
diff --git a/CHANGELOG b/CHANGELOG
29d2b9
index c5619d2e..0b78eb62 100644
29d2b9
--- a/CHANGELOG
29d2b9
+++ b/CHANGELOG
29d2b9
@@ -20,6 +20,7 @@
29d2b9
 - pass mapent_cache to update_offset_entry().
29d2b9
 - fix inconsistent locking in parse_mount().
29d2b9
 - remove unused mount offset list lock functions.
29d2b9
+- eliminate count_mounts() from expire_proc_indirect().
29d2b9
 
29d2b9
 25/01/2021 autofs-5.1.7
29d2b9
 - make bind mounts propagation slave by default.
29d2b9
diff --git a/daemon/direct.c b/daemon/direct.c
29d2b9
index c41c680f..311a98ba 100644
29d2b9
--- a/daemon/direct.c
29d2b9
+++ b/daemon/direct.c
29d2b9
@@ -884,7 +884,7 @@ cont:
29d2b9
 			ioctlfd = me->ioctlfd;
29d2b9
 
29d2b9
 			ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
29d2b9
-			if (ret) {
29d2b9
+			if (ret == 1) {
29d2b9
 				left++;
29d2b9
 				pthread_setcancelstate(cur_state, NULL);
29d2b9
 				continue;
29d2b9
@@ -910,7 +910,7 @@ cont:
29d2b9
 
29d2b9
 		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
29d2b9
 		ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
29d2b9
-		if (ret)
29d2b9
+		if (ret == 1)
29d2b9
 			left++;
29d2b9
 		pthread_setcancelstate(cur_state, NULL);
29d2b9
 	}
29d2b9
diff --git a/daemon/indirect.c b/daemon/indirect.c
29d2b9
index 65cfe4e3..b259ebdc 100644
29d2b9
--- a/daemon/indirect.c
29d2b9
+++ b/daemon/indirect.c
29d2b9
@@ -358,7 +358,6 @@ void *expire_proc_indirect(void *arg)
29d2b9
 	struct expire_args ec;
29d2b9
 	unsigned int how;
29d2b9
 	int offsets, submnts, count;
29d2b9
-	int retries;
29d2b9
 	int ioctlfd, cur_state;
29d2b9
 	int status, ret, left;
29d2b9
 
29d2b9
@@ -496,7 +495,7 @@ void *expire_proc_indirect(void *arg)
29d2b9
 
29d2b9
 		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
29d2b9
 		ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
29d2b9
-		if (ret)
29d2b9
+		if (ret == 1)
29d2b9
 			left++;
29d2b9
 		pthread_setcancelstate(cur_state, NULL);
29d2b9
 	}
29d2b9
@@ -507,10 +506,11 @@ void *expire_proc_indirect(void *arg)
29d2b9
 	 * so we need to umount or unlink them here.
29d2b9
 	 */
29d2b9
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
29d2b9
-	retries = (count_mounts(ap, ap->path, ap->dev) + 1);
29d2b9
-	while (retries--) {
29d2b9
+	while (1) {
29d2b9
 		ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how);
29d2b9
-		if (ret)
29d2b9
+		if (ret != 0 && errno == EAGAIN)
29d2b9
+			break;
29d2b9
+		if (ret == 1)
29d2b9
 			left++;
29d2b9
 	}
29d2b9
 	pthread_setcancelstate(cur_state, NULL);
29d2b9
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
29d2b9
index 7040c3da..e7a1b42a 100644
29d2b9
--- a/lib/dev-ioctl-lib.c
29d2b9
+++ b/lib/dev-ioctl-lib.c
29d2b9
@@ -650,6 +650,7 @@ static int expire(unsigned int logopt,
29d2b9
 {
29d2b9
 	int ret, retries = EXPIRE_RETRIES;
29d2b9
 	unsigned int may_umount;
29d2b9
+	int save_errno = 0;
29d2b9
 
29d2b9
 	while (retries--) {
29d2b9
 		struct timespec tm = {0, 100000000};
29d2b9
@@ -657,9 +658,11 @@ static int expire(unsigned int logopt,
29d2b9
 		/* Ggenerate expire message for the mount. */
29d2b9
 		ret = ioctl(fd, cmd, arg);
29d2b9
 		if (ret == -1) {
29d2b9
+			save_errno = errno;
29d2b9
+
29d2b9
 			/* Mount has gone away */
29d2b9
 			if (errno == EBADF || errno == EINVAL)
29d2b9
-				return 0;
29d2b9
+				break;
29d2b9
 
29d2b9
 			/*
29d2b9
 			 * Other than EAGAIN is an expire error so continue.
29d2b9
@@ -673,14 +676,16 @@ static int expire(unsigned int logopt,
29d2b9
 		nanosleep(&tm, NULL);
29d2b9
 	}
29d2b9
 
29d2b9
-	may_umount = 0;
29d2b9
-	if (ctl.ops->askumount(logopt, ioctlfd, &may_umount))
29d2b9
-		return -1;
29d2b9
-
29d2b9
-	if (!may_umount)
29d2b9
-		return 1;
29d2b9
+	if (!ret || save_errno == EAGAIN) {
29d2b9
+		may_umount = 0;
29d2b9
+		if (!ctl.ops->askumount(logopt, ioctlfd, &may_umount)) {
29d2b9
+			if (!may_umount)
29d2b9
+				ret = 1;
29d2b9
+		}
29d2b9
+	}
29d2b9
+	errno = save_errno;
29d2b9
 
29d2b9
-	return 0;
29d2b9
+	return ret;
29d2b9
 }
29d2b9
 
29d2b9
 static int dev_ioctl_expire(unsigned int logopt,