/* * Pass I/O requests to the memory filesystem process. */ int mfs_strategy(void *v) { struct vop_strategy_args *ap = v; struct buf *bp = ap->a_bp; struct mfsnode *mfsp; struct vnode *vp; struct proc *p = curproc; int s; if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0) panic("mfs_strategy: bad dev"); mfsp = VTOMFS(vp); if (p != NULL && mfsp->mfs_pid == p->p_pid) { mfs_doio(mfsp, bp); } else { s = splbio(); bp->b_actf = mfsp->mfs_buflist; mfsp->mfs_buflist = bp; splx(s); wakeup((caddr_t)vp); } return (0); }
/* * Pass I/O requests to the memory filesystem process. */ int mfs_strategy(void *v) { struct vop_strategy_args *ap = v; struct buf *bp = ap->a_bp; struct mfsnode *mfsp; struct vnode *vp; struct proc *p = curproc; if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0) panic("mfs_strategy: bad dev"); mfsp = VTOMFS(vp); if (p != NULL && mfsp->mfs_pid == p->p_pid) { mfs_doio(mfsp, bp); } else { bufq_queue(&mfsp->mfs_bufq, bp); wakeup(vp); } return (0); }
int cnclose(dev_t dev, int flag, int mode, struct proc *p) { struct vnode *vp; if (cn_tab == NULL) return (0); /* * If the real console isn't otherwise open, close it. * If it's otherwise open, don't close it, because that'll * screw up others who have it open. */ dev = cn_tab->cn_dev; if (cn_devvp != NULL) { /* release our reference to real dev's vnode */ vrele(cn_devvp); cn_devvp = NULL; } if (vfinddev(dev, VCHR, &vp) && vcount(vp)) return (0); return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p)); }
/* * Open a special file. */ int spec_open(void *v) { struct vop_open_args *ap = v; struct proc *p = ap->a_p; struct vnode *vp = ap->a_vp; struct vnode *bvp; dev_t bdev; dev_t dev = (dev_t)vp->v_rdev; int maj = major(dev); int error; /* * Don't allow open if fs is mounted -nodev. */ if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV)) return (ENXIO); switch (vp->v_type) { case VCHR: if ((u_int)maj >= nchrdev) return (ENXIO); if (ap->a_cred != FSCRED && (ap->a_mode & FWRITE)) { /* * When running in very secure mode, do not allow * opens for writing of any disk character devices. */ if (securelevel >= 2 && cdevsw[maj].d_type == D_DISK) return (EPERM); /* * When running in secure mode, do not allow opens * for writing of /dev/mem, /dev/kmem, or character * devices whose corresponding block devices are * currently mounted. */ if (securelevel >= 1) { if ((bdev = chrtoblk(dev)) != NODEV && vfinddev(bdev, VBLK, &bvp) && bvp->v_usecount > 0 && (error = vfs_mountedon(bvp))) return (error); if (iskmemdev(dev)) return (EPERM); } } if (cdevsw[maj].d_type == D_TTY) vp->v_flag |= VISTTY; if (cdevsw[maj].d_flags & D_CLONE) return (spec_open_clone(ap)); VOP_UNLOCK(vp, 0, p); error = (*cdevsw[maj].d_open)(dev, ap->a_mode, S_IFCHR, p); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); return (error); case VBLK: if ((u_int)maj >= nblkdev) return (ENXIO); /* * When running in very secure mode, do not allow * opens for writing of any disk block devices. */ if (securelevel >= 2 && ap->a_cred != FSCRED && (ap->a_mode & FWRITE) && bdevsw[maj].d_type == D_DISK) return (EPERM); /* * Do not allow opens of block devices that are * currently mounted. */ if ((error = vfs_mountedon(vp)) != 0) return (error); return ((*bdevsw[maj].d_open)(dev, ap->a_mode, S_IFBLK, p)); case VNON: case VLNK: case VDIR: case VREG: case VBAD: case VFIFO: case VSOCK: break; } return (0); }