Module Name:    src
Committed By:   riz
Date:           Thu Nov 22 18:51:14 UTC 2012

Modified Files:
        src/sys/kern [netbsd-6-0]: vfs_vnode.c vfs_vnops.c

Log Message:
Pull up following revision(s) (requested by hannken in ticket #692):
        sys/kern/vfs_vnode.c: revision 1.17
        sys/kern/vfs_vnops.c: revision 1.186
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.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.15.8.1 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.183.8.1 -r1.183.8.1.4.1 src/sys/kern/vfs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.15 src/sys/kern/vfs_vnode.c:1.15.8.1
--- src/sys/kern/vfs_vnode.c:1.15	Tue Dec 20 16:49:37 2011
+++ src/sys/kern/vfs_vnode.c	Thu Nov 22 18:51:14 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.15 2011/12/20 16:49:37 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.15.8.1 2012/11/22 18:51:14 riz Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -120,7 +120,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.15 2011/12/20 16:49:37 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.15.8.1 2012/11/22 18:51:14 riz Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -555,6 +555,22 @@ vget(vnode_t *vp, int flags)
 		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.
 	 */
@@ -665,8 +681,12 @@ retry:
 			/* 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) {
@@ -674,6 +694,18 @@ retry:
 				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) {
 			/* 
@@ -709,6 +741,7 @@ retry:
 			if (++vrele_pending > (desiredvnodes >> 8))
 				cv_signal(&vrele_cv); 
 			mutex_exit(&vrele_lock);
+			cv_broadcast(&vp->v_cv);
 			mutex_exit(vp->v_interlock);
 			return;
 		}
@@ -726,6 +759,7 @@ retry:
 		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);

Index: src/sys/kern/vfs_vnops.c
diff -u src/sys/kern/vfs_vnops.c:1.183.8.1 src/sys/kern/vfs_vnops.c:1.183.8.1.4.1
--- src/sys/kern/vfs_vnops.c:1.183.8.1	Thu Apr 12 17:15:23 2012
+++ src/sys/kern/vfs_vnops.c	Thu Nov 22 18:51:14 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnops.c,v 1.183.8.1 2012/04/12 17:15:23 riz Exp $	*/
+/*	$NetBSD: vfs_vnops.c,v 1.183.8.1.4.1 2012/11/22 18:51:14 riz 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.183.8.1 2012/04/12 17:15:23 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.183.8.1.4.1 2012/11/22 18:51:14 riz Exp $");
 
 #include "veriexec.h"
 
@@ -805,15 +805,6 @@ vn_lock(struct vnode *vp, int flags)
 		} 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);
 		}

Reply via email to