Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-6-0]: src/sys/kern Pull up following revision(s) (requested by ha...



details:   https://anonhg.NetBSD.org/src/rev/339d78676a6f
branches:  netbsd-6-0
changeset: 774691:339d78676a6f
user:      riz <riz%NetBSD.org@localhost>
date:      Thu Nov 22 18:51:14 2012 +0000

description:
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.

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 2b544ecfcf9e -r 339d78676a6f sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c      Thu Nov 22 17:26:58 2012 +0000
+++ b/sys/kern/vfs_vnode.c      Thu Nov 22 18:51:14 2012 +0000
@@ -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 @@
                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 @@
                        /* 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 @@
                                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 @@
                        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 @@
                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 2b544ecfcf9e -r 339d78676a6f sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c      Thu Nov 22 17:26:58 2012 +0000
+++ b/sys/kern/vfs_vnops.c      Thu Nov 22 18:51:14 2012 +0000
@@ -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 @@
                } 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