diff options
| -rw-r--r-- | sys/kern/vfs_extattr.c | 20 | ||||
| -rw-r--r-- | sys/kern/vfs_syscalls.c | 20 | ||||
| -rw-r--r-- | sys/sys/vnode.h | 3 |
3 files changed, 34 insertions, 9 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 805afb99b423..6ab0ea717b25 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -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 @@ update: 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 @@ update: 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); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 805afb99b423..6ab0ea717b25 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -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 @@ update: 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 @@ update: 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); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index d5e7311758ee..7e5b6bbbd651 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -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 |
