more-or-less working with new proc & user structs
[unix-history] / usr / src / sys / miscfs / specfs / spec_vnops.c
index 53425d3..c1f2520 100644 (file)
@@ -2,19 +2,9 @@
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)spec_vnops.c        7.19 (Berkeley) %G%
+ *     @(#)spec_vnops.c        7.31 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
 #include "buf.h"
 #include "mount.h"
 #include "vnode.h"
 #include "buf.h"
 #include "mount.h"
 #include "vnode.h"
+#include "specdev.h"
 #include "stat.h"
 #include "errno.h"
 #include "ioctl.h"
 #include "file.h"
 #include "disklabel.h"
 
 #include "stat.h"
 #include "errno.h"
 #include "ioctl.h"
 #include "file.h"
 #include "disklabel.h"
 
+/* symbolic sleep message strings for devices */
+char   devopn[] = "devopn";
+char   devio[] = "devio";
+char   devwait[] = "devwait";
+char   devin[] = "devin";
+char   devout[] = "devout";
+char   devioc[] = "devioc";
+char   devcls[] = "devcls";
+
 int    spec_lookup(),
        spec_open(),
        spec_read(),
        spec_write(),
        spec_strategy(),
 int    spec_lookup(),
        spec_open(),
        spec_read(),
        spec_write(),
        spec_strategy(),
+       spec_bmap(),
        spec_ioctl(),
        spec_select(),
        spec_lock(),
        spec_unlock(),
        spec_close(),
        spec_ioctl(),
        spec_select(),
        spec_lock(),
        spec_unlock(),
        spec_close(),
+       spec_print(),
+       spec_advlock(),
        spec_ebadf(),
        spec_ebadf(),
-       spec_badop(),
-       spec_nullop();
+       spec_badop();
+
+int    nullop();
 
 struct vnodeops spec_vnodeops = {
        spec_lookup,            /* lookup */
 
 struct vnodeops spec_vnodeops = {
        spec_lookup,            /* lookup */
@@ -59,7 +63,7 @@ struct vnodeops spec_vnodeops = {
        spec_ioctl,             /* ioctl */
        spec_select,            /* select */
        spec_badop,             /* mmap */
        spec_ioctl,             /* ioctl */
        spec_select,            /* select */
        spec_badop,             /* mmap */
-       spec_nullop,            /* fsync */
+       nullop,                 /* fsync */
        spec_badop,             /* seek */
        spec_badop,             /* remove */
        spec_badop,             /* link */
        spec_badop,             /* seek */
        spec_badop,             /* remove */
        spec_badop,             /* link */
@@ -70,12 +74,15 @@ struct vnodeops spec_vnodeops = {
        spec_badop,             /* readdir */
        spec_badop,             /* readlink */
        spec_badop,             /* abortop */
        spec_badop,             /* readdir */
        spec_badop,             /* readlink */
        spec_badop,             /* abortop */
-       spec_nullop,            /* inactive */
-       spec_nullop,            /* reclaim */
+       nullop,                 /* inactive */
+       nullop,                 /* reclaim */
        spec_lock,              /* lock */
        spec_unlock,            /* unlock */
        spec_lock,              /* lock */
        spec_unlock,            /* unlock */
-       spec_badop,             /* bmap */
+       spec_bmap,              /* bmap */
        spec_strategy,          /* strategy */
        spec_strategy,          /* strategy */
+       spec_print,             /* print */
+       nullop,                 /* islocked */
+       spec_advlock,           /* advlock */
 };
 
 /*
 };
 
 /*
@@ -102,10 +109,12 @@ spec_open(vp, mode, cred)
        int mode;
        struct ucred *cred;
 {
        int mode;
        struct ucred *cred;
 {
+       struct proc *p = curproc;               /* XXX */
        dev_t dev = (dev_t)vp->v_rdev;
        register int maj = major(dev);
        dev_t dev = (dev_t)vp->v_rdev;
        register int maj = major(dev);
+       int error;
 
 
-       if (vp->v_mount && (vp->v_mount->m_flag & M_NODEV))
+       if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV))
                return (ENXIO);
 
        switch (vp->v_type) {
                return (ENXIO);
 
        switch (vp->v_type) {
@@ -113,12 +122,14 @@ spec_open(vp, mode, cred)
        case VCHR:
                if ((u_int)maj >= nchrdev)
                        return (ENXIO);
        case VCHR:
                if ((u_int)maj >= nchrdev)
                        return (ENXIO);
-               return ((*cdevsw[maj].d_open)(dev, mode, S_IFCHR));
+               return ((*cdevsw[maj].d_open)(dev, mode, S_IFCHR, p));
 
        case VBLK:
                if ((u_int)maj >= nblkdev)
                        return (ENXIO);
 
        case VBLK:
                if ((u_int)maj >= nblkdev)
                        return (ENXIO);
-               return ((*bdevsw[maj].d_open)(dev, mode, S_IFBLK));
+               if (error = mountedon(vp))
+                       return (error);
+               return ((*bdevsw[maj].d_open)(dev, mode, S_IFBLK, p));
        }
        return (0);
 }
        }
        return (0);
 }
@@ -126,12 +137,14 @@ spec_open(vp, mode, cred)
 /*
  * Vnode op for read
  */
 /*
  * Vnode op for read
  */
+/* ARGSUSED */
 spec_read(vp, uio, ioflag, cred)
        register struct vnode *vp;
        register struct uio *uio;
        int ioflag;
        struct ucred *cred;
 {
 spec_read(vp, uio, ioflag, cred)
        register struct vnode *vp;
        register struct uio *uio;
        int ioflag;
        struct ucred *cred;
 {
+       struct proc *p = curproc;               /* XXX */
        struct buf *bp;
        daddr_t bn;
        long bsize, bscale;
        struct buf *bp;
        daddr_t bn;
        long bsize, bscale;
@@ -155,7 +168,7 @@ spec_read(vp, uio, ioflag, cred)
                        return (EINVAL);
                VOP_UNLOCK(vp);
                error = (*cdevsw[major(vp->v_rdev)].d_read)
                        return (EINVAL);
                VOP_UNLOCK(vp);
                error = (*cdevsw[major(vp->v_rdev)].d_read)
-                       (vp->v_rdev, uio, ioflag);
+                       (vp->v_rdev, uio, ioflag, p);
                VOP_LOCK(vp);
                return (error);
 
                VOP_LOCK(vp);
                return (error);
 
@@ -164,7 +177,7 @@ spec_read(vp, uio, ioflag, cred)
                        return (EINVAL);
                bsize = BLKDEV_IOSIZE;
                if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev, DIOCGPART,
                        return (EINVAL);
                bsize = BLKDEV_IOSIZE;
                if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev, DIOCGPART,
-                   (caddr_t)&dpart, FREAD) == 0) {
+                   (caddr_t)&dpart, FREAD, p) == 0) {
                        if (dpart.part->p_fstype == FS_BSDFFS &&
                            dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
                                bsize = dpart.part->p_frag *
                        if (dpart.part->p_fstype == FS_BSDFFS &&
                            dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
                                bsize = dpart.part->p_frag *
@@ -202,18 +215,20 @@ spec_read(vp, uio, ioflag, cred)
 /*
  * Vnode op for write
  */
 /*
  * Vnode op for write
  */
+/* ARGSUSED */
 spec_write(vp, uio, ioflag, cred)
        register struct vnode *vp;
        register struct uio *uio;
        int ioflag;
        struct ucred *cred;
 {
 spec_write(vp, uio, ioflag, cred)
        register struct vnode *vp;
        register struct uio *uio;
        int ioflag;
        struct ucred *cred;
 {
+       struct proc *p = curproc;               /* XXX */
        struct buf *bp;
        daddr_t bn;
        int bsize, blkmask;
        struct partinfo dpart;
        struct buf *bp;
        daddr_t bn;
        int bsize, blkmask;
        struct partinfo dpart;
-       register int n, on, i;
-       int count, error = 0;
+       register int n, on;
+       int error = 0;
        extern int mem_no;
 
        if (uio->uio_rw != UIO_WRITE)
        extern int mem_no;
 
        if (uio->uio_rw != UIO_WRITE)
@@ -229,7 +244,7 @@ spec_write(vp, uio, ioflag, cred)
                        return (EINVAL);
                VOP_UNLOCK(vp);
                error = (*cdevsw[major(vp->v_rdev)].d_write)
                        return (EINVAL);
                VOP_UNLOCK(vp);
                error = (*cdevsw[major(vp->v_rdev)].d_write)
-                       (vp->v_rdev, uio, ioflag);
+                       (vp->v_rdev, uio, ioflag, p);
                VOP_LOCK(vp);
                return (error);
 
                VOP_LOCK(vp);
                return (error);
 
@@ -240,7 +255,7 @@ spec_write(vp, uio, ioflag, cred)
                        return (EINVAL);
                bsize = BLKDEV_IOSIZE;
                if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev, DIOCGPART,
                        return (EINVAL);
                bsize = BLKDEV_IOSIZE;
                if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev, DIOCGPART,
-                   (caddr_t)&dpart, FREAD) == 0) {
+                   (caddr_t)&dpart, FREAD, p) == 0) {
                        if (dpart.part->p_fstype == FS_BSDFFS &&
                            dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
                                bsize = dpart.part->p_frag *
                        if (dpart.part->p_fstype == FS_BSDFFS &&
                            dpart.part->p_frag != 0 && dpart.part->p_fsize != 0)
                                bsize = dpart.part->p_frag *
@@ -251,9 +266,6 @@ spec_write(vp, uio, ioflag, cred)
                        bn = (uio->uio_offset / DEV_BSIZE) &~ blkmask;
                        on = uio->uio_offset % bsize;
                        n = MIN((unsigned)(bsize - on), uio->uio_resid);
                        bn = (uio->uio_offset / DEV_BSIZE) &~ blkmask;
                        on = uio->uio_offset % bsize;
                        n = MIN((unsigned)(bsize - on), uio->uio_resid);
-                       count = howmany(bsize, CLBYTES);
-                       for (i = 0; i < count; i++)
-                               munhash(vp, bn + i * (CLBYTES / DEV_BSIZE));
                        if (n == bsize)
                                bp = getblk(vp, bn, bsize);
                        else
                        if (n == bsize)
                                bp = getblk(vp, bn, bsize);
                        else
@@ -284,20 +296,28 @@ spec_write(vp, uio, ioflag, cred)
 /* ARGSUSED */
 spec_ioctl(vp, com, data, fflag, cred)
        struct vnode *vp;
 /* ARGSUSED */
 spec_ioctl(vp, com, data, fflag, cred)
        struct vnode *vp;
-       register int com;
+       int com;
        caddr_t data;
        int fflag;
        struct ucred *cred;
 {
        caddr_t data;
        int fflag;
        struct ucred *cred;
 {
+       struct proc *p = curproc;               /* XXX */
        dev_t dev = vp->v_rdev;
 
        switch (vp->v_type) {
 
        case VCHR:
        dev_t dev = vp->v_rdev;
 
        switch (vp->v_type) {
 
        case VCHR:
-               return ((*cdevsw[major(dev)].d_ioctl)(dev, com, data, fflag));
+               return ((*cdevsw[major(dev)].d_ioctl)(dev, com, data,
+                   fflag, p));
 
        case VBLK:
 
        case VBLK:
-               return ((*bdevsw[major(dev)].d_ioctl)(dev, com, data, fflag));
+               if (com == 0 && (int)data == B_TAPE)
+                       if (bdevsw[major(dev)].d_flags & B_TAPE)
+                               return (0);
+                       else
+                               return (1);
+               return ((*bdevsw[major(dev)].d_ioctl)(dev, com, data,
+                  fflag, p));
 
        default:
                panic("spec_ioctl");
 
        default:
                panic("spec_ioctl");
@@ -306,11 +326,12 @@ spec_ioctl(vp, com, data, fflag, cred)
 }
 
 /* ARGSUSED */
 }
 
 /* ARGSUSED */
-spec_select(vp, which, cred)
+spec_select(vp, which, fflags, cred)
        struct vnode *vp;
        struct vnode *vp;
-       int which;
+       int which, fflags;
        struct ucred *cred;
 {
        struct ucred *cred;
 {
+       struct proc *p = curproc;               /* XXX */
        register dev_t dev;
 
        switch (vp->v_type) {
        register dev_t dev;
 
        switch (vp->v_type) {
@@ -320,7 +341,7 @@ spec_select(vp, which, cred)
 
        case VCHR:
                dev = vp->v_rdev;
 
        case VCHR:
                dev = vp->v_rdev;
-               return (*cdevsw[major(dev)].d_select)(dev, which);
+               return (*cdevsw[major(dev)].d_select)(dev, which, p);
        }
 }
 
        }
 }
 
@@ -330,10 +351,28 @@ spec_select(vp, which, cred)
 spec_strategy(bp)
        register struct buf *bp;
 {
 spec_strategy(bp)
        register struct buf *bp;
 {
+
        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
        return (0);
 }
 
        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
        return (0);
 }
 
+/*
+ * This is a noop, simply returning what one has been given.
+ */
+spec_bmap(vp, bn, vpp, bnp)
+       struct vnode *vp;
+       daddr_t bn;
+       struct vnode **vpp;
+       daddr_t *bnp;
+{
+
+       if (vpp != NULL)
+               *vpp = vp;
+       if (bnp != NULL)
+               *bnp = bn;
+       return (0);
+}
+
 /*
  * At the moment we do not do any locking.
  */
 /*
  * At the moment we do not do any locking.
  */
@@ -362,9 +401,10 @@ spec_close(vp, flag, cred)
        int flag;
        struct ucred *cred;
 {
        int flag;
        struct ucred *cred;
 {
+       struct proc *p = curproc;               /* XXX */
        dev_t dev = vp->v_rdev;
        int (*cfunc)();
        dev_t dev = vp->v_rdev;
        int (*cfunc)();
-       int error, mode;
+       int mode;
 
        switch (vp->v_type) {
 
 
        switch (vp->v_type) {
 
@@ -386,8 +426,8 @@ spec_close(vp, flag, cred)
                 * we must invalidate any in core blocks, so that
                 * we can, for instance, change floppy disks.
                 */
                 * we must invalidate any in core blocks, so that
                 * we can, for instance, change floppy disks.
                 */
-               bflush(vp->v_mounton);
-               if (binval(vp->v_mounton))
+               vflushbuf(vp, 0);
+               if (vinvalbuf(vp, 1))
                        return (0);
                /*
                 * We do not want to really close the device if it
                        return (0);
                /*
                 * We do not want to really close the device if it
@@ -408,15 +448,32 @@ spec_close(vp, flag, cred)
                panic("spec_close: not special");
        }
 
                panic("spec_close: not special");
        }
 
-       if (setjmp(&u.u_qsave)) {
-               /*
-                * If device close routine is interrupted,
-                * must return so closef can clean up.
-                */
-               error = EINTR;
-       } else
-               error = (*cfunc)(dev, flag, mode);
-       return (error);
+       return ((*cfunc)(dev, flag, mode, p));
+}
+
+/*
+ * Print out the contents of a special device vnode.
+ */
+spec_print(vp)
+       struct vnode *vp;
+{
+
+       printf("tag VT_NON, dev %d, %d\n", major(vp->v_rdev),
+               minor(vp->v_rdev));
+}
+
+/*
+ * Special device advisory byte-level locks.
+ */
+spec_advlock(vp, id, op, fl, flags)
+       struct vnode *vp;
+       caddr_t id;
+       int op;
+       struct flock *fl;
+       int flags;
+{
+
+       return (EOPNOTSUPP);
 }
 
 /*
 }
 
 /*
@@ -437,12 +494,3 @@ spec_badop()
        panic("spec_badop called");
        /* NOTREACHED */
 }
        panic("spec_badop called");
        /* NOTREACHED */
 }
-
-/*
- * Special device null operation
- */
-spec_nullop()
-{
-
-       return (0);
-}