1df8bae1dSRodney W. Grimes /*- 2df8bae1dSRodney W. Grimes * Copyright (c) 1994 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * 5df8bae1dSRodney W. Grimes * This code is derived from software contributed to Berkeley 6df8bae1dSRodney W. Grimes * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 7df8bae1dSRodney W. Grimes * Support code is derived from software contributed to Berkeley 8df8bae1dSRodney W. Grimes * by Atsushi Murai (amurai@spec.co.jp). 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 19df8bae1dSRodney W. Grimes * must display the following acknowledgement: 20df8bae1dSRodney W. Grimes * This product includes software developed by the University of 21df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 22df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 23df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 24df8bae1dSRodney W. Grimes * without specific prior written permission. 25df8bae1dSRodney W. Grimes * 26df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36df8bae1dSRodney W. Grimes * SUCH DAMAGE. 37df8bae1dSRodney W. Grimes * 38996c772fSJohn Dyson * @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95 39539ef70cSPoul-Henning Kamp * $Id: cd9660_vnops.c,v 1.40 1997/09/27 13:38:51 kato Exp $ 40df8bae1dSRodney W. Grimes */ 41df8bae1dSRodney W. Grimes 42df8bae1dSRodney W. Grimes #include <sys/param.h> 43df8bae1dSRodney W. Grimes #include <sys/systm.h> 44df8bae1dSRodney W. Grimes #include <sys/namei.h> 45df8bae1dSRodney W. Grimes #include <sys/kernel.h> 46df8bae1dSRodney W. Grimes #include <sys/stat.h> 479d322006SKATO Takenori #include <sys/sysctl.h> 48df8bae1dSRodney W. Grimes #include <sys/buf.h> 49df8bae1dSRodney W. Grimes #include <sys/mount.h> 50df8bae1dSRodney W. Grimes #include <sys/vnode.h> 51df8bae1dSRodney W. Grimes #include <miscfs/specfs/specdev.h> 52df8bae1dSRodney W. Grimes #include <miscfs/fifofs/fifo.h> 53df8bae1dSRodney W. Grimes #include <sys/malloc.h> 54c90607baSBruce Evans #include <sys/dirent.h> 55996c772fSJohn Dyson #include <sys/unistd.h> 56df8bae1dSRodney W. Grimes 57df8bae1dSRodney W. Grimes #include <isofs/cd9660/iso.h> 58df8bae1dSRodney W. Grimes #include <isofs/cd9660/cd9660_node.h> 59df8bae1dSRodney W. Grimes #include <isofs/cd9660/iso_rrip.h> 60df8bae1dSRodney W. Grimes 6110dd32cdSBruce Evans static int cd9660_setattr __P((struct vop_setattr_args *)); 62605e9724SPoul-Henning Kamp static int cd9660_open __P((struct vop_open_args *)); 63605e9724SPoul-Henning Kamp static int cd9660_close __P((struct vop_close_args *)); 64605e9724SPoul-Henning Kamp static int cd9660_access __P((struct vop_access_args *)); 65605e9724SPoul-Henning Kamp static int cd9660_getattr __P((struct vop_getattr_args *)); 66605e9724SPoul-Henning Kamp static int cd9660_read __P((struct vop_read_args *)); 67605e9724SPoul-Henning Kamp static int cd9660_ioctl __P((struct vop_ioctl_args *)); 68605e9724SPoul-Henning Kamp static int cd9660_mmap __P((struct vop_mmap_args *)); 69605e9724SPoul-Henning Kamp static int cd9660_seek __P((struct vop_seek_args *)); 7010dd32cdSBruce Evans struct isoreaddir; 7110dd32cdSBruce Evans static int iso_uiodir __P((struct isoreaddir *idp, struct dirent *dp, 7210dd32cdSBruce Evans off_t off)); 7310dd32cdSBruce Evans static int iso_shipdir __P((struct isoreaddir *idp)); 74605e9724SPoul-Henning Kamp static int cd9660_readdir __P((struct vop_readdir_args *)); 7510dd32cdSBruce Evans static int cd9660_readlink __P((struct vop_readlink_args *ap)); 76605e9724SPoul-Henning Kamp static int cd9660_abortop __P((struct vop_abortop_args *)); 77605e9724SPoul-Henning Kamp static int cd9660_lock __P((struct vop_lock_args *)); 78605e9724SPoul-Henning Kamp static int cd9660_unlock __P((struct vop_unlock_args *)); 79605e9724SPoul-Henning Kamp static int cd9660_strategy __P((struct vop_strategy_args *)); 80605e9724SPoul-Henning Kamp static int cd9660_print __P((struct vop_print_args *)); 81605e9724SPoul-Henning Kamp static int cd9660_islocked __P((struct vop_islocked_args *)); 8210dd32cdSBruce Evans 83df8bae1dSRodney W. Grimes /* 84de8583ceSDavid Greenman * Setattr call. Only allowed for block and character special devices. 85de8583ceSDavid Greenman */ 86996c772fSJohn Dyson int 87de8583ceSDavid Greenman cd9660_setattr(ap) 88de8583ceSDavid Greenman struct vop_setattr_args /* { 89de8583ceSDavid Greenman struct vnodeop_desc *a_desc; 90de8583ceSDavid Greenman struct vnode *a_vp; 91de8583ceSDavid Greenman struct vattr *a_vap; 92de8583ceSDavid Greenman struct ucred *a_cred; 93de8583ceSDavid Greenman struct proc *a_p; 94de8583ceSDavid Greenman } */ *ap; 95de8583ceSDavid Greenman { 96de8583ceSDavid Greenman struct vnode *vp = ap->a_vp; 97de8583ceSDavid Greenman struct vattr *vap = ap->a_vap; 98de8583ceSDavid Greenman 9992579404SAlexander Langer if (vap->va_flags != (u_long)VNOVAL || vap->va_uid != (uid_t)VNOVAL || 10095a1574eSNate Williams vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 10195a1574eSNate Williams vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) 102de8583ceSDavid Greenman return (EROFS); 10392579404SAlexander Langer if (vap->va_size != (u_quad_t)VNOVAL) { 104de8583ceSDavid Greenman switch (vp->v_type) { 105de8583ceSDavid Greenman case VDIR: 106de8583ceSDavid Greenman return (EISDIR); 107de8583ceSDavid Greenman case VLNK: 108de8583ceSDavid Greenman case VREG: 109de8583ceSDavid Greenman return (EROFS); 110de8583ceSDavid Greenman case VCHR: 111de8583ceSDavid Greenman case VBLK: 112de8583ceSDavid Greenman case VSOCK: 113de8583ceSDavid Greenman case VFIFO: 114de8583ceSDavid Greenman return (0); 115de8583ceSDavid Greenman } 116de8583ceSDavid Greenman } 117996c772fSJohn Dyson return (0); 118de8583ceSDavid Greenman } 119de8583ceSDavid Greenman 120de8583ceSDavid Greenman /* 121df8bae1dSRodney W. Grimes * Open called. 122df8bae1dSRodney W. Grimes * 123df8bae1dSRodney W. Grimes * Nothing to do. 124df8bae1dSRodney W. Grimes */ 125df8bae1dSRodney W. Grimes /* ARGSUSED */ 126605e9724SPoul-Henning Kamp static int 127df8bae1dSRodney W. Grimes cd9660_open(ap) 128df8bae1dSRodney W. Grimes struct vop_open_args /* { 129df8bae1dSRodney W. Grimes struct vnode *a_vp; 130df8bae1dSRodney W. Grimes int a_mode; 131df8bae1dSRodney W. Grimes struct ucred *a_cred; 132df8bae1dSRodney W. Grimes struct proc *a_p; 133df8bae1dSRodney W. Grimes } */ *ap; 134df8bae1dSRodney W. Grimes { 135df8bae1dSRodney W. Grimes return (0); 136df8bae1dSRodney W. Grimes } 137df8bae1dSRodney W. Grimes 138df8bae1dSRodney W. Grimes /* 139df8bae1dSRodney W. Grimes * Close called 140df8bae1dSRodney W. Grimes * 141df8bae1dSRodney W. Grimes * Update the times on the inode on writeable file systems. 142df8bae1dSRodney W. Grimes */ 143df8bae1dSRodney W. Grimes /* ARGSUSED */ 144605e9724SPoul-Henning Kamp static int 145df8bae1dSRodney W. Grimes cd9660_close(ap) 146df8bae1dSRodney W. Grimes struct vop_close_args /* { 147df8bae1dSRodney W. Grimes struct vnode *a_vp; 148df8bae1dSRodney W. Grimes int a_fflag; 149df8bae1dSRodney W. Grimes struct ucred *a_cred; 150df8bae1dSRodney W. Grimes struct proc *a_p; 151df8bae1dSRodney W. Grimes } */ *ap; 152df8bae1dSRodney W. Grimes { 153df8bae1dSRodney W. Grimes return (0); 154df8bae1dSRodney W. Grimes } 155df8bae1dSRodney W. Grimes 156df8bae1dSRodney W. Grimes /* 157df8bae1dSRodney W. Grimes * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 158df8bae1dSRodney W. Grimes * The mode is shifted to select the owner/group/other fields. The 159df8bae1dSRodney W. Grimes * super user is granted all permissions. 160df8bae1dSRodney W. Grimes */ 161df8bae1dSRodney W. Grimes /* ARGSUSED */ 162605e9724SPoul-Henning Kamp static int 163df8bae1dSRodney W. Grimes cd9660_access(ap) 164df8bae1dSRodney W. Grimes struct vop_access_args /* { 165df8bae1dSRodney W. Grimes struct vnode *a_vp; 166df8bae1dSRodney W. Grimes int a_mode; 167df8bae1dSRodney W. Grimes struct ucred *a_cred; 168df8bae1dSRodney W. Grimes struct proc *a_p; 169df8bae1dSRodney W. Grimes } */ *ap; 170df8bae1dSRodney W. Grimes { 171996c772fSJohn Dyson struct vnode *vp = ap->a_vp; 172996c772fSJohn Dyson struct iso_node *ip = VTOI(vp); 173996c772fSJohn Dyson struct ucred *cred = ap->a_cred; 174996c772fSJohn Dyson mode_t mask, mode = ap->a_mode; 175996c772fSJohn Dyson gid_t *gp; 176996c772fSJohn Dyson int i; 177996c772fSJohn Dyson 178ba14c327SDavid Greenman /* 179996c772fSJohn Dyson * Disallow write attempts unless the file is a socket, 180996c772fSJohn Dyson * fifo, or a block or character device resident on the 181996c772fSJohn Dyson * file system. 182ba14c327SDavid Greenman */ 183996c772fSJohn Dyson if (mode & VWRITE) { 184996c772fSJohn Dyson switch (vp->v_type) { 185ba14c327SDavid Greenman case VDIR: 186ba14c327SDavid Greenman case VLNK: 187ba14c327SDavid Greenman case VREG: 188ba14c327SDavid Greenman return (EROFS); 189ba14c327SDavid Greenman } 190ba14c327SDavid Greenman } 191ba14c327SDavid Greenman 192996c772fSJohn Dyson /* User id 0 always gets access. */ 193996c772fSJohn Dyson if (cred->cr_uid == 0) 194df8bae1dSRodney W. Grimes return (0); 195996c772fSJohn Dyson 196996c772fSJohn Dyson mask = 0; 197996c772fSJohn Dyson 198996c772fSJohn Dyson /* Otherwise, check the owner. */ 199996c772fSJohn Dyson if (cred->cr_uid == ip->inode.iso_uid) { 200996c772fSJohn Dyson if (mode & VEXEC) 201996c772fSJohn Dyson mask |= S_IXUSR; 202996c772fSJohn Dyson if (mode & VREAD) 203996c772fSJohn Dyson mask |= S_IRUSR; 204996c772fSJohn Dyson if (mode & VWRITE) 205996c772fSJohn Dyson mask |= S_IWUSR; 206996c772fSJohn Dyson return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); 207996c772fSJohn Dyson } 208996c772fSJohn Dyson 209996c772fSJohn Dyson /* Otherwise, check the groups. */ 210996c772fSJohn Dyson for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) 211996c772fSJohn Dyson if (ip->inode.iso_gid == *gp) { 212996c772fSJohn Dyson if (mode & VEXEC) 213996c772fSJohn Dyson mask |= S_IXGRP; 214996c772fSJohn Dyson if (mode & VREAD) 215996c772fSJohn Dyson mask |= S_IRGRP; 216996c772fSJohn Dyson if (mode & VWRITE) 217996c772fSJohn Dyson mask |= S_IWGRP; 218996c772fSJohn Dyson return ((ip->inode.iso_mode & mask) == mask ? 219996c772fSJohn Dyson 0 : EACCES); 220996c772fSJohn Dyson } 221996c772fSJohn Dyson 222996c772fSJohn Dyson /* Otherwise, check everyone else. */ 223996c772fSJohn Dyson if (mode & VEXEC) 224996c772fSJohn Dyson mask |= S_IXOTH; 225996c772fSJohn Dyson if (mode & VREAD) 226996c772fSJohn Dyson mask |= S_IROTH; 227996c772fSJohn Dyson if (mode & VWRITE) 228996c772fSJohn Dyson mask |= S_IWOTH; 229996c772fSJohn Dyson return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); 230df8bae1dSRodney W. Grimes } 231df8bae1dSRodney W. Grimes 232605e9724SPoul-Henning Kamp static int 233df8bae1dSRodney W. Grimes cd9660_getattr(ap) 234df8bae1dSRodney W. Grimes struct vop_getattr_args /* { 235df8bae1dSRodney W. Grimes struct vnode *a_vp; 236df8bae1dSRodney W. Grimes struct vattr *a_vap; 237df8bae1dSRodney W. Grimes struct ucred *a_cred; 238df8bae1dSRodney W. Grimes struct proc *a_p; 239df8bae1dSRodney W. Grimes } */ *ap; 240df8bae1dSRodney W. Grimes 241df8bae1dSRodney W. Grimes { 242df8bae1dSRodney W. Grimes struct vnode *vp = ap->a_vp; 243df8bae1dSRodney W. Grimes register struct vattr *vap = ap->a_vap; 244df8bae1dSRodney W. Grimes register struct iso_node *ip = VTOI(vp); 245df8bae1dSRodney W. Grimes 246df8bae1dSRodney W. Grimes vap->va_fsid = ip->i_dev; 247df8bae1dSRodney W. Grimes vap->va_fileid = ip->i_number; 248df8bae1dSRodney W. Grimes 249df8bae1dSRodney W. Grimes vap->va_mode = ip->inode.iso_mode; 250df8bae1dSRodney W. Grimes vap->va_nlink = ip->inode.iso_links; 251df8bae1dSRodney W. Grimes vap->va_uid = ip->inode.iso_uid; 252df8bae1dSRodney W. Grimes vap->va_gid = ip->inode.iso_gid; 253df8bae1dSRodney W. Grimes vap->va_atime = ip->inode.iso_atime; 254df8bae1dSRodney W. Grimes vap->va_mtime = ip->inode.iso_mtime; 255df8bae1dSRodney W. Grimes vap->va_ctime = ip->inode.iso_ctime; 256df8bae1dSRodney W. Grimes vap->va_rdev = ip->inode.iso_rdev; 257df8bae1dSRodney W. Grimes 258df8bae1dSRodney W. Grimes vap->va_size = (u_quad_t) ip->i_size; 259996c772fSJohn Dyson if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) { 260996c772fSJohn Dyson struct vop_readlink_args rdlnk; 261996c772fSJohn Dyson struct iovec aiov; 262996c772fSJohn Dyson struct uio auio; 263996c772fSJohn Dyson char *cp; 264996c772fSJohn Dyson 265996c772fSJohn Dyson MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK); 266996c772fSJohn Dyson aiov.iov_base = cp; 267996c772fSJohn Dyson aiov.iov_len = MAXPATHLEN; 268996c772fSJohn Dyson auio.uio_iov = &aiov; 269996c772fSJohn Dyson auio.uio_iovcnt = 1; 270996c772fSJohn Dyson auio.uio_offset = 0; 271996c772fSJohn Dyson auio.uio_rw = UIO_READ; 272996c772fSJohn Dyson auio.uio_segflg = UIO_SYSSPACE; 273996c772fSJohn Dyson auio.uio_procp = ap->a_p; 274996c772fSJohn Dyson auio.uio_resid = MAXPATHLEN; 275996c772fSJohn Dyson rdlnk.a_uio = &auio; 276996c772fSJohn Dyson rdlnk.a_vp = ap->a_vp; 277996c772fSJohn Dyson rdlnk.a_cred = ap->a_cred; 278996c772fSJohn Dyson if (cd9660_readlink(&rdlnk) == 0) 279996c772fSJohn Dyson vap->va_size = MAXPATHLEN - auio.uio_resid; 280996c772fSJohn Dyson FREE(cp, M_TEMP); 281996c772fSJohn Dyson } 282df8bae1dSRodney W. Grimes vap->va_flags = 0; 283df8bae1dSRodney W. Grimes vap->va_gen = 1; 284df8bae1dSRodney W. Grimes vap->va_blocksize = ip->i_mnt->logical_block_size; 285df8bae1dSRodney W. Grimes vap->va_bytes = (u_quad_t) ip->i_size; 286df8bae1dSRodney W. Grimes vap->va_type = vp->v_type; 28794a8606fSDoug Rabson vap->va_filerev = 0; 288df8bae1dSRodney W. Grimes return (0); 289df8bae1dSRodney W. Grimes } 290df8bae1dSRodney W. Grimes 291df8bae1dSRodney W. Grimes /* 292df8bae1dSRodney W. Grimes * Vnode op for reading. 293df8bae1dSRodney W. Grimes */ 294605e9724SPoul-Henning Kamp static int 295df8bae1dSRodney W. Grimes cd9660_read(ap) 296df8bae1dSRodney W. Grimes struct vop_read_args /* { 297df8bae1dSRodney W. Grimes struct vnode *a_vp; 298df8bae1dSRodney W. Grimes struct uio *a_uio; 299df8bae1dSRodney W. Grimes int a_ioflag; 300df8bae1dSRodney W. Grimes struct ucred *a_cred; 301df8bae1dSRodney W. Grimes } */ *ap; 302df8bae1dSRodney W. Grimes { 303df8bae1dSRodney W. Grimes struct vnode *vp = ap->a_vp; 304df8bae1dSRodney W. Grimes register struct uio *uio = ap->a_uio; 305df8bae1dSRodney W. Grimes register struct iso_node *ip = VTOI(vp); 306df8bae1dSRodney W. Grimes register struct iso_mnt *imp; 307df8bae1dSRodney W. Grimes struct buf *bp; 3081295d82eSGary Palmer daddr_t lbn, rablock; 309df8bae1dSRodney W. Grimes off_t diff; 310df8bae1dSRodney W. Grimes int rasize, error = 0; 311df8bae1dSRodney W. Grimes long size, n, on; 312df8bae1dSRodney W. Grimes 313df8bae1dSRodney W. Grimes if (uio->uio_resid == 0) 314df8bae1dSRodney W. Grimes return (0); 315df8bae1dSRodney W. Grimes if (uio->uio_offset < 0) 316df8bae1dSRodney W. Grimes return (EINVAL); 317996c772fSJohn Dyson ip->i_flag |= IN_ACCESS; 318df8bae1dSRodney W. Grimes imp = ip->i_mnt; 319df8bae1dSRodney W. Grimes do { 320996c772fSJohn Dyson lbn = lblkno(imp, uio->uio_offset); 321996c772fSJohn Dyson on = blkoff(imp, uio->uio_offset); 322996c772fSJohn Dyson n = min((u_int)(imp->logical_block_size - on), 323df8bae1dSRodney W. Grimes uio->uio_resid); 324df8bae1dSRodney W. Grimes diff = (off_t)ip->i_size - uio->uio_offset; 325df8bae1dSRodney W. Grimes if (diff <= 0) 326df8bae1dSRodney W. Grimes return (0); 327df8bae1dSRodney W. Grimes if (diff < n) 328df8bae1dSRodney W. Grimes n = diff; 329996c772fSJohn Dyson size = blksize(imp, ip, lbn); 330df8bae1dSRodney W. Grimes rablock = lbn + 1; 33181bca6ddSKATO Takenori if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) { 332996c772fSJohn Dyson if (lblktosize(imp, rablock) <= ip->i_size) 333996c772fSJohn Dyson error = cluster_read(vp, (off_t)ip->i_size, 3348b612c4bSJohn Dyson lbn, size, NOCRED, uio->uio_resid, 3358b612c4bSJohn Dyson (ap->a_ioflag >> 16), &bp); 336df8bae1dSRodney W. Grimes else 337df8bae1dSRodney W. Grimes error = bread(vp, lbn, size, NOCRED, &bp); 338df8bae1dSRodney W. Grimes } else { 339df8bae1dSRodney W. Grimes if (vp->v_lastr + 1 == lbn && 340996c772fSJohn Dyson lblktosize(imp, rablock) < ip->i_size) { 341996c772fSJohn Dyson rasize = blksize(imp, ip, rablock); 342df8bae1dSRodney W. Grimes error = breadn(vp, lbn, size, &rablock, 343df8bae1dSRodney W. Grimes &rasize, 1, NOCRED, &bp); 344df8bae1dSRodney W. Grimes } else 345df8bae1dSRodney W. Grimes error = bread(vp, lbn, size, NOCRED, &bp); 346df8bae1dSRodney W. Grimes } 347df8bae1dSRodney W. Grimes vp->v_lastr = lbn; 348df8bae1dSRodney W. Grimes n = min(n, size - bp->b_resid); 349df8bae1dSRodney W. Grimes if (error) { 350df8bae1dSRodney W. Grimes brelse(bp); 351df8bae1dSRodney W. Grimes return (error); 352df8bae1dSRodney W. Grimes } 353df8bae1dSRodney W. Grimes 354996c772fSJohn Dyson error = uiomove(bp->b_data + on, (int)n, uio); 355df8bae1dSRodney W. Grimes brelse(bp); 356df8bae1dSRodney W. Grimes } while (error == 0 && uio->uio_resid > 0 && n != 0); 357df8bae1dSRodney W. Grimes return (error); 358df8bae1dSRodney W. Grimes } 359df8bae1dSRodney W. Grimes 360df8bae1dSRodney W. Grimes /* ARGSUSED */ 361605e9724SPoul-Henning Kamp static int 362df8bae1dSRodney W. Grimes cd9660_ioctl(ap) 363df8bae1dSRodney W. Grimes struct vop_ioctl_args /* { 364df8bae1dSRodney W. Grimes struct vnode *a_vp; 365996c772fSJohn Dyson u_long a_command; 366df8bae1dSRodney W. Grimes caddr_t a_data; 367df8bae1dSRodney W. Grimes int a_fflag; 368df8bae1dSRodney W. Grimes struct ucred *a_cred; 369df8bae1dSRodney W. Grimes struct proc *a_p; 370df8bae1dSRodney W. Grimes } */ *ap; 371df8bae1dSRodney W. Grimes { 372df8bae1dSRodney W. Grimes printf("You did ioctl for isofs !!\n"); 373df8bae1dSRodney W. Grimes return (ENOTTY); 374df8bae1dSRodney W. Grimes } 375df8bae1dSRodney W. Grimes 376df8bae1dSRodney W. Grimes /* 377df8bae1dSRodney W. Grimes * Mmap a file 378df8bae1dSRodney W. Grimes * 379df8bae1dSRodney W. Grimes * NB Currently unsupported. 380df8bae1dSRodney W. Grimes */ 381df8bae1dSRodney W. Grimes /* ARGSUSED */ 382605e9724SPoul-Henning Kamp static int 383df8bae1dSRodney W. Grimes cd9660_mmap(ap) 384df8bae1dSRodney W. Grimes struct vop_mmap_args /* { 385df8bae1dSRodney W. Grimes struct vnode *a_vp; 386df8bae1dSRodney W. Grimes int a_fflags; 387df8bae1dSRodney W. Grimes struct ucred *a_cred; 388df8bae1dSRodney W. Grimes struct proc *a_p; 389df8bae1dSRodney W. Grimes } */ *ap; 390df8bae1dSRodney W. Grimes { 391df8bae1dSRodney W. Grimes 392df8bae1dSRodney W. Grimes return (EINVAL); 393df8bae1dSRodney W. Grimes } 394df8bae1dSRodney W. Grimes 395df8bae1dSRodney W. Grimes /* 396df8bae1dSRodney W. Grimes * Seek on a file 397df8bae1dSRodney W. Grimes * 398df8bae1dSRodney W. Grimes * Nothing to do, so just return. 399df8bae1dSRodney W. Grimes */ 400df8bae1dSRodney W. Grimes /* ARGSUSED */ 401605e9724SPoul-Henning Kamp static int 402df8bae1dSRodney W. Grimes cd9660_seek(ap) 403df8bae1dSRodney W. Grimes struct vop_seek_args /* { 404df8bae1dSRodney W. Grimes struct vnode *a_vp; 405df8bae1dSRodney W. Grimes off_t a_oldoff; 406df8bae1dSRodney W. Grimes off_t a_newoff; 407df8bae1dSRodney W. Grimes struct ucred *a_cred; 408df8bae1dSRodney W. Grimes } */ *ap; 409df8bae1dSRodney W. Grimes { 410df8bae1dSRodney W. Grimes 411df8bae1dSRodney W. Grimes return (0); 412df8bae1dSRodney W. Grimes } 413df8bae1dSRodney W. Grimes 414df8bae1dSRodney W. Grimes /* 415df8bae1dSRodney W. Grimes * Structure for reading directories 416df8bae1dSRodney W. Grimes */ 417df8bae1dSRodney W. Grimes struct isoreaddir { 418df8bae1dSRodney W. Grimes struct dirent saveent; 419df8bae1dSRodney W. Grimes struct dirent assocent; 420df8bae1dSRodney W. Grimes struct dirent current; 421df8bae1dSRodney W. Grimes off_t saveoff; 422df8bae1dSRodney W. Grimes off_t assocoff; 423df8bae1dSRodney W. Grimes off_t curroff; 424df8bae1dSRodney W. Grimes struct uio *uio; 425df8bae1dSRodney W. Grimes off_t uio_off; 426996c772fSJohn Dyson int eofflag; 427996c772fSJohn Dyson u_long *cookies; 428df8bae1dSRodney W. Grimes int ncookies; 429df8bae1dSRodney W. Grimes }; 430df8bae1dSRodney W. Grimes 431996c772fSJohn Dyson int 432df8bae1dSRodney W. Grimes iso_uiodir(idp,dp,off) 433df8bae1dSRodney W. Grimes struct isoreaddir *idp; 434df8bae1dSRodney W. Grimes struct dirent *dp; 435df8bae1dSRodney W. Grimes off_t off; 436df8bae1dSRodney W. Grimes { 437df8bae1dSRodney W. Grimes int error; 438df8bae1dSRodney W. Grimes 439df8bae1dSRodney W. Grimes dp->d_name[dp->d_namlen] = 0; 440c90607baSBruce Evans dp->d_reclen = GENERIC_DIRSIZ(dp); 441df8bae1dSRodney W. Grimes 442df8bae1dSRodney W. Grimes if (idp->uio->uio_resid < dp->d_reclen) { 443996c772fSJohn Dyson idp->eofflag = 0; 444996c772fSJohn Dyson return (-1); 445df8bae1dSRodney W. Grimes } 446df8bae1dSRodney W. Grimes 447996c772fSJohn Dyson if (idp->cookies) { 448df8bae1dSRodney W. Grimes if (idp->ncookies <= 0) { 449996c772fSJohn Dyson idp->eofflag = 0; 450996c772fSJohn Dyson return (-1); 451df8bae1dSRodney W. Grimes } 452df8bae1dSRodney W. Grimes 453996c772fSJohn Dyson *idp->cookies++ = off; 454df8bae1dSRodney W. Grimes --idp->ncookies; 455df8bae1dSRodney W. Grimes } 456df8bae1dSRodney W. Grimes 457996c772fSJohn Dyson if (error = uiomove((caddr_t) dp,dp->d_reclen,idp->uio)) 458996c772fSJohn Dyson return (error); 459df8bae1dSRodney W. Grimes idp->uio_off = off; 460996c772fSJohn Dyson return (0); 461df8bae1dSRodney W. Grimes } 462df8bae1dSRodney W. Grimes 463996c772fSJohn Dyson int 464df8bae1dSRodney W. Grimes iso_shipdir(idp) 465df8bae1dSRodney W. Grimes struct isoreaddir *idp; 466df8bae1dSRodney W. Grimes { 467df8bae1dSRodney W. Grimes struct dirent *dp; 468df8bae1dSRodney W. Grimes int cl, sl, assoc; 469df8bae1dSRodney W. Grimes int error; 470df8bae1dSRodney W. Grimes char *cname, *sname; 471df8bae1dSRodney W. Grimes 472df8bae1dSRodney W. Grimes cl = idp->current.d_namlen; 473df8bae1dSRodney W. Grimes cname = idp->current.d_name; 4741295d82eSGary Palmer assoc = (cl > 1) && (*cname == ASSOCCHAR); 4751295d82eSGary Palmer if (assoc) { 476df8bae1dSRodney W. Grimes cl--; 477df8bae1dSRodney W. Grimes cname++; 478df8bae1dSRodney W. Grimes } 479df8bae1dSRodney W. Grimes 480df8bae1dSRodney W. Grimes dp = &idp->saveent; 481df8bae1dSRodney W. Grimes sname = dp->d_name; 482df8bae1dSRodney W. Grimes if (!(sl = dp->d_namlen)) { 483df8bae1dSRodney W. Grimes dp = &idp->assocent; 484df8bae1dSRodney W. Grimes sname = dp->d_name + 1; 485df8bae1dSRodney W. Grimes sl = dp->d_namlen - 1; 486df8bae1dSRodney W. Grimes } 487df8bae1dSRodney W. Grimes if (sl > 0) { 488df8bae1dSRodney W. Grimes if (sl != cl 489df8bae1dSRodney W. Grimes || bcmp(sname,cname,sl)) { 490df8bae1dSRodney W. Grimes if (idp->assocent.d_namlen) { 491996c772fSJohn Dyson if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) 492996c772fSJohn Dyson return (error); 493df8bae1dSRodney W. Grimes idp->assocent.d_namlen = 0; 494df8bae1dSRodney W. Grimes } 495df8bae1dSRodney W. Grimes if (idp->saveent.d_namlen) { 496996c772fSJohn Dyson if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) 497996c772fSJohn Dyson return (error); 498df8bae1dSRodney W. Grimes idp->saveent.d_namlen = 0; 499df8bae1dSRodney W. Grimes } 500df8bae1dSRodney W. Grimes } 501df8bae1dSRodney W. Grimes } 502c90607baSBruce Evans idp->current.d_reclen = GENERIC_DIRSIZ(&idp->current); 503df8bae1dSRodney W. Grimes if (assoc) { 504df8bae1dSRodney W. Grimes idp->assocoff = idp->curroff; 505df8bae1dSRodney W. Grimes bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); 506df8bae1dSRodney W. Grimes } else { 507df8bae1dSRodney W. Grimes idp->saveoff = idp->curroff; 508df8bae1dSRodney W. Grimes bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); 509df8bae1dSRodney W. Grimes } 510996c772fSJohn Dyson return (0); 511df8bae1dSRodney W. Grimes } 512df8bae1dSRodney W. Grimes 513df8bae1dSRodney W. Grimes /* 514df8bae1dSRodney W. Grimes * Vnode op for readdir 515df8bae1dSRodney W. Grimes */ 516605e9724SPoul-Henning Kamp static int 517df8bae1dSRodney W. Grimes cd9660_readdir(ap) 518df8bae1dSRodney W. Grimes struct vop_readdir_args /* { 519df8bae1dSRodney W. Grimes struct vnode *a_vp; 520df8bae1dSRodney W. Grimes struct uio *a_uio; 521df8bae1dSRodney W. Grimes struct ucred *a_cred; 522996c772fSJohn Dyson int *a_eofflag; 523996c772fSJohn Dyson int *a_ncookies; 524996c772fSJohn Dyson u_long *a_cookies; 525df8bae1dSRodney W. Grimes } */ *ap; 526df8bae1dSRodney W. Grimes { 527df8bae1dSRodney W. Grimes register struct uio *uio = ap->a_uio; 528df8bae1dSRodney W. Grimes struct isoreaddir *idp; 529996c772fSJohn Dyson struct vnode *vdp = ap->a_vp; 530996c772fSJohn Dyson struct iso_node *dp; 531df8bae1dSRodney W. Grimes struct iso_mnt *imp; 532df8bae1dSRodney W. Grimes struct buf *bp = NULL; 533996c772fSJohn Dyson struct iso_directory_record *ep; 534996c772fSJohn Dyson int entryoffsetinblock; 535996c772fSJohn Dyson doff_t endsearch; 536996c772fSJohn Dyson u_long bmask; 537996c772fSJohn Dyson int error = 0; 538996c772fSJohn Dyson int reclen; 539996c772fSJohn Dyson u_short namelen; 5409abf4d6eSDoug Rabson int ncookies = 0; 541996c772fSJohn Dyson u_long *cookies = NULL; 542df8bae1dSRodney W. Grimes 543996c772fSJohn Dyson dp = VTOI(vdp); 544996c772fSJohn Dyson imp = dp->i_mnt; 545996c772fSJohn Dyson bmask = imp->im_bmask; 546df8bae1dSRodney W. Grimes 547df8bae1dSRodney W. Grimes MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK); 548996c772fSJohn Dyson idp->saveent.d_namlen = idp->assocent.d_namlen = 0; 549996c772fSJohn Dyson /* 550996c772fSJohn Dyson * XXX 551996c772fSJohn Dyson * Is it worth trying to figure out the type? 552996c772fSJohn Dyson */ 553996c772fSJohn Dyson idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = 554996c772fSJohn Dyson DT_UNKNOWN; 555df8bae1dSRodney W. Grimes idp->uio = uio; 556996c772fSJohn Dyson if (ap->a_ncookies == NULL) { 557996c772fSJohn Dyson idp->cookies = NULL; 558996c772fSJohn Dyson } else { 5599abf4d6eSDoug Rabson /* 5609abf4d6eSDoug Rabson * Guess the number of cookies needed. 5619abf4d6eSDoug Rabson */ 5629abf4d6eSDoug Rabson ncookies = uio->uio_resid / 16; 563996c772fSJohn Dyson MALLOC(cookies, u_long *, ncookies * sizeof(u_int), M_TEMP, 564996c772fSJohn Dyson M_WAITOK); 565996c772fSJohn Dyson idp->cookies = cookies; 566df8bae1dSRodney W. Grimes idp->ncookies = ncookies; 567996c772fSJohn Dyson } 568996c772fSJohn Dyson idp->eofflag = 1; 569df8bae1dSRodney W. Grimes idp->curroff = uio->uio_offset; 570df8bae1dSRodney W. Grimes 571996c772fSJohn Dyson if ((entryoffsetinblock = idp->curroff & bmask) && 572996c772fSJohn Dyson (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) { 573df8bae1dSRodney W. Grimes FREE(idp, M_TEMP); 574df8bae1dSRodney W. Grimes return (error); 575df8bae1dSRodney W. Grimes } 576996c772fSJohn Dyson endsearch = dp->i_size; 577df8bae1dSRodney W. Grimes 578df8bae1dSRodney W. Grimes while (idp->curroff < endsearch) { 579df8bae1dSRodney W. Grimes /* 580df8bae1dSRodney W. Grimes * If offset is on a block boundary, 581df8bae1dSRodney W. Grimes * read the next directory block. 582df8bae1dSRodney W. Grimes * Release previous if it exists. 583df8bae1dSRodney W. Grimes */ 584996c772fSJohn Dyson if ((idp->curroff & bmask) == 0) { 585df8bae1dSRodney W. Grimes if (bp != NULL) 586df8bae1dSRodney W. Grimes brelse(bp); 587996c772fSJohn Dyson if (error = 588996c772fSJohn Dyson VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp)) 589df8bae1dSRodney W. Grimes break; 590df8bae1dSRodney W. Grimes entryoffsetinblock = 0; 591df8bae1dSRodney W. Grimes } 592df8bae1dSRodney W. Grimes /* 593df8bae1dSRodney W. Grimes * Get pointer to next entry. 594df8bae1dSRodney W. Grimes */ 595df8bae1dSRodney W. Grimes ep = (struct iso_directory_record *) 596996c772fSJohn Dyson ((char *)bp->b_data + entryoffsetinblock); 597df8bae1dSRodney W. Grimes 598df8bae1dSRodney W. Grimes reclen = isonum_711(ep->length); 599df8bae1dSRodney W. Grimes if (reclen == 0) { 600df8bae1dSRodney W. Grimes /* skip to next block, if any */ 601996c772fSJohn Dyson idp->curroff = 602996c772fSJohn Dyson (idp->curroff & ~bmask) + imp->logical_block_size; 603df8bae1dSRodney W. Grimes continue; 604df8bae1dSRodney W. Grimes } 605df8bae1dSRodney W. Grimes 606df8bae1dSRodney W. Grimes if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 607df8bae1dSRodney W. Grimes error = EINVAL; 608df8bae1dSRodney W. Grimes /* illegal entry, stop */ 609df8bae1dSRodney W. Grimes break; 610df8bae1dSRodney W. Grimes } 611df8bae1dSRodney W. Grimes 612df8bae1dSRodney W. Grimes if (entryoffsetinblock + reclen > imp->logical_block_size) { 613df8bae1dSRodney W. Grimes error = EINVAL; 614df8bae1dSRodney W. Grimes /* illegal directory, so stop looking */ 615df8bae1dSRodney W. Grimes break; 616df8bae1dSRodney W. Grimes } 617df8bae1dSRodney W. Grimes 618996c772fSJohn Dyson idp->current.d_namlen = isonum_711(ep->name_len); 619996c772fSJohn Dyson 620996c772fSJohn Dyson if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 62181ec856aSJoerg Wunsch error = EINVAL; 62281ec856aSJoerg Wunsch /* illegal entry, stop */ 62381ec856aSJoerg Wunsch break; 62481ec856aSJoerg Wunsch } 62581ec856aSJoerg Wunsch 626996c772fSJohn Dyson if (isonum_711(ep->flags)&2) 627996c772fSJohn Dyson idp->current.d_fileno = isodirino(ep, imp); 628df8bae1dSRodney W. Grimes else 629df8bae1dSRodney W. Grimes idp->current.d_fileno = dbtob(bp->b_blkno) + 630996c772fSJohn Dyson entryoffsetinblock; 631df8bae1dSRodney W. Grimes 632df8bae1dSRodney W. Grimes idp->curroff += reclen; 633996c772fSJohn Dyson 634df8bae1dSRodney W. Grimes switch (imp->iso_ftype) { 635df8bae1dSRodney W. Grimes case ISO_FTYPE_RRIP: 636996c772fSJohn Dyson cd9660_rrip_getname(ep,idp->current.d_name, &namelen, 637df8bae1dSRodney W. Grimes &idp->current.d_fileno,imp); 638996c772fSJohn Dyson idp->current.d_namlen = (u_char)namelen; 639df8bae1dSRodney W. Grimes if (idp->current.d_namlen) 640df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 641df8bae1dSRodney W. Grimes break; 642988fa8efSJoerg Wunsch default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 || ISO_FTYPE_HIGH_SIERRA*/ 643df8bae1dSRodney W. Grimes strcpy(idp->current.d_name,".."); 644df8bae1dSRodney W. Grimes switch (ep->name[0]) { 645df8bae1dSRodney W. Grimes case 0: 646df8bae1dSRodney W. Grimes idp->current.d_namlen = 1; 647df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 648df8bae1dSRodney W. Grimes break; 649df8bae1dSRodney W. Grimes case 1: 650df8bae1dSRodney W. Grimes idp->current.d_namlen = 2; 651df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 652df8bae1dSRodney W. Grimes break; 653df8bae1dSRodney W. Grimes default: 654df8bae1dSRodney W. Grimes isofntrans(ep->name,idp->current.d_namlen, 655996c772fSJohn Dyson idp->current.d_name, &namelen, 656df8bae1dSRodney W. Grimes imp->iso_ftype == ISO_FTYPE_9660, 657996c772fSJohn Dyson isonum_711(ep->flags)&4); 658996c772fSJohn Dyson idp->current.d_namlen = (u_char)namelen; 659df8bae1dSRodney W. Grimes if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 660df8bae1dSRodney W. Grimes error = iso_shipdir(idp); 661df8bae1dSRodney W. Grimes else 662df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 663df8bae1dSRodney W. Grimes break; 664df8bae1dSRodney W. Grimes } 665df8bae1dSRodney W. Grimes } 666df8bae1dSRodney W. Grimes if (error) 667df8bae1dSRodney W. Grimes break; 668df8bae1dSRodney W. Grimes 669df8bae1dSRodney W. Grimes entryoffsetinblock += reclen; 670df8bae1dSRodney W. Grimes } 671df8bae1dSRodney W. Grimes 672df8bae1dSRodney W. Grimes if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 673df8bae1dSRodney W. Grimes idp->current.d_namlen = 0; 674df8bae1dSRodney W. Grimes error = iso_shipdir(idp); 675df8bae1dSRodney W. Grimes } 676df8bae1dSRodney W. Grimes if (error < 0) 677df8bae1dSRodney W. Grimes error = 0; 678df8bae1dSRodney W. Grimes 6799abf4d6eSDoug Rabson if (ap->a_ncookies != NULL) { 6809abf4d6eSDoug Rabson if (error) 681996c772fSJohn Dyson free(cookies, M_TEMP); 6829abf4d6eSDoug Rabson else { 6839abf4d6eSDoug Rabson /* 6849abf4d6eSDoug Rabson * Work out the number of cookies actually used. 6859abf4d6eSDoug Rabson */ 6869abf4d6eSDoug Rabson *ap->a_ncookies = ncookies - idp->ncookies; 6879abf4d6eSDoug Rabson *ap->a_cookies = cookies; 6889abf4d6eSDoug Rabson } 6899abf4d6eSDoug Rabson } 6909abf4d6eSDoug Rabson 691df8bae1dSRodney W. Grimes if (bp) 692df8bae1dSRodney W. Grimes brelse (bp); 693df8bae1dSRodney W. Grimes 694df8bae1dSRodney W. Grimes uio->uio_offset = idp->uio_off; 695996c772fSJohn Dyson *ap->a_eofflag = idp->eofflag; 696df8bae1dSRodney W. Grimes 697df8bae1dSRodney W. Grimes FREE(idp, M_TEMP); 698df8bae1dSRodney W. Grimes 699df8bae1dSRodney W. Grimes return (error); 700df8bae1dSRodney W. Grimes } 701df8bae1dSRodney W. Grimes 702df8bae1dSRodney W. Grimes /* 703df8bae1dSRodney W. Grimes * Return target name of a symbolic link 704df8bae1dSRodney W. Grimes * Shouldn't we get the parent vnode and read the data from there? 705df8bae1dSRodney W. Grimes * This could eventually result in deadlocks in cd9660_lookup. 706df8bae1dSRodney W. Grimes * But otherwise the block read here is in the block buffer two times. 707df8bae1dSRodney W. Grimes */ 708df8bae1dSRodney W. Grimes typedef struct iso_directory_record ISODIR; 709df8bae1dSRodney W. Grimes typedef struct iso_node ISONODE; 710df8bae1dSRodney W. Grimes typedef struct iso_mnt ISOMNT; 711605e9724SPoul-Henning Kamp static int 712df8bae1dSRodney W. Grimes cd9660_readlink(ap) 713df8bae1dSRodney W. Grimes struct vop_readlink_args /* { 714df8bae1dSRodney W. Grimes struct vnode *a_vp; 715df8bae1dSRodney W. Grimes struct uio *a_uio; 716df8bae1dSRodney W. Grimes struct ucred *a_cred; 717df8bae1dSRodney W. Grimes } */ *ap; 718df8bae1dSRodney W. Grimes { 719df8bae1dSRodney W. Grimes ISONODE *ip; 720df8bae1dSRodney W. Grimes ISODIR *dirp; 721df8bae1dSRodney W. Grimes ISOMNT *imp; 722df8bae1dSRodney W. Grimes struct buf *bp; 723996c772fSJohn Dyson struct uio *uio; 724df8bae1dSRodney W. Grimes u_short symlen; 725df8bae1dSRodney W. Grimes int error; 726df8bae1dSRodney W. Grimes char *symname; 727df8bae1dSRodney W. Grimes 728df8bae1dSRodney W. Grimes ip = VTOI(ap->a_vp); 729df8bae1dSRodney W. Grimes imp = ip->i_mnt; 730996c772fSJohn Dyson uio = ap->a_uio; 731df8bae1dSRodney W. Grimes 732df8bae1dSRodney W. Grimes if (imp->iso_ftype != ISO_FTYPE_RRIP) 733996c772fSJohn Dyson return (EINVAL); 734df8bae1dSRodney W. Grimes 735df8bae1dSRodney W. Grimes /* 736df8bae1dSRodney W. Grimes * Get parents directory record block that this inode included. 737df8bae1dSRodney W. Grimes */ 738df8bae1dSRodney W. Grimes error = bread(imp->im_devvp, 739996c772fSJohn Dyson (ip->i_number >> imp->im_bshift) << 740996c772fSJohn Dyson (imp->im_bshift - DEV_BSHIFT), 741996c772fSJohn Dyson imp->logical_block_size, NOCRED, &bp); 742df8bae1dSRodney W. Grimes if (error) { 743df8bae1dSRodney W. Grimes brelse(bp); 744996c772fSJohn Dyson return (EINVAL); 745df8bae1dSRodney W. Grimes } 746df8bae1dSRodney W. Grimes 747df8bae1dSRodney W. Grimes /* 748df8bae1dSRodney W. Grimes * Setup the directory pointer for this inode 749df8bae1dSRodney W. Grimes */ 750996c772fSJohn Dyson dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask)); 751df8bae1dSRodney W. Grimes 752df8bae1dSRodney W. Grimes /* 753df8bae1dSRodney W. Grimes * Just make sure, we have a right one.... 754df8bae1dSRodney W. Grimes * 1: Check not cross boundary on block 755df8bae1dSRodney W. Grimes */ 756df8bae1dSRodney W. Grimes if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 75792579404SAlexander Langer > (unsigned)imp->logical_block_size) { 758df8bae1dSRodney W. Grimes brelse(bp); 759996c772fSJohn Dyson return (EINVAL); 760df8bae1dSRodney W. Grimes } 761df8bae1dSRodney W. Grimes 762df8bae1dSRodney W. Grimes /* 763df8bae1dSRodney W. Grimes * Now get a buffer 764df8bae1dSRodney W. Grimes * Abuse a namei buffer for now. 765df8bae1dSRodney W. Grimes */ 766996c772fSJohn Dyson if (uio->uio_segflg == UIO_SYSSPACE) 767996c772fSJohn Dyson symname = uio->uio_iov->iov_base; 768996c772fSJohn Dyson else 76999448ed1SJohn Dyson symname = zalloc(namei_zone); 770df8bae1dSRodney W. Grimes 771df8bae1dSRodney W. Grimes /* 772df8bae1dSRodney W. Grimes * Ok, we just gathering a symbolic name in SL record. 773df8bae1dSRodney W. Grimes */ 774df8bae1dSRodney W. Grimes if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) { 775996c772fSJohn Dyson if (uio->uio_segflg != UIO_SYSSPACE) 77699448ed1SJohn Dyson zfree(namei_zone, symname); 777df8bae1dSRodney W. Grimes brelse(bp); 778996c772fSJohn Dyson return (EINVAL); 779df8bae1dSRodney W. Grimes } 780df8bae1dSRodney W. Grimes /* 781df8bae1dSRodney W. Grimes * Don't forget before you leave from home ;-) 782df8bae1dSRodney W. Grimes */ 783df8bae1dSRodney W. Grimes brelse(bp); 784df8bae1dSRodney W. Grimes 785df8bae1dSRodney W. Grimes /* 786df8bae1dSRodney W. Grimes * return with the symbolic name to caller's. 787df8bae1dSRodney W. Grimes */ 788996c772fSJohn Dyson if (uio->uio_segflg != UIO_SYSSPACE) { 789996c772fSJohn Dyson error = uiomove(symname, symlen, uio); 79099448ed1SJohn Dyson zfree(namei_zone, symname); 791996c772fSJohn Dyson return (error); 792996c772fSJohn Dyson } 793996c772fSJohn Dyson uio->uio_resid -= symlen; 794996c772fSJohn Dyson uio->uio_iov->iov_base += symlen; 795996c772fSJohn Dyson uio->uio_iov->iov_len -= symlen; 796996c772fSJohn Dyson return (0); 797df8bae1dSRodney W. Grimes } 798df8bae1dSRodney W. Grimes 799df8bae1dSRodney W. Grimes /* 800df8bae1dSRodney W. Grimes * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 801df8bae1dSRodney W. Grimes * done. If a buffer has been saved in anticipation of a CREATE, delete it. 802df8bae1dSRodney W. Grimes */ 803605e9724SPoul-Henning Kamp static int 804df8bae1dSRodney W. Grimes cd9660_abortop(ap) 805df8bae1dSRodney W. Grimes struct vop_abortop_args /* { 806df8bae1dSRodney W. Grimes struct vnode *a_dvp; 807df8bae1dSRodney W. Grimes struct componentname *a_cnp; 808df8bae1dSRodney W. Grimes } */ *ap; 809df8bae1dSRodney W. Grimes { 810df8bae1dSRodney W. Grimes if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 81199448ed1SJohn Dyson zfree(namei_zone, ap->a_cnp->cn_pnbuf); 812996c772fSJohn Dyson return (0); 813df8bae1dSRodney W. Grimes } 814df8bae1dSRodney W. Grimes 815df8bae1dSRodney W. Grimes /* 816df8bae1dSRodney W. Grimes * Lock an inode. 817df8bae1dSRodney W. Grimes */ 818605e9724SPoul-Henning Kamp static int 819df8bae1dSRodney W. Grimes cd9660_lock(ap) 820df8bae1dSRodney W. Grimes struct vop_lock_args /* { 821df8bae1dSRodney W. Grimes struct vnode *a_vp; 822996c772fSJohn Dyson int a_flags; 823996c772fSJohn Dyson struct proc *a_p; 824df8bae1dSRodney W. Grimes } */ *ap; 825df8bae1dSRodney W. Grimes { 826996c772fSJohn Dyson struct vnode *vp = ap->a_vp; 827df8bae1dSRodney W. Grimes 828996c772fSJohn Dyson return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock, 829996c772fSJohn Dyson ap->a_p)); 830df8bae1dSRodney W. Grimes } 831df8bae1dSRodney W. Grimes 832df8bae1dSRodney W. Grimes /* 833df8bae1dSRodney W. Grimes * Unlock an inode. 834df8bae1dSRodney W. Grimes */ 835605e9724SPoul-Henning Kamp static int 836df8bae1dSRodney W. Grimes cd9660_unlock(ap) 837df8bae1dSRodney W. Grimes struct vop_unlock_args /* { 838df8bae1dSRodney W. Grimes struct vnode *a_vp; 839996c772fSJohn Dyson int a_flags; 840996c772fSJohn Dyson struct proc *a_p; 841df8bae1dSRodney W. Grimes } */ *ap; 842df8bae1dSRodney W. Grimes { 843996c772fSJohn Dyson struct vnode *vp = ap->a_vp; 844df8bae1dSRodney W. Grimes 845996c772fSJohn Dyson return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE, 846996c772fSJohn Dyson &vp->v_interlock, ap->a_p)); 847df8bae1dSRodney W. Grimes } 848df8bae1dSRodney W. Grimes 849df8bae1dSRodney W. Grimes /* 850df8bae1dSRodney W. Grimes * Calculate the logical to physical mapping if not done already, 851df8bae1dSRodney W. Grimes * then call the device strategy routine. 852df8bae1dSRodney W. Grimes */ 853605e9724SPoul-Henning Kamp static int 854df8bae1dSRodney W. Grimes cd9660_strategy(ap) 855df8bae1dSRodney W. Grimes struct vop_strategy_args /* { 856df8bae1dSRodney W. Grimes struct buf *a_bp; 857df8bae1dSRodney W. Grimes } */ *ap; 858df8bae1dSRodney W. Grimes { 859df8bae1dSRodney W. Grimes register struct buf *bp = ap->a_bp; 860df8bae1dSRodney W. Grimes register struct vnode *vp = bp->b_vp; 861df8bae1dSRodney W. Grimes register struct iso_node *ip; 862df8bae1dSRodney W. Grimes int error; 863df8bae1dSRodney W. Grimes 864df8bae1dSRodney W. Grimes ip = VTOI(vp); 865df8bae1dSRodney W. Grimes if (vp->v_type == VBLK || vp->v_type == VCHR) 866df8bae1dSRodney W. Grimes panic("cd9660_strategy: spec"); 867df8bae1dSRodney W. Grimes if (bp->b_blkno == bp->b_lblkno) { 8681295d82eSGary Palmer if ((error = 869c83ebe77SJohn Dyson VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL))) { 870df8bae1dSRodney W. Grimes bp->b_error = error; 871df8bae1dSRodney W. Grimes bp->b_flags |= B_ERROR; 872df8bae1dSRodney W. Grimes biodone(bp); 873df8bae1dSRodney W. Grimes return (error); 874df8bae1dSRodney W. Grimes } 875df8bae1dSRodney W. Grimes if ((long)bp->b_blkno == -1) 876df8bae1dSRodney W. Grimes clrbuf(bp); 877df8bae1dSRodney W. Grimes } 878df8bae1dSRodney W. Grimes if ((long)bp->b_blkno == -1) { 879df8bae1dSRodney W. Grimes biodone(bp); 880df8bae1dSRodney W. Grimes return (0); 881df8bae1dSRodney W. Grimes } 882df8bae1dSRodney W. Grimes vp = ip->i_devvp; 883df8bae1dSRodney W. Grimes bp->b_dev = vp->v_rdev; 884df8bae1dSRodney W. Grimes VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 885df8bae1dSRodney W. Grimes return (0); 886df8bae1dSRodney W. Grimes } 887df8bae1dSRodney W. Grimes 888df8bae1dSRodney W. Grimes /* 889df8bae1dSRodney W. Grimes * Print out the contents of an inode. 890df8bae1dSRodney W. Grimes */ 891605e9724SPoul-Henning Kamp static int 892df8bae1dSRodney W. Grimes cd9660_print(ap) 893df8bae1dSRodney W. Grimes struct vop_print_args /* { 894df8bae1dSRodney W. Grimes struct vnode *a_vp; 895df8bae1dSRodney W. Grimes } */ *ap; 896df8bae1dSRodney W. Grimes { 897996c772fSJohn Dyson 898df8bae1dSRodney W. Grimes printf("tag VT_ISOFS, isofs vnode\n"); 899996c772fSJohn Dyson return (0); 900df8bae1dSRodney W. Grimes } 901df8bae1dSRodney W. Grimes 902df8bae1dSRodney W. Grimes /* 903996c772fSJohn Dyson * Check for a locked inode. 904df8bae1dSRodney W. Grimes */ 905996c772fSJohn Dyson int 906996c772fSJohn Dyson cd9660_islocked(ap) 907996c772fSJohn Dyson struct vop_islocked_args /* { 908996c772fSJohn Dyson struct vnode *a_vp; 909996c772fSJohn Dyson } */ *ap; 910df8bae1dSRodney W. Grimes { 911df8bae1dSRodney W. Grimes 912996c772fSJohn Dyson return (lockstatus(&VTOI(ap->a_vp)->i_lock)); 913996c772fSJohn Dyson } 914996c772fSJohn Dyson 915996c772fSJohn Dyson /* 916996c772fSJohn Dyson * Return POSIX pathconf information applicable to cd9660 filesystems. 917996c772fSJohn Dyson */ 918996c772fSJohn Dyson int 919996c772fSJohn Dyson cd9660_pathconf(ap) 920996c772fSJohn Dyson struct vop_pathconf_args /* { 921996c772fSJohn Dyson struct vnode *a_vp; 922996c772fSJohn Dyson int a_name; 923996c772fSJohn Dyson register_t *a_retval; 924996c772fSJohn Dyson } */ *ap; 925996c772fSJohn Dyson { 926996c772fSJohn Dyson 927996c772fSJohn Dyson switch (ap->a_name) { 928996c772fSJohn Dyson case _PC_LINK_MAX: 929996c772fSJohn Dyson *ap->a_retval = 1; 930996c772fSJohn Dyson return (0); 931996c772fSJohn Dyson case _PC_NAME_MAX: 932996c772fSJohn Dyson if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP) 933996c772fSJohn Dyson *ap->a_retval = NAME_MAX; 934996c772fSJohn Dyson else 935996c772fSJohn Dyson *ap->a_retval = 37; 936996c772fSJohn Dyson return (0); 937996c772fSJohn Dyson case _PC_PATH_MAX: 938996c772fSJohn Dyson *ap->a_retval = PATH_MAX; 939996c772fSJohn Dyson return (0); 940996c772fSJohn Dyson case _PC_PIPE_BUF: 941996c772fSJohn Dyson *ap->a_retval = PIPE_BUF; 942996c772fSJohn Dyson return (0); 943996c772fSJohn Dyson case _PC_CHOWN_RESTRICTED: 944996c772fSJohn Dyson *ap->a_retval = 1; 945996c772fSJohn Dyson return (0); 946996c772fSJohn Dyson case _PC_NO_TRUNC: 947996c772fSJohn Dyson *ap->a_retval = 1; 948996c772fSJohn Dyson return (0); 949996c772fSJohn Dyson default: 950996c772fSJohn Dyson return (EINVAL); 951996c772fSJohn Dyson } 952996c772fSJohn Dyson /* NOTREACHED */ 953df8bae1dSRodney W. Grimes } 954df8bae1dSRodney W. Grimes 955df8bae1dSRodney W. Grimes /* 956df8bae1dSRodney W. Grimes * Global vfs data structures for isofs 957df8bae1dSRodney W. Grimes */ 958df8bae1dSRodney W. Grimes #define cd9660_create \ 959996c772fSJohn Dyson ((int (*) __P((struct vop_create_args *)))eopnotsupp) 960996c772fSJohn Dyson #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))eopnotsupp) 961996c772fSJohn Dyson #define cd9660_write ((int (*) __P((struct vop_write_args *)))eopnotsupp) 962996c772fSJohn Dyson #ifdef NFS 963996c772fSJohn Dyson #define cd9660_lease_check lease_check 964996c772fSJohn Dyson #else 965996c772fSJohn Dyson #define cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop) 966996c772fSJohn Dyson #endif 967a6aeade2SPeter Wemm #define cd9660_poll vop_nopoll 968df8bae1dSRodney W. Grimes #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 969df8bae1dSRodney W. Grimes #define cd9660_remove \ 970996c772fSJohn Dyson ((int (*) __P((struct vop_remove_args *)))eopnotsupp) 971996c772fSJohn Dyson #define cd9660_link ((int (*) __P((struct vop_link_args *)))eopnotsupp) 972df8bae1dSRodney W. Grimes #define cd9660_rename \ 973996c772fSJohn Dyson ((int (*) __P((struct vop_rename_args *)))eopnotsupp) 974996c772fSJohn Dyson #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))eopnotsupp) 975996c772fSJohn Dyson #define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))eopnotsupp) 976df8bae1dSRodney W. Grimes #define cd9660_symlink \ 977996c772fSJohn Dyson ((int (*) __P((struct vop_symlink_args *)))eopnotsupp) 978df8bae1dSRodney W. Grimes #define cd9660_advlock \ 979996c772fSJohn Dyson ((int (*) __P((struct vop_advlock_args *)))eopnotsupp) 980df8bae1dSRodney W. Grimes #define cd9660_valloc ((int(*) __P(( \ 981df8bae1dSRodney W. Grimes struct vnode *pvp, \ 982df8bae1dSRodney W. Grimes int mode, \ 983df8bae1dSRodney W. Grimes struct ucred *cred, \ 984996c772fSJohn Dyson struct vnode **vpp))) eopnotsupp) 985996c772fSJohn Dyson #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))eopnotsupp) 986df8bae1dSRodney W. Grimes #define cd9660_truncate \ 987996c772fSJohn Dyson ((int (*) __P((struct vop_truncate_args *)))eopnotsupp) 988df8bae1dSRodney W. Grimes #define cd9660_update \ 989996c772fSJohn Dyson ((int (*) __P((struct vop_update_args *)))eopnotsupp) 990df8bae1dSRodney W. Grimes #define cd9660_bwrite \ 991996c772fSJohn Dyson ((int (*) __P((struct vop_bwrite_args *)))eopnotsupp) 992df8bae1dSRodney W. Grimes 993df8bae1dSRodney W. Grimes /* 994996c772fSJohn Dyson * Global vfs data structures for cd9660 995df8bae1dSRodney W. Grimes */ 996f57e6547SBruce Evans vop_t **cd9660_vnodeop_p; 997996c772fSJohn Dyson struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { 998f57e6547SBruce Evans { &vop_default_desc, (vop_t *) vn_default_error }, 999539ef70cSPoul-Henning Kamp { &vop_abortop_desc, (vop_t *) cd9660_abortop }, 1000539ef70cSPoul-Henning Kamp { &vop_access_desc, (vop_t *) cd9660_access }, 1001539ef70cSPoul-Henning Kamp { &vop_advlock_desc, (vop_t *) cd9660_advlock }, 1002539ef70cSPoul-Henning Kamp { &vop_blkatoff_desc, (vop_t *) cd9660_blkatoff }, 1003539ef70cSPoul-Henning Kamp { &vop_bmap_desc, (vop_t *) cd9660_bmap }, 1004996c772fSJohn Dyson { &vop_bwrite_desc, (vop_t *) vn_bwrite }, 1005539ef70cSPoul-Henning Kamp { &vop_cachedlookup_desc, (vop_t *) cd9660_lookup }, 1006539ef70cSPoul-Henning Kamp { &vop_close_desc, (vop_t *) cd9660_close }, 1007539ef70cSPoul-Henning Kamp { &vop_create_desc, (vop_t *) cd9660_create }, 1008539ef70cSPoul-Henning Kamp { &vop_fsync_desc, (vop_t *) cd9660_fsync }, 1009539ef70cSPoul-Henning Kamp { &vop_getattr_desc, (vop_t *) cd9660_getattr }, 1010539ef70cSPoul-Henning Kamp { &vop_inactive_desc, (vop_t *) cd9660_inactive }, 1011539ef70cSPoul-Henning Kamp { &vop_ioctl_desc, (vop_t *) cd9660_ioctl }, 1012539ef70cSPoul-Henning Kamp { &vop_islocked_desc, (vop_t *) cd9660_islocked }, 1013539ef70cSPoul-Henning Kamp { &vop_lease_desc, (vop_t *) cd9660_lease_check }, 1014539ef70cSPoul-Henning Kamp { &vop_link_desc, (vop_t *) cd9660_link }, 1015539ef70cSPoul-Henning Kamp { &vop_lock_desc, (vop_t *) cd9660_lock }, 1016539ef70cSPoul-Henning Kamp { &vop_lookup_desc, (vop_t *) vfs_cache_lookup }, 1017539ef70cSPoul-Henning Kamp { &vop_mkdir_desc, (vop_t *) cd9660_mkdir }, 1018539ef70cSPoul-Henning Kamp { &vop_mknod_desc, (vop_t *) cd9660_mknod }, 1019539ef70cSPoul-Henning Kamp { &vop_mmap_desc, (vop_t *) cd9660_mmap }, 1020539ef70cSPoul-Henning Kamp { &vop_open_desc, (vop_t *) cd9660_open }, 1021539ef70cSPoul-Henning Kamp { &vop_pathconf_desc, (vop_t *) cd9660_pathconf }, 1022539ef70cSPoul-Henning Kamp { &vop_poll_desc, (vop_t *) cd9660_poll }, 1023539ef70cSPoul-Henning Kamp { &vop_print_desc, (vop_t *) cd9660_print }, 1024539ef70cSPoul-Henning Kamp { &vop_read_desc, (vop_t *) cd9660_read }, 1025539ef70cSPoul-Henning Kamp { &vop_readdir_desc, (vop_t *) cd9660_readdir }, 1026539ef70cSPoul-Henning Kamp { &vop_readlink_desc, (vop_t *) cd9660_readlink }, 1027539ef70cSPoul-Henning Kamp { &vop_reclaim_desc, (vop_t *) cd9660_reclaim }, 1028539ef70cSPoul-Henning Kamp { &vop_remove_desc, (vop_t *) cd9660_remove }, 1029539ef70cSPoul-Henning Kamp { &vop_rename_desc, (vop_t *) cd9660_rename }, 1030539ef70cSPoul-Henning Kamp { &vop_revoke_desc, (vop_t *) cd9660_revoke }, 1031539ef70cSPoul-Henning Kamp { &vop_rmdir_desc, (vop_t *) cd9660_rmdir }, 1032539ef70cSPoul-Henning Kamp { &vop_seek_desc, (vop_t *) cd9660_seek }, 1033539ef70cSPoul-Henning Kamp { &vop_setattr_desc, (vop_t *) cd9660_setattr }, 1034539ef70cSPoul-Henning Kamp { &vop_strategy_desc, (vop_t *) cd9660_strategy }, 1035539ef70cSPoul-Henning Kamp { &vop_symlink_desc, (vop_t *) cd9660_symlink }, 1036539ef70cSPoul-Henning Kamp { &vop_truncate_desc, (vop_t *) cd9660_truncate }, 1037539ef70cSPoul-Henning Kamp { &vop_unlock_desc, (vop_t *) cd9660_unlock }, 1038539ef70cSPoul-Henning Kamp { &vop_update_desc, (vop_t *) cd9660_update }, 1039539ef70cSPoul-Henning Kamp { &vop_valloc_desc, (vop_t *) cd9660_valloc }, 1040539ef70cSPoul-Henning Kamp { &vop_vfree_desc, (vop_t *) cd9660_vfree }, 1041539ef70cSPoul-Henning Kamp { &vop_write_desc, (vop_t *) cd9660_write }, 1042f57e6547SBruce Evans { NULL, NULL } 1043df8bae1dSRodney W. Grimes }; 1044605e9724SPoul-Henning Kamp static struct vnodeopv_desc cd9660_vnodeop_opv_desc = 1045df8bae1dSRodney W. Grimes { &cd9660_vnodeop_p, cd9660_vnodeop_entries }; 1046c901836cSGarrett Wollman VNODEOP_SET(cd9660_vnodeop_opv_desc); 1047df8bae1dSRodney W. Grimes 1048df8bae1dSRodney W. Grimes /* 1049df8bae1dSRodney W. Grimes * Special device vnode ops 1050df8bae1dSRodney W. Grimes */ 1051f57e6547SBruce Evans vop_t **cd9660_specop_p; 1052996c772fSJohn Dyson struct vnodeopv_entry_desc cd9660_specop_entries[] = { 1053f57e6547SBruce Evans { &vop_default_desc, (vop_t *) vn_default_error }, 1054539ef70cSPoul-Henning Kamp { &vop_abortop_desc, (vop_t *) spec_abortop }, 1055539ef70cSPoul-Henning Kamp { &vop_access_desc, (vop_t *) cd9660_access }, 1056539ef70cSPoul-Henning Kamp { &vop_advlock_desc, (vop_t *) spec_advlock }, 1057539ef70cSPoul-Henning Kamp { &vop_blkatoff_desc, (vop_t *) spec_blkatoff }, 1058539ef70cSPoul-Henning Kamp { &vop_bmap_desc, (vop_t *) spec_bmap }, 1059996c772fSJohn Dyson { &vop_bwrite_desc, (vop_t *) vn_bwrite }, 1060539ef70cSPoul-Henning Kamp { &vop_close_desc, (vop_t *) spec_close }, 1061539ef70cSPoul-Henning Kamp { &vop_create_desc, (vop_t *) spec_create }, 1062539ef70cSPoul-Henning Kamp { &vop_fsync_desc, (vop_t *) spec_fsync }, 1063539ef70cSPoul-Henning Kamp { &vop_getattr_desc, (vop_t *) cd9660_getattr }, 1064539ef70cSPoul-Henning Kamp { &vop_inactive_desc, (vop_t *) cd9660_inactive }, 1065539ef70cSPoul-Henning Kamp { &vop_ioctl_desc, (vop_t *) spec_ioctl }, 1066539ef70cSPoul-Henning Kamp { &vop_islocked_desc, (vop_t *) cd9660_islocked }, 1067539ef70cSPoul-Henning Kamp { &vop_lease_desc, (vop_t *) spec_lease_check }, 1068539ef70cSPoul-Henning Kamp { &vop_link_desc, (vop_t *) spec_link }, 1069539ef70cSPoul-Henning Kamp { &vop_lock_desc, (vop_t *) cd9660_lock }, 1070539ef70cSPoul-Henning Kamp { &vop_lookup_desc, (vop_t *) spec_lookup }, 1071539ef70cSPoul-Henning Kamp { &vop_mkdir_desc, (vop_t *) spec_mkdir }, 1072539ef70cSPoul-Henning Kamp { &vop_mknod_desc, (vop_t *) spec_mknod }, 1073539ef70cSPoul-Henning Kamp { &vop_mmap_desc, (vop_t *) spec_mmap }, 1074539ef70cSPoul-Henning Kamp { &vop_open_desc, (vop_t *) spec_open }, 1075539ef70cSPoul-Henning Kamp { &vop_pathconf_desc, (vop_t *) spec_pathconf }, 1076539ef70cSPoul-Henning Kamp { &vop_poll_desc, (vop_t *) spec_poll }, 1077539ef70cSPoul-Henning Kamp { &vop_print_desc, (vop_t *) cd9660_print }, 1078539ef70cSPoul-Henning Kamp { &vop_read_desc, (vop_t *) spec_read }, 1079539ef70cSPoul-Henning Kamp { &vop_readdir_desc, (vop_t *) spec_readdir }, 1080539ef70cSPoul-Henning Kamp { &vop_readlink_desc, (vop_t *) spec_readlink }, 1081539ef70cSPoul-Henning Kamp { &vop_reclaim_desc, (vop_t *) cd9660_reclaim }, 1082539ef70cSPoul-Henning Kamp { &vop_remove_desc, (vop_t *) spec_remove }, 1083539ef70cSPoul-Henning Kamp { &vop_rename_desc, (vop_t *) spec_rename }, 1084539ef70cSPoul-Henning Kamp { &vop_revoke_desc, (vop_t *) spec_revoke }, 1085539ef70cSPoul-Henning Kamp { &vop_rmdir_desc, (vop_t *) spec_rmdir }, 1086539ef70cSPoul-Henning Kamp { &vop_seek_desc, (vop_t *) spec_seek }, 1087539ef70cSPoul-Henning Kamp { &vop_setattr_desc, (vop_t *) cd9660_setattr }, 1088539ef70cSPoul-Henning Kamp { &vop_strategy_desc, (vop_t *) spec_strategy }, 1089539ef70cSPoul-Henning Kamp { &vop_symlink_desc, (vop_t *) spec_symlink }, 1090539ef70cSPoul-Henning Kamp { &vop_truncate_desc, (vop_t *) spec_truncate }, 1091539ef70cSPoul-Henning Kamp { &vop_unlock_desc, (vop_t *) cd9660_unlock }, 1092539ef70cSPoul-Henning Kamp { &vop_update_desc, (vop_t *) cd9660_update }, 1093539ef70cSPoul-Henning Kamp { &vop_valloc_desc, (vop_t *) spec_valloc }, 1094539ef70cSPoul-Henning Kamp { &vop_vfree_desc, (vop_t *) spec_vfree }, 1095539ef70cSPoul-Henning Kamp { &vop_write_desc, (vop_t *) spec_write }, 1096f57e6547SBruce Evans { NULL, NULL } 1097df8bae1dSRodney W. Grimes }; 1098605e9724SPoul-Henning Kamp static struct vnodeopv_desc cd9660_specop_opv_desc = 1099df8bae1dSRodney W. Grimes { &cd9660_specop_p, cd9660_specop_entries }; 1100c901836cSGarrett Wollman VNODEOP_SET(cd9660_specop_opv_desc); 1101df8bae1dSRodney W. Grimes 1102f57e6547SBruce Evans vop_t **cd9660_fifoop_p; 1103996c772fSJohn Dyson struct vnodeopv_entry_desc cd9660_fifoop_entries[] = { 1104f57e6547SBruce Evans { &vop_default_desc, (vop_t *) vn_default_error }, 1105539ef70cSPoul-Henning Kamp { &vop_abortop_desc, (vop_t *) fifo_abortop }, 1106539ef70cSPoul-Henning Kamp { &vop_access_desc, (vop_t *) cd9660_access }, 1107539ef70cSPoul-Henning Kamp { &vop_advlock_desc, (vop_t *) fifo_advlock }, 1108539ef70cSPoul-Henning Kamp { &vop_blkatoff_desc, (vop_t *) fifo_blkatoff }, 1109539ef70cSPoul-Henning Kamp { &vop_bmap_desc, (vop_t *) fifo_bmap }, 1110996c772fSJohn Dyson { &vop_bwrite_desc, (vop_t *) vn_bwrite }, 1111539ef70cSPoul-Henning Kamp { &vop_close_desc, (vop_t *) fifo_close }, 1112539ef70cSPoul-Henning Kamp { &vop_create_desc, (vop_t *) fifo_create }, 1113539ef70cSPoul-Henning Kamp { &vop_fsync_desc, (vop_t *) fifo_fsync }, 1114539ef70cSPoul-Henning Kamp { &vop_getattr_desc, (vop_t *) cd9660_getattr }, 1115539ef70cSPoul-Henning Kamp { &vop_inactive_desc, (vop_t *) cd9660_inactive }, 1116539ef70cSPoul-Henning Kamp { &vop_ioctl_desc, (vop_t *) fifo_ioctl }, 1117539ef70cSPoul-Henning Kamp { &vop_islocked_desc, (vop_t *) cd9660_islocked }, 1118539ef70cSPoul-Henning Kamp { &vop_lease_desc, (vop_t *) fifo_lease_check }, 1119539ef70cSPoul-Henning Kamp { &vop_link_desc, (vop_t *) fifo_link }, 1120539ef70cSPoul-Henning Kamp { &vop_lock_desc, (vop_t *) cd9660_lock }, 1121539ef70cSPoul-Henning Kamp { &vop_lookup_desc, (vop_t *) fifo_lookup }, 1122539ef70cSPoul-Henning Kamp { &vop_mkdir_desc, (vop_t *) fifo_mkdir }, 1123539ef70cSPoul-Henning Kamp { &vop_mknod_desc, (vop_t *) fifo_mknod }, 1124539ef70cSPoul-Henning Kamp { &vop_mmap_desc, (vop_t *) fifo_mmap }, 1125539ef70cSPoul-Henning Kamp { &vop_open_desc, (vop_t *) fifo_open }, 1126539ef70cSPoul-Henning Kamp { &vop_pathconf_desc, (vop_t *) fifo_pathconf }, 1127539ef70cSPoul-Henning Kamp { &vop_poll_desc, (vop_t *) fifo_poll }, 1128539ef70cSPoul-Henning Kamp { &vop_print_desc, (vop_t *) cd9660_print }, 1129539ef70cSPoul-Henning Kamp { &vop_read_desc, (vop_t *) fifo_read }, 1130539ef70cSPoul-Henning Kamp { &vop_readdir_desc, (vop_t *) fifo_readdir }, 1131539ef70cSPoul-Henning Kamp { &vop_readlink_desc, (vop_t *) fifo_readlink }, 1132539ef70cSPoul-Henning Kamp { &vop_reclaim_desc, (vop_t *) cd9660_reclaim }, 1133539ef70cSPoul-Henning Kamp { &vop_remove_desc, (vop_t *) fifo_remove }, 1134539ef70cSPoul-Henning Kamp { &vop_rename_desc, (vop_t *) fifo_rename }, 1135539ef70cSPoul-Henning Kamp { &vop_revoke_desc, (vop_t *) fifo_revoke }, 1136539ef70cSPoul-Henning Kamp { &vop_rmdir_desc, (vop_t *) fifo_rmdir }, 1137539ef70cSPoul-Henning Kamp { &vop_seek_desc, (vop_t *) fifo_seek }, 1138539ef70cSPoul-Henning Kamp { &vop_setattr_desc, (vop_t *) cd9660_setattr }, 1139539ef70cSPoul-Henning Kamp { &vop_strategy_desc, (vop_t *) fifo_strategy }, 1140539ef70cSPoul-Henning Kamp { &vop_symlink_desc, (vop_t *) fifo_symlink }, 1141539ef70cSPoul-Henning Kamp { &vop_truncate_desc, (vop_t *) fifo_truncate }, 1142539ef70cSPoul-Henning Kamp { &vop_unlock_desc, (vop_t *) cd9660_unlock }, 1143539ef70cSPoul-Henning Kamp { &vop_update_desc, (vop_t *) cd9660_update }, 1144539ef70cSPoul-Henning Kamp { &vop_valloc_desc, (vop_t *) fifo_valloc }, 1145539ef70cSPoul-Henning Kamp { &vop_vfree_desc, (vop_t *) fifo_vfree }, 1146539ef70cSPoul-Henning Kamp { &vop_write_desc, (vop_t *) fifo_write }, 1147f57e6547SBruce Evans { NULL, NULL } 1148df8bae1dSRodney W. Grimes }; 1149605e9724SPoul-Henning Kamp static struct vnodeopv_desc cd9660_fifoop_opv_desc = 1150df8bae1dSRodney W. Grimes { &cd9660_fifoop_p, cd9660_fifoop_entries }; 1151c901836cSGarrett Wollman 1152c901836cSGarrett Wollman VNODEOP_SET(cd9660_fifoop_opv_desc); 1153