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