Source-Changes-HG archive

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

[src/thorpej-devvp]: src/sys/miscfs/specfs Bring locking state of VCHR vnodes...



details:   https://anonhg.NetBSD.org/src/rev/b51a9ad34fd6
branches:  thorpej-devvp
changeset: 514623:b51a9ad34fd6
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Fri Sep 28 20:39:28 2001 +0000

description:
Bring locking state of VCHR vnodes across device entry points back
to what they used to be. The locking state of vnodes across
device functions really needs to be cleaned up, but at least
this is not worse than it was before.

diffstat:

 sys/miscfs/specfs/spec_vnops.c |  48 +++++++++++++++++++++--------------------
 1 files changed, 25 insertions(+), 23 deletions(-)

diffs (149 lines):

diff -r e649ab15ea3a -r b51a9ad34fd6 sys/miscfs/specfs/spec_vnops.c
--- a/sys/miscfs/specfs/spec_vnops.c    Fri Sep 28 20:37:00 2001 +0000
+++ b/sys/miscfs/specfs/spec_vnops.c    Fri Sep 28 20:39:28 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spec_vnops.c,v 1.56.2.4 2001/09/27 14:52:26 fvdl Exp $ */
+/*     $NetBSD: spec_vnops.c,v 1.56.2.5 2001/09/28 20:39:28 fvdl Exp $ */
 
 /*
  * Copyright (c) 1989, 1993
@@ -206,18 +206,14 @@
                }
                if (cdevsw[maj].d_type == D_TTY)
                        vp->v_flag |= VISTTY;
-               /*
-                * XXXXXfvdl why is the vnode unlocked for
-                * a character device open but not for a block device??
-                * This can't be right.
-                */
-               VOP_UNLOCK(vp, 0);
+
                if (iscloningcdev(dev) && vpp != NULL) {
                        error = spec_clonevnode(vp, vpp, dev, VCHR, p);
                        if (error != 0)
                                return error;
                        vp = *vpp;
-               }
+               } else
+                       VOP_UNLOCK(vp, 0);
                error = (*cdevsw[maj].d_open)(vp, ap->a_mode, S_IFCHR, p);
                vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
                return (error);
@@ -243,7 +239,6 @@
                 * a character device open but not for a block device??
                 * This can't be right.
                 */
-               VOP_UNLOCK(vp, 0);
                if (iscloningbdev(dev) && vpp != NULL) {
                        error = spec_clonevnode(vp, vpp, dev, VBLK, p);
                        if (error != 0)
@@ -251,17 +246,14 @@
                        vp = *vpp;
                }
                error = (*bdevsw[maj].d_open)(vp, ap->a_mode, S_IFBLK, p);
-               if (error) {
-                       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+               if (error)
                        return error;
-               }
                error = (*bdevsw[major(vp->v_rdev)].d_ioctl)(vp,
                    DIOCGPART, (caddr_t)&pi, FREAD, curproc);
                if (error == 0) {
                        vp->v_uvm.u_size = (voff_t)pi.disklab->d_secsize *
                            pi.part->p_size;
                }
-               vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
                return 0;
 
        case VNON:
@@ -605,14 +597,17 @@
        } */ *ap = v;
        struct vnode *vp = ap->a_vp;
        dev_t dev = vp->v_rdev;
-       int (*devclose) __P((struct vnode *, int, int, struct proc *));
-       int mode, error, count, flags, flags1;
+       int error, count, flags, fflag;
 
        count = vcount(vp);
        simple_lock(&vp->v_interlock);
        flags = vp->v_flag;
        simple_unlock(&vp->v_interlock);
 
+       fflag = ap->a_fflag;
+       if (flags & VXLOCK)
+               fflag |= FNONBLOCK;
+
        switch (vp->v_type) {
 
        case VCHR:
@@ -640,8 +635,11 @@
                 */
                if (count > 1 && (flags & VXLOCK) == 0)
                        return (0);
-               devclose = cdevsw[major(dev)].d_close;
-               mode = S_IFCHR;
+               if ((flags & VXLOCK) == 0)
+                       VOP_UNLOCK(vp, 0);
+               error = cdevsw[major(dev)].d_close(vp, fflag, S_IFCHR, ap->a_p);
+               if ((flags & VXLOCK) == 0)
+                       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
                break;
 
        case VBLK:
@@ -664,16 +662,13 @@
                 */
                if (count > 1 && (flags & VXLOCK) == 0)
                        return (0);
-               devclose = bdevsw[major(dev)].d_close;
-               mode = S_IFBLK;
+               error = bdevsw[major(dev)].d_close(vp, fflag, S_IFBLK, ap->a_p);
                break;
 
        default:
                panic("spec_close: not special");
        }
 
-       error =  (*devclose)(vp, flags1, mode, ap->a_p);
-
        return (error);
 }
 
@@ -865,7 +860,8 @@
 
 /*
  * Create a clone of a vnode.
- * vp is passed in unlocked, it's locked on exit.
+ * XXX convoluted locking code, because if the inconsistency between
+ * locking for VCHR and VBLK vnodes.
  */
 static int
 spec_clonevnode(struct vnode *vp, struct vnode **vpp, dev_t dev, int type,
@@ -874,6 +870,8 @@
        int error;
        struct vattr *vap;
 
+       VOP_UNLOCK(vp, 0);
+
        error = type == VCHR ? cdevvp(dev, vpp) : bdevvp(dev, vpp);
        if (error != 0)
                goto out;
@@ -886,14 +884,18 @@
        }
 out:
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+       if (type == VBLK)
+               vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY);
        /*
         * XXX check if vnode was revoked while sleeping for the lock.
+        * Can only happen in the VCHR case.
         */
        if ((*vpp)->v_type == VBAD) {
-               vrele(*vpp);
+               vput(*vpp);
                free(vap, M_VNODE);
                return EIO;
        }
+
        if (error == 0) {
                (*vpp)->v_cloneattr = vap;
                (*vpp)->v_flag |= VCLONED;



Home | Main Index | Thread Index | Old Index