tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: panic due to lost vnode flag
On Sat, Oct 24, 2009 at 01:58:44PM +0100, Mindaugas Rasiukevicius wrote:
> Hello,
>
> Manuel Bouyer <bouyer%antioche.eu.org@localhost> wrote:
> > Could all thoses who have the problem try the attached patch (against
> > netbsd-5 but should apply without much problems to HEAD) ?
>
> > mutex_exit(&vp->v_interlock);
> > + cv_broadcast(&vp->v_cv);
>
> This (and other instances) are wrong i.e. cv_broadcast() must always be
> called with interlock held (in this case v_interlock).
thanks, this will make things easier :)
Here's a new diff.
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--
Index: sys/ufs/ufs/ufs_ihash.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_ihash.c,v
retrieving revision 1.26.10.1
diff -u -p -u -r1.26.10.1 ufs_ihash.c
--- sys/ufs/ufs/ufs_ihash.c 28 Sep 2009 01:43:02 -0000 1.26.10.1
+++ sys/ufs/ufs/ufs_ihash.c 24 Oct 2009 13:33:23 -0000
@@ -152,6 +152,7 @@ ufs_ihashget(dev_t dev, ino_t inum, int
mutex_exit(&ufs_ihash_lock);
if (vget(vp, flags | LK_INTERLOCK))
goto loop;
+#if 0
if (VTOI(vp) != ip ||
ip->i_number != inum || ip->i_dev != dev) {
/* lost race against vclean() */
@@ -161,6 +162,7 @@ ufs_ihashget(dev_t dev, ino_t inum, int
vp = NULL;
goto loop;
}
+#endif
}
return (vp);
}
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.357.4.5
diff -u -p -u -r1.357.4.5 vfs_subr.c
--- sys/kern/vfs_subr.c 21 Jul 2009 00:31:58 -0000 1.357.4.5
+++ sys/kern/vfs_subr.c 24 Oct 2009 13:33:23 -0000
@@ -370,6 +370,17 @@ try_nextlist:
vp->v_freelisthd = NULL;
mutex_exit(&vnode_free_list_lock);
+ if (vp->v_usecount != 0) {
+ /*
+ * was referenced again before we got the interlock
+ * Don't return to freelist - the holder of the last
+ * reference will destroy it.
+ */
+ vrelel(vp, 0); /* releases vp->v_interlock */
+ mutex_enter(&vnode_free_list_lock);
+ goto retry;
+ }
+
/*
* The vnode is still associated with a file system, so we must
* clean it out before reusing it. We need to add a reference
@@ -1288,6 +1299,22 @@ vget(vnode_t *vp, int flags)
vrelel(vp, 0);
return ENOENT;
}
+
+ if ((vp->v_iflag & VI_INACTNOW) != 0) {
+ /*
+ * if it's being desactived, wait for it to complete.
+ * Make sure to not return a clean vnode.
+ */
+ if ((flags & LK_NOWAIT) != 0) {
+ vrelel(vp, 0);
+ return EBUSY;
+ }
+ vwait(vp, VI_INACTNOW);
+ if ((vp->v_iflag & VI_CLEAN) != 0) {
+ vrelel(vp, 0);
+ return ENOENT;
+ }
+ }
if (flags & LK_TYPE_MASK) {
error = vn_lock(vp, flags | LK_INTERLOCK);
if (error != 0) {
@@ -1427,6 +1454,7 @@ vrelel(vnode_t *vp, int flags)
if (++vrele_pending > (desiredvnodes >> 8))
cv_signal(&vrele_cv);
mutex_exit(&vrele_lock);
+ cv_broadcast(&vp->v_cv);
mutex_exit(&vp->v_interlock);
return;
}
@@ -1451,6 +1479,7 @@ vrelel(vnode_t *vp, int flags)
VOP_INACTIVE(vp, &recycle);
mutex_enter(&vp->v_interlock);
vp->v_iflag &= ~VI_INACTNOW;
+ cv_broadcast(&vp->v_cv);
if (!recycle) {
if (vtryrele(vp)) {
mutex_exit(&vp->v_interlock);
Home |
Main Index |
Thread Index |
Old Index