Blame SOURCES/autofs-5.0.6-fix-recursive-mount-deadlock.patch

4d476f
autofs-5.0.6 - fix recursive mount deadlock
4d476f
4d476f
From: Ian Kent <raven@themaw.net>
4d476f
4d476f
Prior to the vfs-automount changes that went into 2.6.38
4d476f
and were finalized in 3.1 it was not possible to block
4d476f
path walks into multi-mounts whose root was covered by
4d476f
another mount. To deal with that a write lock was used
4d476f
to ensure the mount tree construction was completed. This
4d476f
restricts the types of recursively defined mount maps that
4d476f
can be used and can lead to a deadlock during lookup.
4d476f
4d476f
Now that we can prevent processes walking into multi-mounts
4d476f
that are under construction we no longer need to use a
4d476f
write lock.
4d476f
4d476f
Also, in the patch below, a cache writelock is changed to
4d476f
a read lock because a write lock isn't needed since the
4d476f
map cache entry isn't being updated.
4d476f
---
4d476f
4d476f
 CHANGELOG       |    1 +
4d476f
 daemon/direct.c |   14 ++++++++++++--
4d476f
 2 files changed, 13 insertions(+), 2 deletions(-)
4d476f
4d476f
4d476f
diff --git a/CHANGELOG b/CHANGELOG
4d476f
index 936c9ab..9cdad6e 100644
4d476f
--- a/CHANGELOG
4d476f
+++ b/CHANGELOG
4d476f
@@ -12,6 +12,7 @@
4d476f
 - configure.in: allow cross compilation.
4d476f
 - README: update mailing list subscription info.
4d476f
 - allow non root user to check status.
4d476f
+- fix recursive mount deadlock.
4d476f
 
4d476f
 25/07/2012 autofs-5.0.7
4d476f
 =======================
4d476f
diff --git a/daemon/direct.c b/daemon/direct.c
4d476f
index 7e2f0d7..3e09c5d 100644
4d476f
--- a/daemon/direct.c
4d476f
+++ b/daemon/direct.c
4d476f
@@ -1285,6 +1285,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
4d476f
 	struct timespec wait;
4d476f
 	struct timeval now;
4d476f
 	int ioctlfd, len, state;
4d476f
+	unsigned int kver_major = get_kver_major();
4d476f
+	unsigned int kver_minor = get_kver_minor();
4d476f
 
4d476f
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
4d476f
 
4d476f
@@ -1297,8 +1299,16 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
4d476f
 	 * cache entry we will not be able to find the mapent. So
4d476f
 	 * we must take the source writelock to ensure the parent
4d476f
 	 * has mount is complete before we look for the entry.
4d476f
+	 *
4d476f
+	 * Since the vfs-automount kernel changes we can now block
4d476f
+	 * on covered mounts during mount tree construction so a
4d476f
+	 * write lock is no longer needed. So we now can handle a
4d476f
+	 * wider class of recursively define mount lookups.
4d476f
 	 */
4d476f
-	master_source_writelock(ap->entry);
4d476f
+	if (kver_major > 5 || (kver_major == 5 && kver_minor > 1))
4d476f
+		master_source_readlock(ap->entry);
4d476f
+	else
4d476f
+		master_source_writelock(ap->entry);
4d476f
 	map = ap->entry->maps;
4d476f
 	while (map) {
4d476f
 		/*
4d476f
@@ -1311,7 +1321,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
4d476f
 		}
4d476f
 
4d476f
 		mc = map->mc;
4d476f
-		cache_writelock(mc);
4d476f
+		cache_readlock(mc);
4d476f
 		me = cache_lookup_ino(mc, pkt->dev, pkt->ino);
4d476f
 		if (me)
4d476f
 			break;