From owner-freebsd-hackers Wed Jun 10 07:55:05 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id HAA16405 for freebsd-hackers-outgoing; Wed, 10 Jun 1998 07:55:05 -0700 (PDT) (envelope-from owner-freebsd-hackers@FreeBSD.ORG) Received: from pat.idi.ntnu.no (0@pat.idi.ntnu.no [129.241.103.5]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id HAA16335 for ; Wed, 10 Jun 1998 07:54:51 -0700 (PDT) (envelope-from Tor.Egge@fast.no) From: Tor.Egge@fast.no Received: from idi.ntnu.no (tegge@ikke.idi.ntnu.no [129.241.111.65]) by pat.idi.ntnu.no (8.8.8/8.8.8) with ESMTP id QAA09941; Wed, 10 Jun 1998 16:53:44 +0200 (MET DST) Message-Id: <199806101453.QAA09941@pat.idi.ntnu.no> To: mcl@Amnesiac.123.org Cc: hackers@FreeBSD.ORG Subject: Re: system shitdown using mount In-Reply-To: Your message of "Wed, 10 Jun 1998 08:48:03 +0200 (CEST)" References: X-Mailer: Mew version 1.70 on Emacs 19.34.1 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Wed, 10 Jun 1998 16:53:44 +0200 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > -----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