Date: Wed, 10 Jun 1998 16:53:44 +0200 From: Tor.Egge@fast.no To: mcl@Amnesiac.123.org Cc: hackers@FreeBSD.ORG Subject: Re: system shitdown using mount Message-ID: <199806101453.QAA09941@pat.idi.ntnu.no> In-Reply-To: Your message of "Wed, 10 Jun 1998 08:48:03 %2B0200 (CEST)" References: <Pine.BSF.3.96.980610083657.28640A-100000@Amnesiac.123.org>
next in thread | previous in thread | raw e-mail | index | archive | help
> -----BEGIN PGP SIGNED MESSAGE-----
>
> 'bry
>
> After visiting few pubs I tried to mount some device,
> but I mistyped it:
> # mount /mnt/foo /mnt
>
> *shitdown*, wtf? So I tried again, as expected, my box crashed again.
/mnt was locked while ffs_mount tried to lookup /mnt/foo. This probably
caused a panic in ufs_lock, since a recursive lock on /mnt was not expected.
This behavior is also present in 3.0-CURRENT. I'm using the following
patch (for 3.0-CURRENT), after having made a similar mistake with
the mount command (I forgot to specify the '-t null' option).
Index: sys/sys/vnode.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/vnode.h,v
retrieving revision 1.71
diff -u -5 -r1.71 vnode.h
--- vnode.h 1998/05/11 03:55:16 1.71
+++ vnode.h 1998/05/14 22:07:55
@@ -156,10 +156,11 @@
#define VOWANT 0x20000 /* a process is waiting for VOLOCK */
#define VDOOMED 0x40000 /* This vnode is being recycled */
#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
* is unavailable (getattr) or which is not to be changed (setattr).
*/
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.101
diff -u -5 -r1.101 vfs_syscalls.c
--- vfs_syscalls.c 1998/05/11 03:55:28 1.101
+++ vfs_syscalls.c 1998/05/14 22:07:27
@@ -239,14 +239,19 @@
break;
if (vfsp == NULL) {
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.
*/
mp = (struct mount *)malloc((u_long)sizeof(struct mount),
@@ -258,13 +263,13 @@
mp->mnt_vfc = vfsp;
vfsp->vfc_refcount++;
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.
*/
if (SCARG(uap, flags) & MNT_RDONLY)
@@ -302,15 +307,20 @@
mp->mnt_syncer = NULL;
}
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);
checkdirs(vp);
VOP_UNLOCK(vp, 0, p);
@@ -318,11 +328,13 @@
error = vfs_allocate_syncvnode(mp);
vfs_unbusy(mp, p);
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);
vput(vp);
}
- Tor Egge
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806101453.QAA09941>
