You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.3 KiB
140 lines
4.3 KiB
3 years ago
|
autofs-5.1.8 - fix kernel mount status notification
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
The status return for attempted mount notification is not done
|
||
|
correctly in some cases leading to a status being sent to the
|
||
|
kernel multiple times or the send causing an error.
|
||
|
|
||
|
We must send a status to the kernel but it needs to be the correct
|
||
|
one. It definitely shouldn't be sent twice for the same mount attempt
|
||
|
and shouldn't be failing.
|
||
|
|
||
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
||
|
---
|
||
|
CHANGELOG | 2 ++
|
||
|
daemon/direct.c | 19 +++++++++++--------
|
||
|
daemon/indirect.c | 19 +++++++++++--------
|
||
|
3 files changed, 24 insertions(+), 16 deletions(-)
|
||
|
|
||
|
diff --git a/CHANGELOG b/CHANGELOG
|
||
|
index 3be6119a..18a2f29c 100644
|
||
|
--- a/CHANGELOG
|
||
|
+++ b/CHANGELOG
|
||
|
@@ -1,3 +1,5 @@
|
||
|
+- fix kernel mount status notification.
|
||
|
+
|
||
|
19/10/2021 autofs-5.1.8
|
||
|
- add xdr_exports().
|
||
|
- remove mount.x and rpcgen dependencies.
|
||
|
diff --git a/daemon/direct.c b/daemon/direct.c
|
||
|
index 4a56486b..c2331155 100644
|
||
|
--- a/daemon/direct.c
|
||
|
+++ b/daemon/direct.c
|
||
|
@@ -1147,12 +1147,18 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static void mount_send_fail(void *arg)
|
||
|
+static void mount_send_status(void *arg)
|
||
|
{
|
||
|
struct ioctl_ops *ops = get_ioctl_ops();
|
||
|
struct pending_args *mt = arg;
|
||
|
struct autofs_point *ap = mt->ap;
|
||
|
- ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
||
|
+
|
||
|
+ if (mt->status)
|
||
|
+ ops->send_fail(ap->logopt, mt->ioctlfd,
|
||
|
+ mt->wait_queue_token, mt->status);
|
||
|
+ else
|
||
|
+ ops->send_ready(ap->logopt,
|
||
|
+ mt->ioctlfd, mt->wait_queue_token);
|
||
|
ops->close(ap->logopt, mt->ioctlfd);
|
||
|
}
|
||
|
|
||
|
@@ -1181,7 +1187,8 @@ static void *do_mount_direct(void *arg)
|
||
|
|
||
|
pending_mutex_unlock(args);
|
||
|
|
||
|
- pthread_cleanup_push(mount_send_fail, &mt);
|
||
|
+ mt.status = 0;
|
||
|
+ pthread_cleanup_push(mount_send_status, &mt);
|
||
|
|
||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||
|
|
||
|
@@ -1195,9 +1202,7 @@ static void *do_mount_direct(void *arg)
|
||
|
if (status == -1) {
|
||
|
error(ap->logopt,
|
||
|
"can't stat direct mount trigger %s", mt.name);
|
||
|
- ops->send_fail(ap->logopt,
|
||
|
- mt.ioctlfd, mt.wait_queue_token, -ENOENT);
|
||
|
- ops->close(ap->logopt, mt.ioctlfd);
|
||
|
+ mt.status = -ENOENT;
|
||
|
pthread_setcancelstate(state, NULL);
|
||
|
pthread_exit(NULL);
|
||
|
}
|
||
|
@@ -1207,8 +1212,6 @@ static void *do_mount_direct(void *arg)
|
||
|
error(ap->logopt,
|
||
|
"direct trigger not valid or already mounted %s",
|
||
|
mt.name);
|
||
|
- ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
||
|
- ops->close(ap->logopt, mt.ioctlfd);
|
||
|
pthread_setcancelstate(state, NULL);
|
||
|
pthread_exit(NULL);
|
||
|
}
|
||
|
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
||
|
index b73c2781..23ef9f41 100644
|
||
|
--- a/daemon/indirect.c
|
||
|
+++ b/daemon/indirect.c
|
||
|
@@ -683,13 +683,18 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static void mount_send_fail(void *arg)
|
||
|
+static void mount_send_status(void *arg)
|
||
|
{
|
||
|
struct ioctl_ops *ops = get_ioctl_ops();
|
||
|
struct pending_args *mt = arg;
|
||
|
struct autofs_point *ap = mt->ap;
|
||
|
- ops->send_fail(ap->logopt,
|
||
|
- ap->ioctlfd, mt->wait_queue_token, -ENOENT);
|
||
|
+
|
||
|
+ if (mt->status)
|
||
|
+ ops->send_fail(ap->logopt, ap->ioctlfd,
|
||
|
+ mt->wait_queue_token, mt->status);
|
||
|
+ else
|
||
|
+ ops->send_ready(ap->logopt,
|
||
|
+ ap->ioctlfd, mt->wait_queue_token);
|
||
|
}
|
||
|
|
||
|
static void *do_mount_indirect(void *arg)
|
||
|
@@ -718,7 +723,8 @@ static void *do_mount_indirect(void *arg)
|
||
|
|
||
|
pending_mutex_unlock(args);
|
||
|
|
||
|
- pthread_cleanup_push(mount_send_fail, &mt);
|
||
|
+ mt.status = 0;
|
||
|
+ pthread_cleanup_push(mount_send_status, &mt);
|
||
|
|
||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||
|
|
||
|
@@ -731,9 +737,7 @@ static void *do_mount_indirect(void *arg)
|
||
|
len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len);
|
||
|
if (!len) {
|
||
|
crit(ap->logopt, "path to be mounted is to long");
|
||
|
- ops->send_fail(ap->logopt,
|
||
|
- ap->ioctlfd, mt.wait_queue_token,
|
||
|
- -ENAMETOOLONG);
|
||
|
+ mt.status = -ENAMETOOLONG;
|
||
|
pthread_setcancelstate(state, NULL);
|
||
|
pthread_exit(NULL);
|
||
|
}
|
||
|
@@ -742,7 +746,6 @@ static void *do_mount_indirect(void *arg)
|
||
|
if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) {
|
||
|
error(ap->logopt,
|
||
|
"indirect trigger not valid or already mounted %s", buf);
|
||
|
- ops->send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
|
||
|
pthread_setcancelstate(state, NULL);
|
||
|
pthread_exit(NULL);
|
||
|
}
|