Source-Changes-HG archive

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

[src/trunk]: src/sys getcleanvnode(): don't vclean() the vnode if it has gain...



details:   https://anonhg.NetBSD.org/src/rev/5e20122368d0
branches:  trunk
changeset: 748779:5e20122368d0
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Nov 05 08:18:02 2009 +0000

description:
getcleanvnode(): don't vclean() the vnode if it has gained another
  reference while we were getting the v_interlock.
vget(): attempt prevent it from returning a clean vnode:
  if the vnode is being inactivated (by vrelel()), wait for
  vrelel() to complete (or return EBUSY if we can't wait), and return
  ENOENT if the vnode has been vclean'ed by vrelel()
Fix kern/41147 in a better way, hopefully fix other related race conditions.

diffstat:

 sys/kern/vfs_subr.c     |  33 +++++++++++++++++++++++++++++++--
 sys/ufs/ufs/ufs_ihash.c |  13 ++-----------
 2 files changed, 33 insertions(+), 13 deletions(-)

diffs (109 lines):

diff -r 196c38dae60d -r 5e20122368d0 sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c       Thu Nov 05 08:11:24 2009 +0000
+++ b/sys/kern/vfs_subr.c       Thu Nov 05 08:18:02 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_subr.c,v 1.385 2009/10/06 04:28:10 elad Exp $      */
+/*     $NetBSD: vfs_subr.c,v 1.386 2009/11/05 08:18:02 bouyer Exp $    */
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.385 2009/10/06 04:28:10 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.386 2009/11/05 08:18:02 bouyer Exp $");
 
 #include "opt_ddb.h"
 #include "opt_compat_netbsd.h"
@@ -371,6 +371,17 @@
        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
@@ -1306,6 +1317,22 @@
                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) {
@@ -1445,6 +1472,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;
                }
@@ -1469,6 +1497,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 196c38dae60d -r 5e20122368d0 sys/ufs/ufs/ufs_ihash.c
--- a/sys/ufs/ufs/ufs_ihash.c   Thu Nov 05 08:11:24 2009 +0000
+++ b/sys/ufs/ufs/ufs_ihash.c   Thu Nov 05 08:18:02 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_ihash.c,v 1.27 2009/09/20 14:00:24 bouyer Exp $    */
+/*     $NetBSD: ufs_ihash.c,v 1.28 2009/11/05 08:18:02 bouyer Exp $    */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.27 2009/09/20 14:00:24 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.28 2009/11/05 08:18:02 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -152,15 +152,6 @@
                                mutex_exit(&ufs_ihash_lock);
                                if (vget(vp, flags | LK_INTERLOCK))
                                        goto loop;
-                               if (VTOI(vp) != ip ||
-                                   ip->i_number != inum || ip->i_dev != dev) {
-                                       /* lost race against vclean() */
-                                       if (vlockmgr(vp->v_vnlock, LK_RELEASE))
-                                               printf("can't release lock\n");
-                                       vrele(vp);
-                                       vp = NULL;
-                                       goto loop;
-                               }
                        }
                        return (vp);
                }



Home | Main Index | Thread Index | Old Index