[PATCH 01/19] autofs-5.1.8 - fix kernel mount status notification

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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);
 	}





[Index of Archives]     [Linux Filesystem Development]     [Linux Ext4]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux