Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 254

kernel-2.6.18-238.el5.src.rpm

From: Ian Kent <ikent@redhat.com>
Subject: Re: [RHEL 5.1 PATCH] autofs4 - fix race between mount and expire
Date: Thu, 23 Aug 2007 18:05:46 +0800
Bugzilla: 236875
Message-Id: <1187863546.3150.26.camel@raven.themaw.net>
Changelog: [autofs] autofs4 - fix race between mount and expire


On Wed, 2007-04-18 at 16:04 +0800, Ian Kent wrote:
> 
> Explaination.
> 
> What happens is that during an expire the situation can arise that a
> directory is removed and another lookup is done before the expire issues
> a completion status to the kernel module. In this case, since the the
> lookup gets a new dentry, it doesn't know that there is an expire in
> progress and when it posts its mount request, matches the existing
> expire request and waits for its completion.  ENOENT is then returned to
> user space from lookup (as the dentry passed in remains negative)
> without having performed the mount request.
> 
> The solution is to keep track of dentrys in this unhashed state and
> reuse them, if possible, in order to preserve the flags.

Original patch snipped...

The problem with the original patch arises because when a dentry is
rehashed after catching the race the process wake up order is not
determined. It's possible for the process requesting the mount to fail
to send a mount request to the daemon if the AUTOFS_INF_EXPIRING flag
hasn't been cleared soon enough. This can happen when the mount
requester process proceeds before the expire requester process when the
waiters are woken up as there's a finite time between this event and the
clearing of the flag.

This patch resolves the problem.

---
--- linux-2.6.18.noarch/fs/autofs4/root.c.lookup-expire-race-fix-2	2007-08-20 19:37:17.000000000 +0800
+++ linux-2.6.18.noarch/fs/autofs4/root.c	2007-08-20 19:39:52.000000000 +0800
@@ -608,8 +608,11 @@ static struct dentry *autofs4_lookup(str
 		 * If we are racing with expire the request might not
 		 * be quite complete but the directory has been removed
 		 * so it must have been successful, so just wait for it.
+		 * We need to ensure the AUTOFS_INF_EXPIRING flag is clear
+		 * before continuing as revalidate may fail when calling
+		 * try_to_fill_dentry (returning EAGAIN) if we don't.
 		 */
-		if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
+		while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
 			DPRINTK("wait for incomplete expire %p name=%.*s",
 				unhashed, unhashed->d_name.len,
 				unhashed->d_name.name);