Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 241

kernel-2.6.18-194.11.1.el5.src.rpm

From: Ian Kent <ikent@redhat.com>
Date: Tue, 12 Aug 2008 12:28:29 +0800
Subject: [autofs4] fix pending checks
Message-id: 20080812042827.15842.32103.stgit@web.messagingengine.com
O-Subject: [RHEL 5.3 PATCH 16/20] autofs4 - fix pending checks [bz452139]
Bugzilla: 452139

This patch contributes to the resolution of bugs 458749, 448936
and 452139.

There are two cases for which a dentry that has a pending mount request
does not wait for completion. One is via autofs4_revalidate() and the
other via autofs4_follow_link().

In revalidate, after the mount point directory is created, but before
the mount is done, the check in try_to_fill_dentry() can can fail to
send the dentry to the wait queue since the dentry is positive and the
lookup flags may contain only LOOKUP_FOLLOW. Although we don't trigger
a mount for the LOOKUP_FOLLOW flag, if ther's one pending we might as
well wait and use the mounted dentry for the lookup.

In autofs4_follow_link() the dentry is not checked to see if it is
pending so it may fail to call try_to_fill_dentry() and not wait
for mount completion.

A dentry that is pending must always be sent to the wait queue.

Signed-off-by: Ian Kent <raven@themaw.net>

diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 2bcbd1b..6920daf 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -178,7 +178,8 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
 			return status;
 		}
 	/* Trigger mount for path component or follow link */
-	} else if (flags & (TRIGGER_FLAGS | TRIGGER_INTENTS) ||
+	} else if (dentry->d_flags & DCACHE_AUTOFS_PENDING ||
+			flags & (TRIGGER_FLAGS | TRIGGER_INTENTS) ||
 			current->link_count) {
 		DPRINTK("waiting for mount name=%.*s",
 			dentry->d_name.len, dentry->d_name.name);
@@ -223,7 +224,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
 
 	/* If it's our master or we shouldn't trigger a mount we're done */
 	lookup_type = nd->flags & (TRIGGER_FLAGS | TRIGGER_INTENTS);
-	if (oz_mode || !lookup_type)
+	if (oz_mode ||
+	    !(lookup_type || dentry->d_flags & DCACHE_AUTOFS_PENDING))
 		goto done;
 
 	/* If an expire request is pending wait for it. */
@@ -242,7 +244,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
 	 * don't try to mount it again.
 	 */
 	spin_lock(&dcache_lock);
-	if (!d_mountpoint(dentry) && __simple_empty(dentry)) {
+	if (dentry->d_flags & DCACHE_AUTOFS_PENDING ||
+	    (!d_mountpoint(dentry) && __simple_empty(dentry))) {
 		spin_unlock(&dcache_lock);
 
 		status = try_to_fill_dentry(dentry, 0);