PR: kern/8965

Obtained from: Stephen Clawson <sclawson@cs.utah.edu>

    Wakeup anyone waiting on a mount point prior to returning from umount,
    whether an error occurs or not.  Fixes a stat/NFS-umount race and other
    potential future problems.  Fix taken from bug/pr which also indicated
    that the same fix has already been applied to OpenBSD and NetBSD.
This commit is contained in:
Matthew Dillon 1998-12-12 21:07:09 +00:00
parent 3a3c0cf418
commit 4c01697599
2 changed files with 6 additions and 2 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.109 1998/11/03 08:01:47 peter Exp $ * $Id: vfs_syscalls.c,v 1.110 1998/11/03 14:29:09 peter Exp $
*/ */
/* For 4.3 integer FS ID compatibility */ /* For 4.3 integer FS ID compatibility */
@ -494,6 +494,8 @@ dounmount(mp, flags, p)
mp->mnt_flag |= async_flag; mp->mnt_flag |= async_flag;
lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
&mountlist_slock, p); &mountlist_slock, p);
if (mp->mnt_kern_flag & MNTK_MWAIT)
wakeup((caddr_t)mp);
return (error); return (error);
} }
CIRCLEQ_REMOVE(&mountlist, mp, mnt_list); CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.109 1998/11/03 08:01:47 peter Exp $ * $Id: vfs_syscalls.c,v 1.110 1998/11/03 14:29:09 peter Exp $
*/ */
/* For 4.3 integer FS ID compatibility */ /* For 4.3 integer FS ID compatibility */
@ -494,6 +494,8 @@ dounmount(mp, flags, p)
mp->mnt_flag |= async_flag; mp->mnt_flag |= async_flag;
lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
&mountlist_slock, p); &mountlist_slock, p);
if (mp->mnt_kern_flag & MNTK_MWAIT)
wakeup((caddr_t)mp);
return (error); return (error);
} }
CIRCLEQ_REMOVE(&mountlist, mp, mnt_list); CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);