Source-Changes-HG archive

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

[src/trunk]: src/sys In spec_close(), if we're not doing a non-blocking close...



details:   https://anonhg.NetBSD.org/src/rev/ffda7e6d5340
branches:  trunk
changeset: 477224:ffda7e6d5340
user:      wrstuden <wrstuden%NetBSD.org@localhost>
date:      Sat Oct 16 23:53:26 1999 +0000

description:
In spec_close(), if we're not doing a non-blocking close and VXLOCK is
not set, unlock the vnode before calling the device's close routine and
relock it after it returns. tty close routines will sleep waiting for
buffers to drain, which won't happen often times as the other side needs
to grab the vnode lock first.

Make all unmount routines lock the device vnode before calling VOP_CLOSE().

diffstat:

 sys/adosfs/advfsops.c            |   5 ++-
 sys/coda/coda_vnops.c            |  17 +++++++++++++--
 sys/filecorefs/filecore_vfsops.c |   7 ++++-
 sys/isofs/cd9660/cd9660_vfsops.c |   5 ++-
 sys/miscfs/specfs/spec_vnops.c   |  41 ++++++++++++++++++++++++++++++++++-----
 sys/miscfs/union/union_subr.c    |   4 ++-
 sys/msdosfs/msdosfs_vfsops.c     |   7 ++++-
 sys/ntfs/ntfs_vfsops.c           |   6 ++++-
 sys/ufs/ext2fs/ext2fs_vfsops.c   |   7 ++++-
 sys/ufs/ffs/ffs_vfsops.c         |   7 ++++-
 sys/uvm/uvm_swap.c               |  12 ++++++++--
 11 files changed, 92 insertions(+), 26 deletions(-)

diffs (truncated from 386 to 300 lines):

diff -r e4577574b8c4 -r ffda7e6d5340 sys/adosfs/advfsops.c
--- a/sys/adosfs/advfsops.c     Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/adosfs/advfsops.c     Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: advfsops.c,v 1.36 1999/06/02 22:04:30 is Exp $ */
+/*     $NetBSD: advfsops.c,v 1.37 1999/10/16 23:53:26 wrstuden Exp $   */
 
 /*
  * Copyright (c) 1994 Christian E. Hopps
@@ -299,8 +299,9 @@
                return (error);
        amp = VFSTOADOSFS(mp);
        amp->devvp->v_specflags &= ~SI_MOUNTEDON;
+       vn_lock(amp->devvp, LK_EXCLUSIVE | LK_RETRY);
        error = VOP_CLOSE(amp->devvp, FREAD, NOCRED, p);
-       vrele(amp->devvp);
+       vput(amp->devvp);
        if (amp->bitmap)
                free(amp->bitmap, M_ADOSFSBITMAP);
        free(amp, M_ADOSFSMNT);
diff -r e4577574b8c4 -r ffda7e6d5340 sys/coda/coda_vnops.c
--- a/sys/coda/coda_vnops.c     Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/coda/coda_vnops.c     Sat Oct 16 23:53:26 1999 +0000
@@ -6,7 +6,7 @@
 rmdir
 symlink
 */
-/*     $NetBSD: coda_vnops.c,v 1.13 1999/10/01 22:26:00 soren Exp $    */
+/*     $NetBSD: coda_vnops.c,v 1.14 1999/10/16 23:53:27 wrstuden Exp $ */
 
 /*
  * 
@@ -56,6 +56,15 @@
 /*
  * HISTORY
  * $Log: coda_vnops.c,v $
+ * Revision 1.14  1999/10/16 23:53:27  wrstuden
+ * In spec_close(), if we're not doing a non-blocking close and VXLOCK is
+ * not set, unlock the vnode before calling the device's close routine and
+ * relock it after it returns. tty close routines will sleep waiting for
+ * buffers to drain, which won't happen often times as the other side needs
+ * to grab the vnode lock first.
+ *
+ * Make all unmount routines lock the device vnode before calling VOP_CLOSE().
+ *
  * Revision 1.13  1999/10/01 22:26:00  soren
  * Account for widened v_usecount in struct vnode.
  *
@@ -561,8 +570,9 @@
 #ifdef hmm
            vgone(cp->c_ovp);
 #else
+           vn_lock(cp->c_ovp, LK_EXCLUSIVE | LK_RETRY);
            VOP_CLOSE(cp->c_ovp, flag, cred, p); /* Do errors matter here? */
-           vrele(cp->c_ovp);
+           vput(cp->c_ovp);
 #endif
        } else {
 #ifdef CODA_VERBOSE
@@ -571,8 +581,9 @@
        }
        return ENODEV;
     } else {
+       vn_lock(cp->c_ovp, LK_EXCLUSIVE | LK_RETRY);
        VOP_CLOSE(cp->c_ovp, flag, cred, p); /* Do errors matter here? */
-       vrele(cp->c_ovp);
+       vput(cp->c_ovp);
     }
 
     if (--cp->c_ocount == 0)
diff -r e4577574b8c4 -r ffda7e6d5340 sys/filecorefs/filecore_vfsops.c
--- a/sys/filecorefs/filecore_vfsops.c  Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/filecorefs/filecore_vfsops.c  Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: filecore_vfsops.c,v 1.7 1999/07/08 01:06:00 wrstuden Exp $     */
+/*     $NetBSD: filecore_vfsops.c,v 1.8 1999/10/16 23:53:27 wrstuden Exp $     */
 
 /*-
  * Copyright (c) 1998 Andrew McMurry
@@ -345,7 +345,9 @@
 #endif
                brelse(bp);
        }
+       vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
+       VOP_UNLOCK(devvp, 0);
        if (fcmp) {
                free((caddr_t)fcmp, M_FILECOREMNT);
                mp->mnt_data = (qaddr_t)0;
@@ -392,8 +394,9 @@
        fcmp = VFSTOFILECORE(mp);
 
        fcmp->fc_devvp->v_specflags &= ~SI_MOUNTEDON;
+       vn_lock(fcmp->fc_devvp, LK_EXCLUSIVE | LK_RETRY);
        error = VOP_CLOSE(fcmp->fc_devvp, FREAD, NOCRED, p);
-       vrele(fcmp->fc_devvp);
+       vput(fcmp->fc_devvp);
        free((caddr_t)fcmp, M_FILECOREMNT);
        mp->mnt_data = (qaddr_t)0;
        mp->mnt_flag &= ~MNT_LOCAL;
diff -r e4577574b8c4 -r ffda7e6d5340 sys/isofs/cd9660/cd9660_vfsops.c
--- a/sys/isofs/cd9660/cd9660_vfsops.c  Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/isofs/cd9660/cd9660_vfsops.c  Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd9660_vfsops.c,v 1.39 1999/07/17 01:08:28 wrstuden Exp $      */
+/*     $NetBSD: cd9660_vfsops.c,v 1.40 1999/10/16 23:53:27 wrstuden Exp $      */
 
 /*-
  * Copyright (c) 1994
@@ -511,8 +511,9 @@
 #endif
        
        isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON;
+       vn_lock(isomp->im_devvp, LK_EXCLUSIVE | LK_RETRY);
        error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, p);
-       vrele(isomp->im_devvp);
+       vput(isomp->im_devvp);
        free((caddr_t)isomp, M_ISOFSMNT);
        mp->mnt_data = (qaddr_t)0;
        mp->mnt_flag &= ~MNT_LOCAL;
diff -r e4577574b8c4 -r ffda7e6d5340 sys/miscfs/specfs/spec_vnops.c
--- a/sys/miscfs/specfs/spec_vnops.c    Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/miscfs/specfs/spec_vnops.c    Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spec_vnops.c,v 1.43 1998/10/02 00:21:39 ross Exp $     */
+/*     $NetBSD: spec_vnops.c,v 1.44 1999/10/16 23:53:27 wrstuden Exp $ */
 
 /*
  * Copyright (c) 1989, 1993
@@ -551,7 +551,12 @@
        register struct vnode *vp = ap->a_vp;
        dev_t dev = vp->v_rdev;
        int (*devclose) __P((dev_t, int, int, struct proc *));
-       int mode, error;
+       int mode, error, count, flags, flags1;
+
+       simple_lock(&vp->v_interlock);
+       count = vcount(vp);
+       flags = vp->v_flag;
+       simple_unlock(&vp->v_interlock);
 
        switch (vp->v_type) {
 
@@ -565,9 +570,10 @@
                 * if the reference count is 2 (this last descriptor
                 * plus the session), release the reference from the session.
                 */
-               if (vcount(vp) == 2 && ap->a_p &&
+               if (count == 2 && ap->a_p &&
                    vp == ap->a_p->p_session->s_ttyvp) {
                        vrele(vp);
+                       count--;
                        ap->a_p->p_session->s_ttyvp = NULL;
                }
                /*
@@ -575,7 +581,7 @@
                 * of forcably closing the device, otherwise we only
                 * close on last reference.
                 */
-               if (vcount(vp) > 1 && (vp->v_flag & VXLOCK) == 0)
+               if (count > 1 && (flags & VXLOCK) == 0)
                        return (0);
                devclose = cdevsw[major(dev)].d_close;
                mode = S_IFCHR;
@@ -599,7 +605,7 @@
                 * sum of the reference counts on all the aliased
                 * vnodes descends to one, we are on last close.
                 */
-               if (vcount(vp) > 1 && (vp->v_flag & VXLOCK) == 0)
+               if (count > 1 && (flags & VXLOCK) == 0)
                        return (0);
                devclose = bdevsw[major(dev)].d_close;
                mode = S_IFBLK;
@@ -609,7 +615,30 @@
                panic("spec_close: not special");
        }
 
-       return ((*devclose)(dev, ap->a_fflag, mode, ap->a_p));
+       flags1 = ap->a_fflag;
+
+       /*
+        * if VXLOCK is set, then we're going away soon, so make this
+        * non-blocking. Also ensures that we won't wedge in vn_lock below.
+        */
+       if (flags & VXLOCK)
+               flags1 |= FNONBLOCK;
+
+       /*
+        * If we're able to block, release the vnode lock & reaquire. We
+        * might end up sleaping for someone else who wants our queues. They
+        * won't get them if we hold the vnode locked. Also, if VXLOCK is set,
+        * don't release the lock as we won't be able to regain it.
+        */
+       if (!(flags1 & FNONBLOCK))
+               VOP_UNLOCK(vp, 0);
+
+       error =  (*devclose)(dev, flags1, mode, ap->a_p);
+
+       if (!(flags1 & FNONBLOCK))
+               vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+
+       return (error);
 }
 
 /*
diff -r e4577574b8c4 -r ffda7e6d5340 sys/miscfs/union/union_subr.c
--- a/sys/miscfs/union/union_subr.c     Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/miscfs/union/union_subr.c     Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: union_subr.c,v 1.35 1999/08/01 23:16:34 sommerfeld Exp $       */
+/*     $NetBSD: union_subr.c,v 1.36 1999/10/16 23:53:28 wrstuden Exp $ */
 
 /*
  * Copyright (c) 1994 Jan-Simon Pendry
@@ -706,11 +706,13 @@
        if (error == 0) {
                int i;
 
+               vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY);
                for (i = 0; i < un->un_openl; i++) {
                        (void) VOP_CLOSE(lvp, FREAD, cred, p);
                        (void) VOP_OPEN(uvp, FREAD, cred, p);
                }
                un->un_openl = 0;
+               VOP_UNLOCK(lvp, 0);
        }
 
        return (error);
diff -r e4577574b8c4 -r ffda7e6d5340 sys/msdosfs/msdosfs_vfsops.c
--- a/sys/msdosfs/msdosfs_vfsops.c      Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/msdosfs/msdosfs_vfsops.c      Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msdosfs_vfsops.c,v 1.62 1999/07/17 01:08:29 wrstuden Exp $     */
+/*     $NetBSD: msdosfs_vfsops.c,v 1.63 1999/10/16 23:53:28 wrstuden Exp $     */
 
 /*-
  * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -714,7 +714,9 @@
 error_exit:;
        if (bp)
                brelse(bp);
+       vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        (void) VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
+       VOP_UNLOCK(devvp, 0);
        if (pmp) {
                if (pmp->pm_inusemap)
                        free(pmp->pm_inusemap, M_MSDOSFSFAT);
@@ -777,9 +779,10 @@
                    ((u_int *)vp->v_data)[1]);
        }
 #endif
+       vn_lock(pmp->pm_devvp, LK_EXCLUSIVE | LK_RETRY);
        error = VOP_CLOSE(pmp->pm_devvp,
            pmp->pm_flags & MSDOSFSMNT_RONLY ? FREAD : FREAD|FWRITE, NOCRED, p);
-       vrele(pmp->pm_devvp);
+       vput(pmp->pm_devvp);
        free(pmp->pm_inusemap, M_MSDOSFSFAT);
        free(pmp, M_MSDOSFSMNT);
        mp->mnt_data = (qaddr_t)0;
diff -r e4577574b8c4 -r ffda7e6d5340 sys/ntfs/ntfs_vfsops.c
--- a/sys/ntfs/ntfs_vfsops.c    Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/ntfs/ntfs_vfsops.c    Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ntfs_vfsops.c,v 1.16 1999/10/09 14:27:42 jdolecek Exp $        */
+/*     $NetBSD: ntfs_vfsops.c,v 1.17 1999/10/16 23:53:28 wrstuden Exp $        */
 
 /*-
  * Copyright (c) 1998, 1999 Semen Ustimenko
@@ -606,7 +606,9 @@
 #endif
        if (bp)
                brelse(bp);
+       vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
+       VOP_UNLOCK(devvp, 0);
        return (error);
 }
 
@@ -669,8 +671,10 @@
 #endif
 
        vinvalbuf(ntmp->ntm_devvp, V_SAVE, NOCRED, p, 0, 0);
+       VOP_LOCK(ntmp->ntm_devvp, LK_EXCLUSIVE | LK_RETRY);
        error = VOP_CLOSE(ntmp->ntm_devvp, ronly ? FREAD : FREAD|FWRITE,
                NOCRED, p);
+       VOP_UNLOCK(ntmp->ntm_devvp, 0);
 
        vrele(ntmp->ntm_devvp);
 
diff -r e4577574b8c4 -r ffda7e6d5340 sys/ufs/ext2fs/ext2fs_vfsops.c
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c    Sat Oct 16 20:17:29 1999 +0000
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c    Sat Oct 16 23:53:26 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ext2fs_vfsops.c,v 1.27 1999/07/17 01:08:29 wrstuden Exp $      */
+/*     $NetBSD: ext2fs_vfsops.c,v 1.28 1999/10/16 23:53:28 wrstuden Exp $      */
 
 /*
  * Copyright (c) 1997 Manuel Bouyer.
@@ -612,7 +612,9 @@
 out:



Home | Main Index | Thread Index | Old Index