NetBSD-Bugs archive

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

Re: kern/38990: Unmounting a disk fails the first time



I think this should do it, I'll try it out shortly.

Andrew

Index: vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.350
diff -u -p -r1.350 vfs_subr.c
--- vfs_subr.c  5 Jun 2008 12:32:57 -0000       1.350
+++ vfs_subr.c  22 Jun 2008 10:02:07 -0000
@@ -130,6 +130,7 @@ static vnodelst_t vnode_hold_list = TAIL
 static vnodelst_t vrele_list = TAILQ_HEAD_INITIALIZER(vrele_list);
 
 static int vrele_pending;
+static int vrele_gen;
 static kmutex_t        vrele_lock;
 static kcondvar_t vrele_cv;
 static lwp_t *vrele_lwp;
@@ -1038,6 +1036,8 @@ vrele_thread(void *cookie)
        for (;;) {
                mutex_enter(&vrele_lock);
                while (TAILQ_EMPTY(&vrele_list)) {
+                       vrele_gen++;
+                       cv_broadcast(&vrele_cv);
                        cv_timedwait(&vrele_cv, &vrele_lock, hz);
                }
                vp = TAILQ_FIRST(&vrele_list);
@@ -1153,17 +1153,28 @@ int
 vflush(struct mount *mp, vnode_t *skipvp, int flags)
 {
        vnode_t *vp, *mvp;
-       int busy = 0, when = 0;
+       int busy = 0, when = 0, gen;
+
+       /*
+        * First, flush out any vnode references from vrele_list.
+        */
+       mutex_enter(&vrele_lock);
+       gen = vrele_gen;
+       do {
+               cv_broadcast(&vrele_cv);
+               cv_wait(&vrele_cv, &vrele_lock);
+       } while (gen == vrele_gen);
+       mutex_exit(&vrele_lock);
 
        /* Allocate a marker vnode. */
        if ((mvp = vnalloc(mp)) == NULL)
                return (ENOMEM);
 
-       mutex_enter(&mntvnode_lock);
        /*
         * NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
         * and vclean() are called
         */
+       mutex_enter(&mntvnode_lock);
        for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL;
            vp = vflushnext(mvp, &when)) {
                vmark(mvp, vp);


Home | Main Index | Thread Index | Old Index