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

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