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