Don't keep the underlying directory locked while performing the file

system specific VFS_MOUNT operation.
PR:		1067
This commit is contained in:
Tor Egge 1998-09-10 02:27:52 +00:00
parent b45187b7cc
commit a58915fc10
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39036
3 changed files with 34 additions and 9 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.104 1998/07/03 03:47:24 dg Exp $
* $Id: vfs_syscalls.c,v 1.105 1998/07/15 02:32:13 bde Exp $
*/
/* For 4.3 integer FS ID compatibility */
@ -236,10 +236,15 @@ mount(p, uap)
vput(vp);
return (ENODEV);
}
if (vp->v_mountedhere != NULL) {
simple_lock(&vp->v_interlock);
if ((vp->v_flag & VMOUNT) != 0 ||
vp->v_mountedhere != NULL) {
simple_unlock(&vp->v_interlock);
vput(vp);
return (EBUSY);
}
vp->v_flag |= VMOUNT;
simple_unlock(&vp->v_interlock);
/*
* Allocate and initialize the filesystem.
@ -255,9 +260,9 @@ mount(p, uap)
mp->mnt_stat.f_type = vfsp->vfc_typenum;
mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
vp->v_mountedhere = mp;
mp->mnt_vnodecovered = vp;
mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
VOP_UNLOCK(vp, 0, p);
update:
/*
* Set the mount level flags.
@ -299,11 +304,16 @@ mount(p, uap)
vfs_unbusy(mp, p);
return (error);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
/*
* Put the new filesystem on the mount list after root.
*/
cache_purge(vp);
if (!error) {
simple_lock(&vp->v_interlock);
vp->v_flag &= ~VMOUNT;
vp->v_mountedhere = mp;
simple_unlock(&vp->v_interlock);
simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
simple_unlock(&mountlist_slock);
@ -315,7 +325,9 @@ mount(p, uap)
if (error = VFS_START(mp, 0, p))
vrele(vp);
} else {
mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
simple_lock(&vp->v_interlock);
vp->v_flag &= ~VMOUNT;
simple_unlock(&vp->v_interlock);
mp->mnt_vfc->vfc_refcount--;
vfs_unbusy(mp, p);
free((caddr_t)mp, M_MOUNT);

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.104 1998/07/03 03:47:24 dg Exp $
* $Id: vfs_syscalls.c,v 1.105 1998/07/15 02:32:13 bde Exp $
*/
/* For 4.3 integer FS ID compatibility */
@ -236,10 +236,15 @@ mount(p, uap)
vput(vp);
return (ENODEV);
}
if (vp->v_mountedhere != NULL) {
simple_lock(&vp->v_interlock);
if ((vp->v_flag & VMOUNT) != 0 ||
vp->v_mountedhere != NULL) {
simple_unlock(&vp->v_interlock);
vput(vp);
return (EBUSY);
}
vp->v_flag |= VMOUNT;
simple_unlock(&vp->v_interlock);
/*
* Allocate and initialize the filesystem.
@ -255,9 +260,9 @@ mount(p, uap)
mp->mnt_stat.f_type = vfsp->vfc_typenum;
mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
vp->v_mountedhere = mp;
mp->mnt_vnodecovered = vp;
mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
VOP_UNLOCK(vp, 0, p);
update:
/*
* Set the mount level flags.
@ -299,11 +304,16 @@ mount(p, uap)
vfs_unbusy(mp, p);
return (error);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
/*
* Put the new filesystem on the mount list after root.
*/
cache_purge(vp);
if (!error) {
simple_lock(&vp->v_interlock);
vp->v_flag &= ~VMOUNT;
vp->v_mountedhere = mp;
simple_unlock(&vp->v_interlock);
simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
simple_unlock(&mountlist_slock);
@ -315,7 +325,9 @@ mount(p, uap)
if (error = VFS_START(mp, 0, p))
vrele(vp);
} else {
mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
simple_lock(&vp->v_interlock);
vp->v_flag &= ~VMOUNT;
simple_unlock(&vp->v_interlock);
mp->mnt_vfc->vfc_refcount--;
vfs_unbusy(mp, p);
free((caddr_t)mp, M_MOUNT);

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vnode.h 8.7 (Berkeley) 2/4/94
* $Id: vnode.h,v 1.71 1998/05/11 03:55:16 dyson Exp $
* $Id: vnode.h,v 1.72 1998/08/27 02:34:30 jkh Exp $
*/
#ifndef _SYS_VNODE_H_
@ -158,6 +158,7 @@ struct vnode {
#define VFREE 0x80000 /* This vnode is on the freelist */
#define VTBFREE 0x100000 /* This vnode is on the to-be-freelist */
#define VONWORKLST 0x200000 /* On syncer work-list */
#define VMOUNT 0x400000 /* Mount in progress */
/*
* Vnode attributes. A field value of VNOVAL represents a field whose value