Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Bring back Manuel Bouyers patch to resolve races be...
details: https://anonhg.NetBSD.org/src/rev/6058f919c9f4
branches: trunk
changeset: 782651:6058f919c9f4
user: hannken <hannken%NetBSD.org@localhost>
date: Mon Nov 12 11:00:07 2012 +0000
description:
Bring back Manuel Bouyers patch to resolve races between vget() and vrelel()
resulting in vget() returning dead vnodes.
It is impossible to resolve these races in vn_lock().
Needs pullup to NetBSD-6.
diffstat:
sys/kern/vfs_vnode.c | 42 ++++++++++++++++++++++++++++++++++++++----
sys/kern/vfs_vnops.c | 13 ++-----------
2 files changed, 40 insertions(+), 15 deletions(-)
diffs (125 lines):
diff -r 1c93d8316266 -r 6058f919c9f4 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c Mon Nov 12 09:03:52 2012 +0000
+++ b/sys/kern/vfs_vnode.c Mon Nov 12 11:00:07 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.16 2012/10/12 21:10:55 rmind Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.17 2012/11/12 11:00:07 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -124,7 +124,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.16 2012/10/12 21:10:55 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.17 2012/11/12 11:00:07 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -564,6 +564,22 @@
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;
+ }
+ }
+
/*
* Ok, we got it in good shape. Just locking left.
*/
@@ -674,8 +690,12 @@
/* The pagedaemon can't wait around; defer. */
defer = true;
} else if (curlwp == vrele_lwp) {
- /* We have to try harder. */
- vp->v_iflag &= ~VI_INACTREDO;
+ /*
+ * We have to try harder. But we can't sleep
+ * with VI_INACTNOW as vget() may be waiting on it.
+ */
+ vp->v_iflag &= ~(VI_INACTREDO|VI_INACTNOW);
+ cv_broadcast(&vp->v_cv);
mutex_exit(vp->v_interlock);
error = vn_lock(vp, LK_EXCLUSIVE);
if (error != 0) {
@@ -683,6 +703,18 @@
vnpanic(vp, "%s: unable to lock %p",
__func__, vp);
}
+ mutex_enter(vp->v_interlock);
+ /*
+ * if we did get another reference while
+ * sleeping, don't try to inactivate it yet.
+ */
+ if (__predict_false(vtryrele(vp))) {
+ VOP_UNLOCK(vp);
+ mutex_exit(vp->v_interlock);
+ return;
+ }
+ vp->v_iflag |= VI_INACTNOW;
+ mutex_exit(vp->v_interlock);
defer = false;
} else if ((vp->v_iflag & VI_LAYER) != 0) {
/*
@@ -718,6 +750,7 @@
if (++vrele_pending > (desiredvnodes >> 8))
cv_signal(&vrele_cv);
mutex_exit(&vrele_lock);
+ cv_broadcast(&vp->v_cv);
mutex_exit(vp->v_interlock);
return;
}
@@ -735,6 +768,7 @@
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);
diff -r 1c93d8316266 -r 6058f919c9f4 sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c Mon Nov 12 09:03:52 2012 +0000
+++ b/sys/kern/vfs_vnops.c Mon Nov 12 11:00:07 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnops.c,v 1.185 2012/08/24 05:52:17 dholland Exp $ */
+/* $NetBSD: vfs_vnops.c,v 1.186 2012/11/12 11:00:07 hannken Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.185 2012/08/24 05:52:17 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.186 2012/11/12 11:00:07 hannken Exp $");
#include "veriexec.h"
@@ -807,15 +807,6 @@
} else {
mutex_exit(vp->v_interlock);
error = VOP_LOCK(vp, (flags & ~LK_RETRY));
- if (error == 0 && (flags & LK_RETRY) == 0) {
- mutex_enter(vp->v_interlock);
- if ((vp->v_iflag & VI_CLEAN)) {
- mutex_exit(vp->v_interlock);
- VOP_UNLOCK(vp);
- return ENOENT;
- }
- mutex_exit(vp->v_interlock);
- }
if (error == 0 || error == EDEADLK || error == EBUSY)
return (error);
}
Home |
Main Index |
Thread Index |
Old Index