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



The following reply was made to PR kern/38990; it has been noted by GNATS.

From: Andrew Doran <ad%netbsd.org@localhost>
To: Christos Zoulas <christos%zoulas.com@localhost>
Cc: David Holland <dholland-bugs%netbsd.org@localhost>, 
gnats-bugs%NetBSD.org@localhost,
        kern-bug-people%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
        netbsd-bugs%netbsd.org@localhost, apb%cequrux.com@localhost
Subject: Re: kern/38990: Unmounting a disk fails the first time
Date: Sun, 22 Jun 2008 10:04:08 +0000

 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