File 0014-autofs-5.1.9-improve-handling-of-missing-map-entry-f.patch of Package autofs

From 5b5cf984cef487cc7672cb709c03b08512537a3f Mon Sep 17 00:00:00 2001
From: Ian Kent <raven@themaw.net>
Date: Fri, 31 Oct 2025 09:31:39 +0800
Subject: [PATCH 14/14] autofs-5.1.9 - improve handling of missing map entry
 for mount request

If the map entry isn't found it must have been deleted from the map but
a trigger mount is still mounted because it has sent us this request.
Use the mount table for a brute force lookup to get the path and open a
file handle for it so we can send a failure status to the kernel.

Also remove the crit() log message following open_ioctlfd() as it already
issues an appropriate error message on failure.

Signed-off-by: Ian Kent <raven@themaw.net>
Acked-by: David Disseldorp <ddiss@suse.de>
---
 CHANGELOG       |  1 +
 daemon/direct.c | 49 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index f9aafd4..2725130 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,7 @@
 - refactor do_umount_autofs_direct().
 - fix stale direct mount trigger not umounted on expire.
 - add function table_lookup_ino().
+- improve handling of missing map entry for mount request.
 
 02/11/2023 autofs-5.1.9
 - fix kernel mount status notification.
diff --git a/daemon/direct.c b/daemon/direct.c
index be498d6..123611d 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1371,12 +1371,50 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 	}
 
 	if (!me) {
-		/*
-		 * Shouldn't happen as the kernel is telling us
-		 * someone has walked on our mount point.
+		char tmp[PATH_MAX + 1];
+		char *path;
+
+		/* If the map entry wasn't found it must have been deleted
+		 * from the map but a trigger mount is still mounted because
+		 * it has sent us this request. So use the mount table for a
+		 * brute force lookup to get the path and open a file handle
+		 * for it so we can return a not found status to the kernel.
 		 */
-		logerr("can't find map entry for (%lu,%lu)",
-		    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+		path = table_lookup_ino(ap, pkt->dev, pkt->ino, tmp, PATH_MAX + 1, &ioctlfd);
+		if (!path) {
+			/* This could be cuased by an inability to open a file
+			 * handle but generally that doesn't happen. The mount
+			 * has to exist and be pinned becuase we got this request
+			 * so it can't be umounted. Therefore it's very unlikely
+			 * this case will happen. If it does happen it's fatal,
+			 * the waiter will hang and there's nothing we can do
+			 * about it.
+			 */
+			logerr("can't find mount for (%lu,%lu)",
+			    (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+			/* TODO:  how do we clear wait q in kernel ?? */
+		} else {
+			int rv;
+
+			/* Try and recover from this unexpecyedly missing map
+			 * entry by detaching the direct mount trigger that
+			 * sent the request so it's no longer visible to the
+			 * VFS.
+			 */
+			info(ap->logopt, "forcing umount of direct mount %s", path);
+			rv = umount2(path, MNT_DETACH);
+			if  (rmdir(path) == -1) {
+				char buf[MAX_ERR_BUF];
+				char *estr;
+
+				estr = strerror_r(errno, buf, MAX_ERR_BUF);
+				warn(ap->logopt,
+				     "failed to remove dir %s: %s", path, estr);
+			}
+			ops->send_fail(ap->logopt,
+				       ioctlfd, pkt->wait_queue_token, -EINVAL);
+			ops->close(ap->logopt, ioctlfd);
+		}
 		master_source_unlock(ap->entry);
 		master_mutex_unlock();
 		pthread_setcancelstate(state, NULL);
@@ -1395,7 +1433,6 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 		master_source_unlock(ap->entry);
 		master_mutex_unlock();
 		pthread_setcancelstate(state, NULL);
-		crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
 		/* TODO:  how do we clear wait q in kernel ?? */
 		return 1;
 	}
-- 
2.51.0

openSUSE Build Service is sponsored by