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 399d322006SKATO Takenori * $Id: cd9660_vnops.c,v 1.35 1997/04/15 08:05:08 bde 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_select __P((struct vop_select_args *)); 69605e9724SPoul-Henning Kamp static int cd9660_mmap __P((struct vop_mmap_args *)); 70605e9724SPoul-Henning Kamp static int cd9660_seek __P((struct vop_seek_args *)); 7110dd32cdSBruce Evans struct isoreaddir; 7210dd32cdSBruce Evans static int iso_uiodir __P((struct isoreaddir *idp, struct dirent *dp, 7310dd32cdSBruce Evans off_t off)); 7410dd32cdSBruce Evans static int iso_shipdir __P((struct isoreaddir *idp)); 75605e9724SPoul-Henning Kamp static int cd9660_readdir __P((struct vop_readdir_args *)); 7610dd32cdSBruce Evans static int cd9660_readlink __P((struct vop_readlink_args *ap)); 77605e9724SPoul-Henning Kamp static int cd9660_abortop __P((struct vop_abortop_args *)); 78605e9724SPoul-Henning Kamp static int cd9660_lock __P((struct vop_lock_args *)); 79605e9724SPoul-Henning Kamp static int cd9660_unlock __P((struct vop_unlock_args *)); 80605e9724SPoul-Henning Kamp static int cd9660_strategy __P((struct vop_strategy_args *)); 81605e9724SPoul-Henning Kamp static int cd9660_print __P((struct vop_print_args *)); 82605e9724SPoul-Henning Kamp static int cd9660_islocked __P((struct vop_islocked_args *)); 8310dd32cdSBruce Evans 84df8bae1dSRodney W. Grimes /* 859d322006SKATO Takenori * Sysctl values for the cd9660 filesystem. 869d322006SKATO Takenori */ 879d322006SKATO Takenori #define CD9660_CLUSTERREAD 1 /* cluster reading enabled */ 889d322006SKATO Takenori #define CD9660_MAXID 2 /* number of valid cd9660 ids */ 899d322006SKATO Takenori 909d322006SKATO Takenori #define CD9660_NAMES { \ 919d322006SKATO Takenori {0, 0}, \ 929d322006SKATO Takenori { "doclusterread", CTLTYPE_INT}, \ 939d322006SKATO Takenori } 949d322006SKATO Takenori 959d322006SKATO Takenori /* 96de8583ceSDavid Greenman * Setattr call. Only allowed for block and character special devices. 97de8583ceSDavid Greenman */ 98996c772fSJohn Dyson int 99de8583ceSDavid Greenman cd9660_setattr(ap) 100de8583ceSDavid Greenman struct vop_setattr_args /* { 101de8583ceSDavid Greenman struct vnodeop_desc *a_desc; 102de8583ceSDavid Greenman struct vnode *a_vp; 103de8583ceSDavid Greenman struct vattr *a_vap; 104de8583ceSDavid Greenman struct ucred *a_cred; 105de8583ceSDavid Greenman struct proc *a_p; 106de8583ceSDavid Greenman } */ *ap; 107de8583ceSDavid Greenman { 108de8583ceSDavid Greenman struct vnode *vp = ap->a_vp; 109de8583ceSDavid Greenman struct vattr *vap = ap->a_vap; 110de8583ceSDavid Greenman 11192579404SAlexander Langer if (vap->va_flags != (u_long)VNOVAL || vap->va_uid != (uid_t)VNOVAL || 11295a1574eSNate Williams vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 11395a1574eSNate Williams vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) 114de8583ceSDavid Greenman return (EROFS); 11592579404SAlexander Langer if (vap->va_size != (u_quad_t)VNOVAL) { 116de8583ceSDavid Greenman switch (vp->v_type) { 117de8583ceSDavid Greenman case VDIR: 118de8583ceSDavid Greenman return (EISDIR); 119de8583ceSDavid Greenman case VLNK: 120de8583ceSDavid Greenman case VREG: 121de8583ceSDavid Greenman return (EROFS); 122de8583ceSDavid Greenman case VCHR: 123de8583ceSDavid Greenman case VBLK: 124de8583ceSDavid Greenman case VSOCK: 125de8583ceSDavid Greenman case VFIFO: 126de8583ceSDavid Greenman return (0); 127de8583ceSDavid Greenman } 128de8583ceSDavid Greenman } 129996c772fSJohn Dyson return (0); 130de8583ceSDavid Greenman } 131de8583ceSDavid Greenman 132de8583ceSDavid Greenman /* 133df8bae1dSRodney W. Grimes * Open called. 134df8bae1dSRodney W. Grimes * 135df8bae1dSRodney W. Grimes * Nothing to do. 136df8bae1dSRodney W. Grimes */ 137df8bae1dSRodney W. Grimes /* ARGSUSED */ 138605e9724SPoul-Henning Kamp static int 139df8bae1dSRodney W. Grimes cd9660_open(ap) 140df8bae1dSRodney W. Grimes struct vop_open_args /* { 141df8bae1dSRodney W. Grimes struct vnode *a_vp; 142df8bae1dSRodney W. Grimes int a_mode; 143df8bae1dSRodney W. Grimes struct ucred *a_cred; 144df8bae1dSRodney W. Grimes struct proc *a_p; 145df8bae1dSRodney W. Grimes } */ *ap; 146df8bae1dSRodney W. Grimes { 147df8bae1dSRodney W. Grimes return (0); 148df8bae1dSRodney W. Grimes } 149df8bae1dSRodney W. Grimes 150df8bae1dSRodney W. Grimes /* 151df8bae1dSRodney W. Grimes * Close called 152df8bae1dSRodney W. Grimes * 153df8bae1dSRodney W. Grimes * Update the times on the inode on writeable file systems. 154df8bae1dSRodney W. Grimes */ 155df8bae1dSRodney W. Grimes /* ARGSUSED */ 156605e9724SPoul-Henning Kamp static int 157df8bae1dSRodney W. Grimes cd9660_close(ap) 158df8bae1dSRodney W. Grimes struct vop_close_args /* { 159df8bae1dSRodney W. Grimes struct vnode *a_vp; 160df8bae1dSRodney W. Grimes int a_fflag; 161df8bae1dSRodney W. Grimes struct ucred *a_cred; 162df8bae1dSRodney W. Grimes struct proc *a_p; 163df8bae1dSRodney W. Grimes } */ *ap; 164df8bae1dSRodney W. Grimes { 165df8bae1dSRodney W. Grimes return (0); 166df8bae1dSRodney W. Grimes } 167df8bae1dSRodney W. Grimes 168df8bae1dSRodney W. Grimes /* 169df8bae1dSRodney W. Grimes * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 170df8bae1dSRodney W. Grimes * The mode is shifted to select the owner/group/other fields. The 171df8bae1dSRodney W. Grimes * super user is granted all permissions. 172df8bae1dSRodney W. Grimes */ 173df8bae1dSRodney W. Grimes /* ARGSUSED */ 174605e9724SPoul-Henning Kamp static int 175df8bae1dSRodney W. Grimes cd9660_access(ap) 176df8bae1dSRodney W. Grimes struct vop_access_args /* { 177df8bae1dSRodney W. Grimes struct vnode *a_vp; 178df8bae1dSRodney W. Grimes int a_mode; 179df8bae1dSRodney W. Grimes struct ucred *a_cred; 180df8bae1dSRodney W. Grimes struct proc *a_p; 181df8bae1dSRodney W. Grimes } */ *ap; 182df8bae1dSRodney W. Grimes { 183996c772fSJohn Dyson struct vnode *vp = ap->a_vp; 184996c772fSJohn Dyson struct iso_node *ip = VTOI(vp); 185996c772fSJohn Dyson struct ucred *cred = ap->a_cred; 186996c772fSJohn Dyson mode_t mask, mode = ap->a_mode; 187996c772fSJohn Dyson gid_t *gp; 188996c772fSJohn Dyson int i; 189996c772fSJohn Dyson 190ba14c327SDavid Greenman /* 191996c772fSJohn Dyson * Disallow write attempts unless the file is a socket, 192996c772fSJohn Dyson * fifo, or a block or character device resident on the 193996c772fSJohn Dyson * file system. 194ba14c327SDavid Greenman */ 195996c772fSJohn Dyson if (mode & VWRITE) { 196996c772fSJohn Dyson switch (vp->v_type) { 197ba14c327SDavid Greenman case VDIR: 198ba14c327SDavid Greenman case VLNK: 199ba14c327SDavid Greenman case VREG: 200ba14c327SDavid Greenman return (EROFS); 201ba14c327SDavid Greenman } 202ba14c327SDavid Greenman } 203ba14c327SDavid Greenman 204996c772fSJohn Dyson /* User id 0 always gets access. */ 205996c772fSJohn Dyson if (cred->cr_uid == 0) 206df8bae1dSRodney W. Grimes return (0); 207996c772fSJohn Dyson 208996c772fSJohn Dyson mask = 0; 209996c772fSJohn Dyson 210996c772fSJohn Dyson /* Otherwise, check the owner. */ 211996c772fSJohn Dyson if (cred->cr_uid == ip->inode.iso_uid) { 212996c772fSJohn Dyson if (mode & VEXEC) 213996c772fSJohn Dyson mask |= S_IXUSR; 214996c772fSJohn Dyson if (mode & VREAD) 215996c772fSJohn Dyson mask |= S_IRUSR; 216996c772fSJohn Dyson if (mode & VWRITE) 217996c772fSJohn Dyson mask |= S_IWUSR; 218996c772fSJohn Dyson return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); 219996c772fSJohn Dyson } 220996c772fSJohn Dyson 221996c772fSJohn Dyson /* Otherwise, check the groups. */ 222996c772fSJohn Dyson for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) 223996c772fSJohn Dyson if (ip->inode.iso_gid == *gp) { 224996c772fSJohn Dyson if (mode & VEXEC) 225996c772fSJohn Dyson mask |= S_IXGRP; 226996c772fSJohn Dyson if (mode & VREAD) 227996c772fSJohn Dyson mask |= S_IRGRP; 228996c772fSJohn Dyson if (mode & VWRITE) 229996c772fSJohn Dyson mask |= S_IWGRP; 230996c772fSJohn Dyson return ((ip->inode.iso_mode & mask) == mask ? 231996c772fSJohn Dyson 0 : EACCES); 232996c772fSJohn Dyson } 233996c772fSJohn Dyson 234996c772fSJohn Dyson /* Otherwise, check everyone else. */ 235996c772fSJohn Dyson if (mode & VEXEC) 236996c772fSJohn Dyson mask |= S_IXOTH; 237996c772fSJohn Dyson if (mode & VREAD) 238996c772fSJohn Dyson mask |= S_IROTH; 239996c772fSJohn Dyson if (mode & VWRITE) 240996c772fSJohn Dyson mask |= S_IWOTH; 241996c772fSJohn Dyson return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); 242df8bae1dSRodney W. Grimes } 243df8bae1dSRodney W. Grimes 244605e9724SPoul-Henning Kamp static int 245df8bae1dSRodney W. Grimes cd9660_getattr(ap) 246df8bae1dSRodney W. Grimes struct vop_getattr_args /* { 247df8bae1dSRodney W. Grimes struct vnode *a_vp; 248df8bae1dSRodney W. Grimes struct vattr *a_vap; 249df8bae1dSRodney W. Grimes struct ucred *a_cred; 250df8bae1dSRodney W. Grimes struct proc *a_p; 251df8bae1dSRodney W. Grimes } */ *ap; 252df8bae1dSRodney W. Grimes 253df8bae1dSRodney W. Grimes { 254df8bae1dSRodney W. Grimes struct vnode *vp = ap->a_vp; 255df8bae1dSRodney W. Grimes register struct vattr *vap = ap->a_vap; 256df8bae1dSRodney W. Grimes register struct iso_node *ip = VTOI(vp); 257df8bae1dSRodney W. Grimes 258df8bae1dSRodney W. Grimes vap->va_fsid = ip->i_dev; 259df8bae1dSRodney W. Grimes vap->va_fileid = ip->i_number; 260df8bae1dSRodney W. Grimes 261df8bae1dSRodney W. Grimes vap->va_mode = ip->inode.iso_mode; 262df8bae1dSRodney W. Grimes vap->va_nlink = ip->inode.iso_links; 263df8bae1dSRodney W. Grimes vap->va_uid = ip->inode.iso_uid; 264df8bae1dSRodney W. Grimes vap->va_gid = ip->inode.iso_gid; 265df8bae1dSRodney W. Grimes vap->va_atime = ip->inode.iso_atime; 266df8bae1dSRodney W. Grimes vap->va_mtime = ip->inode.iso_mtime; 267df8bae1dSRodney W. Grimes vap->va_ctime = ip->inode.iso_ctime; 268df8bae1dSRodney W. Grimes vap->va_rdev = ip->inode.iso_rdev; 269df8bae1dSRodney W. Grimes 270df8bae1dSRodney W. Grimes vap->va_size = (u_quad_t) ip->i_size; 271996c772fSJohn Dyson if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) { 272996c772fSJohn Dyson struct vop_readlink_args rdlnk; 273996c772fSJohn Dyson struct iovec aiov; 274996c772fSJohn Dyson struct uio auio; 275996c772fSJohn Dyson char *cp; 276996c772fSJohn Dyson 277996c772fSJohn Dyson MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK); 278996c772fSJohn Dyson aiov.iov_base = cp; 279996c772fSJohn Dyson aiov.iov_len = MAXPATHLEN; 280996c772fSJohn Dyson auio.uio_iov = &aiov; 281996c772fSJohn Dyson auio.uio_iovcnt = 1; 282996c772fSJohn Dyson auio.uio_offset = 0; 283996c772fSJohn Dyson auio.uio_rw = UIO_READ; 284996c772fSJohn Dyson auio.uio_segflg = UIO_SYSSPACE; 285996c772fSJohn Dyson auio.uio_procp = ap->a_p; 286996c772fSJohn Dyson auio.uio_resid = MAXPATHLEN; 287996c772fSJohn Dyson rdlnk.a_uio = &auio; 288996c772fSJohn Dyson rdlnk.a_vp = ap->a_vp; 289996c772fSJohn Dyson rdlnk.a_cred = ap->a_cred; 290996c772fSJohn Dyson if (cd9660_readlink(&rdlnk) == 0) 291996c772fSJohn Dyson vap->va_size = MAXPATHLEN - auio.uio_resid; 292996c772fSJohn Dyson FREE(cp, M_TEMP); 293996c772fSJohn Dyson } 294df8bae1dSRodney W. Grimes vap->va_flags = 0; 295df8bae1dSRodney W. Grimes vap->va_gen = 1; 296df8bae1dSRodney W. Grimes vap->va_blocksize = ip->i_mnt->logical_block_size; 297df8bae1dSRodney W. Grimes vap->va_bytes = (u_quad_t) ip->i_size; 298df8bae1dSRodney W. Grimes vap->va_type = vp->v_type; 29994a8606fSDoug Rabson vap->va_filerev = 0; 300df8bae1dSRodney W. Grimes return (0); 301df8bae1dSRodney W. Grimes } 302df8bae1dSRodney W. Grimes 3039d322006SKATO Takenori static int cd9660_doclusterread = 1; 3049d322006SKATO Takenori SYSCTL_NODE(_vfs, MOUNT_CD9660, cd9660, CTLFLAG_RW, 0, "CD9660 filesystem"); 3059d322006SKATO Takenori SYSCTL_INT(_vfs_cd9660, CD9660_CLUSTERREAD, doclusterread, 3069d322006SKATO Takenori CTLFLAG_RW, &cd9660_doclusterread, 0, ""); 307df8bae1dSRodney W. Grimes 308df8bae1dSRodney W. Grimes /* 309df8bae1dSRodney W. Grimes * Vnode op for reading. 310df8bae1dSRodney W. Grimes */ 311605e9724SPoul-Henning Kamp static int 312df8bae1dSRodney W. Grimes cd9660_read(ap) 313df8bae1dSRodney W. Grimes struct vop_read_args /* { 314df8bae1dSRodney W. Grimes struct vnode *a_vp; 315df8bae1dSRodney W. Grimes struct uio *a_uio; 316df8bae1dSRodney W. Grimes int a_ioflag; 317df8bae1dSRodney W. Grimes struct ucred *a_cred; 318df8bae1dSRodney W. Grimes } */ *ap; 319df8bae1dSRodney W. Grimes { 320df8bae1dSRodney W. Grimes struct vnode *vp = ap->a_vp; 321df8bae1dSRodney W. Grimes register struct uio *uio = ap->a_uio; 322df8bae1dSRodney W. Grimes register struct iso_node *ip = VTOI(vp); 323df8bae1dSRodney W. Grimes register struct iso_mnt *imp; 324df8bae1dSRodney W. Grimes struct buf *bp; 3251295d82eSGary Palmer daddr_t lbn, rablock; 326df8bae1dSRodney W. Grimes off_t diff; 327df8bae1dSRodney W. Grimes int rasize, error = 0; 328df8bae1dSRodney W. Grimes long size, n, on; 329df8bae1dSRodney W. Grimes 330df8bae1dSRodney W. Grimes if (uio->uio_resid == 0) 331df8bae1dSRodney W. Grimes return (0); 332df8bae1dSRodney W. Grimes if (uio->uio_offset < 0) 333df8bae1dSRodney W. Grimes return (EINVAL); 334996c772fSJohn Dyson ip->i_flag |= IN_ACCESS; 335df8bae1dSRodney W. Grimes imp = ip->i_mnt; 336df8bae1dSRodney W. Grimes do { 337996c772fSJohn Dyson lbn = lblkno(imp, uio->uio_offset); 338996c772fSJohn Dyson on = blkoff(imp, uio->uio_offset); 339996c772fSJohn Dyson n = min((u_int)(imp->logical_block_size - on), 340df8bae1dSRodney W. Grimes uio->uio_resid); 341df8bae1dSRodney W. Grimes diff = (off_t)ip->i_size - uio->uio_offset; 342df8bae1dSRodney W. Grimes if (diff <= 0) 343df8bae1dSRodney W. Grimes return (0); 344df8bae1dSRodney W. Grimes if (diff < n) 345df8bae1dSRodney W. Grimes n = diff; 346996c772fSJohn Dyson size = blksize(imp, ip, lbn); 347df8bae1dSRodney W. Grimes rablock = lbn + 1; 3489d322006SKATO Takenori if (cd9660_doclusterread) { 349996c772fSJohn Dyson if (lblktosize(imp, rablock) <= ip->i_size) 350996c772fSJohn Dyson error = cluster_read(vp, (off_t)ip->i_size, 3518b612c4bSJohn Dyson lbn, size, NOCRED, uio->uio_resid, 3528b612c4bSJohn Dyson (ap->a_ioflag >> 16), &bp); 353df8bae1dSRodney W. Grimes else 354df8bae1dSRodney W. Grimes error = bread(vp, lbn, size, NOCRED, &bp); 355df8bae1dSRodney W. Grimes } else { 356df8bae1dSRodney W. Grimes if (vp->v_lastr + 1 == lbn && 357996c772fSJohn Dyson lblktosize(imp, rablock) < ip->i_size) { 358996c772fSJohn Dyson rasize = blksize(imp, ip, rablock); 359df8bae1dSRodney W. Grimes error = breadn(vp, lbn, size, &rablock, 360df8bae1dSRodney W. Grimes &rasize, 1, NOCRED, &bp); 361df8bae1dSRodney W. Grimes } else 362df8bae1dSRodney W. Grimes error = bread(vp, lbn, size, NOCRED, &bp); 363df8bae1dSRodney W. Grimes } 364df8bae1dSRodney W. Grimes vp->v_lastr = lbn; 365df8bae1dSRodney W. Grimes n = min(n, size - bp->b_resid); 366df8bae1dSRodney W. Grimes if (error) { 367df8bae1dSRodney W. Grimes brelse(bp); 368df8bae1dSRodney W. Grimes return (error); 369df8bae1dSRodney W. Grimes } 370df8bae1dSRodney W. Grimes 371996c772fSJohn Dyson error = uiomove(bp->b_data + on, (int)n, uio); 372df8bae1dSRodney W. Grimes brelse(bp); 373df8bae1dSRodney W. Grimes } while (error == 0 && uio->uio_resid > 0 && n != 0); 374df8bae1dSRodney W. Grimes return (error); 375df8bae1dSRodney W. Grimes } 376df8bae1dSRodney W. Grimes 377df8bae1dSRodney W. Grimes /* ARGSUSED */ 378605e9724SPoul-Henning Kamp static int 379df8bae1dSRodney W. Grimes cd9660_ioctl(ap) 380df8bae1dSRodney W. Grimes struct vop_ioctl_args /* { 381df8bae1dSRodney W. Grimes struct vnode *a_vp; 382996c772fSJohn Dyson u_long a_command; 383df8bae1dSRodney W. Grimes caddr_t a_data; 384df8bae1dSRodney W. Grimes int a_fflag; 385df8bae1dSRodney W. Grimes struct ucred *a_cred; 386df8bae1dSRodney W. Grimes struct proc *a_p; 387df8bae1dSRodney W. Grimes } */ *ap; 388df8bae1dSRodney W. Grimes { 389df8bae1dSRodney W. Grimes printf("You did ioctl for isofs !!\n"); 390df8bae1dSRodney W. Grimes return (ENOTTY); 391df8bae1dSRodney W. Grimes } 392df8bae1dSRodney W. Grimes 393df8bae1dSRodney W. Grimes /* ARGSUSED */ 394605e9724SPoul-Henning Kamp static int 395df8bae1dSRodney W. Grimes cd9660_select(ap) 396df8bae1dSRodney W. Grimes struct vop_select_args /* { 397df8bae1dSRodney W. Grimes struct vnode *a_vp; 398df8bae1dSRodney W. Grimes int a_which; 399df8bae1dSRodney W. Grimes int a_fflags; 400df8bae1dSRodney W. Grimes struct ucred *a_cred; 401df8bae1dSRodney W. Grimes struct proc *a_p; 402df8bae1dSRodney W. Grimes } */ *ap; 403df8bae1dSRodney W. Grimes { 404df8bae1dSRodney W. Grimes 405df8bae1dSRodney W. Grimes /* 406df8bae1dSRodney W. Grimes * We should really check to see if I/O is possible. 407df8bae1dSRodney W. Grimes */ 408df8bae1dSRodney W. Grimes return (1); 409df8bae1dSRodney W. Grimes } 410df8bae1dSRodney W. Grimes 411df8bae1dSRodney W. Grimes /* 412df8bae1dSRodney W. Grimes * Mmap a file 413df8bae1dSRodney W. Grimes * 414df8bae1dSRodney W. Grimes * NB Currently unsupported. 415df8bae1dSRodney W. Grimes */ 416df8bae1dSRodney W. Grimes /* ARGSUSED */ 417605e9724SPoul-Henning Kamp static int 418df8bae1dSRodney W. Grimes cd9660_mmap(ap) 419df8bae1dSRodney W. Grimes struct vop_mmap_args /* { 420df8bae1dSRodney W. Grimes struct vnode *a_vp; 421df8bae1dSRodney W. Grimes int a_fflags; 422df8bae1dSRodney W. Grimes struct ucred *a_cred; 423df8bae1dSRodney W. Grimes struct proc *a_p; 424df8bae1dSRodney W. Grimes } */ *ap; 425df8bae1dSRodney W. Grimes { 426df8bae1dSRodney W. Grimes 427df8bae1dSRodney W. Grimes return (EINVAL); 428df8bae1dSRodney W. Grimes } 429df8bae1dSRodney W. Grimes 430df8bae1dSRodney W. Grimes /* 431df8bae1dSRodney W. Grimes * Seek on a file 432df8bae1dSRodney W. Grimes * 433df8bae1dSRodney W. Grimes * Nothing to do, so just return. 434df8bae1dSRodney W. Grimes */ 435df8bae1dSRodney W. Grimes /* ARGSUSED */ 436605e9724SPoul-Henning Kamp static int 437df8bae1dSRodney W. Grimes cd9660_seek(ap) 438df8bae1dSRodney W. Grimes struct vop_seek_args /* { 439df8bae1dSRodney W. Grimes struct vnode *a_vp; 440df8bae1dSRodney W. Grimes off_t a_oldoff; 441df8bae1dSRodney W. Grimes off_t a_newoff; 442df8bae1dSRodney W. Grimes struct ucred *a_cred; 443df8bae1dSRodney W. Grimes } */ *ap; 444df8bae1dSRodney W. Grimes { 445df8bae1dSRodney W. Grimes 446df8bae1dSRodney W. Grimes return (0); 447df8bae1dSRodney W. Grimes } 448df8bae1dSRodney W. Grimes 449df8bae1dSRodney W. Grimes /* 450df8bae1dSRodney W. Grimes * Structure for reading directories 451df8bae1dSRodney W. Grimes */ 452df8bae1dSRodney W. Grimes struct isoreaddir { 453df8bae1dSRodney W. Grimes struct dirent saveent; 454df8bae1dSRodney W. Grimes struct dirent assocent; 455df8bae1dSRodney W. Grimes struct dirent current; 456df8bae1dSRodney W. Grimes off_t saveoff; 457df8bae1dSRodney W. Grimes off_t assocoff; 458df8bae1dSRodney W. Grimes off_t curroff; 459df8bae1dSRodney W. Grimes struct uio *uio; 460df8bae1dSRodney W. Grimes off_t uio_off; 461996c772fSJohn Dyson int eofflag; 462996c772fSJohn Dyson u_long *cookies; 463df8bae1dSRodney W. Grimes int ncookies; 464df8bae1dSRodney W. Grimes }; 465df8bae1dSRodney W. Grimes 466996c772fSJohn Dyson int 467df8bae1dSRodney W. Grimes iso_uiodir(idp,dp,off) 468df8bae1dSRodney W. Grimes struct isoreaddir *idp; 469df8bae1dSRodney W. Grimes struct dirent *dp; 470df8bae1dSRodney W. Grimes off_t off; 471df8bae1dSRodney W. Grimes { 472df8bae1dSRodney W. Grimes int error; 473df8bae1dSRodney W. Grimes 474df8bae1dSRodney W. Grimes dp->d_name[dp->d_namlen] = 0; 475c90607baSBruce Evans dp->d_reclen = GENERIC_DIRSIZ(dp); 476df8bae1dSRodney W. Grimes 477df8bae1dSRodney W. Grimes if (idp->uio->uio_resid < dp->d_reclen) { 478996c772fSJohn Dyson idp->eofflag = 0; 479996c772fSJohn Dyson return (-1); 480df8bae1dSRodney W. Grimes } 481df8bae1dSRodney W. Grimes 482996c772fSJohn Dyson if (idp->cookies) { 483df8bae1dSRodney W. Grimes if (idp->ncookies <= 0) { 484996c772fSJohn Dyson idp->eofflag = 0; 485996c772fSJohn Dyson return (-1); 486df8bae1dSRodney W. Grimes } 487df8bae1dSRodney W. Grimes 488996c772fSJohn Dyson *idp->cookies++ = off; 489df8bae1dSRodney W. Grimes --idp->ncookies; 490df8bae1dSRodney W. Grimes } 491df8bae1dSRodney W. Grimes 492996c772fSJohn Dyson if (error = uiomove((caddr_t) dp,dp->d_reclen,idp->uio)) 493996c772fSJohn Dyson return (error); 494df8bae1dSRodney W. Grimes idp->uio_off = off; 495996c772fSJohn Dyson return (0); 496df8bae1dSRodney W. Grimes } 497df8bae1dSRodney W. Grimes 498996c772fSJohn Dyson int 499df8bae1dSRodney W. Grimes iso_shipdir(idp) 500df8bae1dSRodney W. Grimes struct isoreaddir *idp; 501df8bae1dSRodney W. Grimes { 502df8bae1dSRodney W. Grimes struct dirent *dp; 503df8bae1dSRodney W. Grimes int cl, sl, assoc; 504df8bae1dSRodney W. Grimes int error; 505df8bae1dSRodney W. Grimes char *cname, *sname; 506df8bae1dSRodney W. Grimes 507df8bae1dSRodney W. Grimes cl = idp->current.d_namlen; 508df8bae1dSRodney W. Grimes cname = idp->current.d_name; 5091295d82eSGary Palmer assoc = (cl > 1) && (*cname == ASSOCCHAR); 5101295d82eSGary Palmer if (assoc) { 511df8bae1dSRodney W. Grimes cl--; 512df8bae1dSRodney W. Grimes cname++; 513df8bae1dSRodney W. Grimes } 514df8bae1dSRodney W. Grimes 515df8bae1dSRodney W. Grimes dp = &idp->saveent; 516df8bae1dSRodney W. Grimes sname = dp->d_name; 517df8bae1dSRodney W. Grimes if (!(sl = dp->d_namlen)) { 518df8bae1dSRodney W. Grimes dp = &idp->assocent; 519df8bae1dSRodney W. Grimes sname = dp->d_name + 1; 520df8bae1dSRodney W. Grimes sl = dp->d_namlen - 1; 521df8bae1dSRodney W. Grimes } 522df8bae1dSRodney W. Grimes if (sl > 0) { 523df8bae1dSRodney W. Grimes if (sl != cl 524df8bae1dSRodney W. Grimes || bcmp(sname,cname,sl)) { 525df8bae1dSRodney W. Grimes if (idp->assocent.d_namlen) { 526996c772fSJohn Dyson if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) 527996c772fSJohn Dyson return (error); 528df8bae1dSRodney W. Grimes idp->assocent.d_namlen = 0; 529df8bae1dSRodney W. Grimes } 530df8bae1dSRodney W. Grimes if (idp->saveent.d_namlen) { 531996c772fSJohn Dyson if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) 532996c772fSJohn Dyson return (error); 533df8bae1dSRodney W. Grimes idp->saveent.d_namlen = 0; 534df8bae1dSRodney W. Grimes } 535df8bae1dSRodney W. Grimes } 536df8bae1dSRodney W. Grimes } 537c90607baSBruce Evans idp->current.d_reclen = GENERIC_DIRSIZ(&idp->current); 538df8bae1dSRodney W. Grimes if (assoc) { 539df8bae1dSRodney W. Grimes idp->assocoff = idp->curroff; 540df8bae1dSRodney W. Grimes bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); 541df8bae1dSRodney W. Grimes } else { 542df8bae1dSRodney W. Grimes idp->saveoff = idp->curroff; 543df8bae1dSRodney W. Grimes bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); 544df8bae1dSRodney W. Grimes } 545996c772fSJohn Dyson return (0); 546df8bae1dSRodney W. Grimes } 547df8bae1dSRodney W. Grimes 548df8bae1dSRodney W. Grimes /* 549df8bae1dSRodney W. Grimes * Vnode op for readdir 550df8bae1dSRodney W. Grimes */ 551605e9724SPoul-Henning Kamp static int 552df8bae1dSRodney W. Grimes cd9660_readdir(ap) 553df8bae1dSRodney W. Grimes struct vop_readdir_args /* { 554df8bae1dSRodney W. Grimes struct vnode *a_vp; 555df8bae1dSRodney W. Grimes struct uio *a_uio; 556df8bae1dSRodney W. Grimes struct ucred *a_cred; 557996c772fSJohn Dyson int *a_eofflag; 558996c772fSJohn Dyson int *a_ncookies; 559996c772fSJohn Dyson u_long *a_cookies; 560df8bae1dSRodney W. Grimes } */ *ap; 561df8bae1dSRodney W. Grimes { 562df8bae1dSRodney W. Grimes register struct uio *uio = ap->a_uio; 563df8bae1dSRodney W. Grimes struct isoreaddir *idp; 564996c772fSJohn Dyson struct vnode *vdp = ap->a_vp; 565996c772fSJohn Dyson struct iso_node *dp; 566df8bae1dSRodney W. Grimes struct iso_mnt *imp; 567df8bae1dSRodney W. Grimes struct buf *bp = NULL; 568996c772fSJohn Dyson struct iso_directory_record *ep; 569996c772fSJohn Dyson int entryoffsetinblock; 570996c772fSJohn Dyson doff_t endsearch; 571996c772fSJohn Dyson u_long bmask; 572996c772fSJohn Dyson int error = 0; 573996c772fSJohn Dyson int reclen; 574996c772fSJohn Dyson u_short namelen; 5759abf4d6eSDoug Rabson int ncookies = 0; 576996c772fSJohn Dyson u_long *cookies = NULL; 577df8bae1dSRodney W. Grimes 578996c772fSJohn Dyson dp = VTOI(vdp); 579996c772fSJohn Dyson imp = dp->i_mnt; 580996c772fSJohn Dyson bmask = imp->im_bmask; 581df8bae1dSRodney W. Grimes 582df8bae1dSRodney W. Grimes MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK); 583996c772fSJohn Dyson idp->saveent.d_namlen = idp->assocent.d_namlen = 0; 584996c772fSJohn Dyson /* 585996c772fSJohn Dyson * XXX 586996c772fSJohn Dyson * Is it worth trying to figure out the type? 587996c772fSJohn Dyson */ 588996c772fSJohn Dyson idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = 589996c772fSJohn Dyson DT_UNKNOWN; 590df8bae1dSRodney W. Grimes idp->uio = uio; 591996c772fSJohn Dyson if (ap->a_ncookies == NULL) { 592996c772fSJohn Dyson idp->cookies = NULL; 593996c772fSJohn Dyson } else { 5949abf4d6eSDoug Rabson /* 5959abf4d6eSDoug Rabson * Guess the number of cookies needed. 5969abf4d6eSDoug Rabson */ 5979abf4d6eSDoug Rabson ncookies = uio->uio_resid / 16; 598996c772fSJohn Dyson MALLOC(cookies, u_long *, ncookies * sizeof(u_int), M_TEMP, 599996c772fSJohn Dyson M_WAITOK); 600996c772fSJohn Dyson idp->cookies = cookies; 601df8bae1dSRodney W. Grimes idp->ncookies = ncookies; 602996c772fSJohn Dyson } 603996c772fSJohn Dyson idp->eofflag = 1; 604df8bae1dSRodney W. Grimes idp->curroff = uio->uio_offset; 605df8bae1dSRodney W. Grimes 606996c772fSJohn Dyson if ((entryoffsetinblock = idp->curroff & bmask) && 607996c772fSJohn Dyson (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) { 608df8bae1dSRodney W. Grimes FREE(idp, M_TEMP); 609df8bae1dSRodney W. Grimes return (error); 610df8bae1dSRodney W. Grimes } 611996c772fSJohn Dyson endsearch = dp->i_size; 612df8bae1dSRodney W. Grimes 613df8bae1dSRodney W. Grimes while (idp->curroff < endsearch) { 614df8bae1dSRodney W. Grimes /* 615df8bae1dSRodney W. Grimes * If offset is on a block boundary, 616df8bae1dSRodney W. Grimes * read the next directory block. 617df8bae1dSRodney W. Grimes * Release previous if it exists. 618df8bae1dSRodney W. Grimes */ 619996c772fSJohn Dyson if ((idp->curroff & bmask) == 0) { 620df8bae1dSRodney W. Grimes if (bp != NULL) 621df8bae1dSRodney W. Grimes brelse(bp); 622996c772fSJohn Dyson if (error = 623996c772fSJohn Dyson VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp)) 624df8bae1dSRodney W. Grimes break; 625df8bae1dSRodney W. Grimes entryoffsetinblock = 0; 626df8bae1dSRodney W. Grimes } 627df8bae1dSRodney W. Grimes /* 628df8bae1dSRodney W. Grimes * Get pointer to next entry. 629df8bae1dSRodney W. Grimes */ 630df8bae1dSRodney W. Grimes ep = (struct iso_directory_record *) 631996c772fSJohn Dyson ((char *)bp->b_data + entryoffsetinblock); 632df8bae1dSRodney W. Grimes 633df8bae1dSRodney W. Grimes reclen = isonum_711(ep->length); 634df8bae1dSRodney W. Grimes if (reclen == 0) { 635df8bae1dSRodney W. Grimes /* skip to next block, if any */ 636996c772fSJohn Dyson idp->curroff = 637996c772fSJohn Dyson (idp->curroff & ~bmask) + imp->logical_block_size; 638df8bae1dSRodney W. Grimes continue; 639df8bae1dSRodney W. Grimes } 640df8bae1dSRodney W. Grimes 641df8bae1dSRodney W. Grimes if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 642df8bae1dSRodney W. Grimes error = EINVAL; 643df8bae1dSRodney W. Grimes /* illegal entry, stop */ 644df8bae1dSRodney W. Grimes break; 645df8bae1dSRodney W. Grimes } 646df8bae1dSRodney W. Grimes 647df8bae1dSRodney W. Grimes if (entryoffsetinblock + reclen > imp->logical_block_size) { 648df8bae1dSRodney W. Grimes error = EINVAL; 649df8bae1dSRodney W. Grimes /* illegal directory, so stop looking */ 650df8bae1dSRodney W. Grimes break; 651df8bae1dSRodney W. Grimes } 652df8bae1dSRodney W. Grimes 653996c772fSJohn Dyson idp->current.d_namlen = isonum_711(ep->name_len); 654996c772fSJohn Dyson 655996c772fSJohn Dyson if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 65681ec856aSJoerg Wunsch error = EINVAL; 65781ec856aSJoerg Wunsch /* illegal entry, stop */ 65881ec856aSJoerg Wunsch break; 65981ec856aSJoerg Wunsch } 66081ec856aSJoerg Wunsch 661996c772fSJohn Dyson if (isonum_711(ep->flags)&2) 662996c772fSJohn Dyson idp->current.d_fileno = isodirino(ep, imp); 663df8bae1dSRodney W. Grimes else 664df8bae1dSRodney W. Grimes idp->current.d_fileno = dbtob(bp->b_blkno) + 665996c772fSJohn Dyson entryoffsetinblock; 666df8bae1dSRodney W. Grimes 667df8bae1dSRodney W. Grimes idp->curroff += reclen; 668996c772fSJohn Dyson 669df8bae1dSRodney W. Grimes switch (imp->iso_ftype) { 670df8bae1dSRodney W. Grimes case ISO_FTYPE_RRIP: 671996c772fSJohn Dyson cd9660_rrip_getname(ep,idp->current.d_name, &namelen, 672df8bae1dSRodney W. Grimes &idp->current.d_fileno,imp); 673996c772fSJohn Dyson idp->current.d_namlen = (u_char)namelen; 674df8bae1dSRodney W. Grimes if (idp->current.d_namlen) 675df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 676df8bae1dSRodney W. Grimes break; 677988fa8efSJoerg Wunsch default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 || ISO_FTYPE_HIGH_SIERRA*/ 678df8bae1dSRodney W. Grimes strcpy(idp->current.d_name,".."); 679df8bae1dSRodney W. Grimes switch (ep->name[0]) { 680df8bae1dSRodney W. Grimes case 0: 681df8bae1dSRodney W. Grimes idp->current.d_namlen = 1; 682df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 683df8bae1dSRodney W. Grimes break; 684df8bae1dSRodney W. Grimes case 1: 685df8bae1dSRodney W. Grimes idp->current.d_namlen = 2; 686df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 687df8bae1dSRodney W. Grimes break; 688df8bae1dSRodney W. Grimes default: 689df8bae1dSRodney W. Grimes isofntrans(ep->name,idp->current.d_namlen, 690996c772fSJohn Dyson idp->current.d_name, &namelen, 691df8bae1dSRodney W. Grimes imp->iso_ftype == ISO_FTYPE_9660, 692996c772fSJohn Dyson isonum_711(ep->flags)&4); 693996c772fSJohn Dyson idp->current.d_namlen = (u_char)namelen; 694df8bae1dSRodney W. Grimes if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 695df8bae1dSRodney W. Grimes error = iso_shipdir(idp); 696df8bae1dSRodney W. Grimes else 697df8bae1dSRodney W. Grimes error = iso_uiodir(idp,&idp->current,idp->curroff); 698df8bae1dSRodney W. Grimes break; 699df8bae1dSRodney W. Grimes } 700df8bae1dSRodney W. Grimes } 701df8bae1dSRodney W. Grimes if (error) 702df8bae1dSRodney W. Grimes break; 703df8bae1dSRodney W. Grimes 704df8bae1dSRodney W. Grimes entryoffsetinblock += reclen; 705df8bae1dSRodney W. Grimes } 706df8bae1dSRodney W. Grimes 707df8bae1dSRodney W. Grimes if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 708df8bae1dSRodney W. Grimes idp->current.d_namlen = 0; 709df8bae1dSRodney W. Grimes error = iso_shipdir(idp); 710df8bae1dSRodney W. Grimes } 711df8bae1dSRodney W. Grimes if (error < 0) 712df8bae1dSRodney W. Grimes error = 0; 713df8bae1dSRodney W. Grimes 7149abf4d6eSDoug Rabson if (ap->a_ncookies != NULL) { 7159abf4d6eSDoug Rabson if (error) 716996c772fSJohn Dyson free(cookies, M_TEMP); 7179abf4d6eSDoug Rabson else { 7189abf4d6eSDoug Rabson /* 7199abf4d6eSDoug Rabson * Work out the number of cookies actually used. 7209abf4d6eSDoug Rabson */ 7219abf4d6eSDoug Rabson *ap->a_ncookies = ncookies - idp->ncookies; 7229abf4d6eSDoug Rabson *ap->a_cookies = cookies; 7239abf4d6eSDoug Rabson } 7249abf4d6eSDoug Rabson } 7259abf4d6eSDoug Rabson 726df8bae1dSRodney W. Grimes if (bp) 727df8bae1dSRodney W. Grimes brelse (bp); 728df8bae1dSRodney W. Grimes 729df8bae1dSRodney W. Grimes uio->uio_offset = idp->uio_off; 730996c772fSJohn Dyson *ap->a_eofflag = idp->eofflag; 731df8bae1dSRodney W. Grimes 732df8bae1dSRodney W. Grimes FREE(idp, M_TEMP); 733df8bae1dSRodney W. Grimes 734df8bae1dSRodney W. Grimes return (error); 735df8bae1dSRodney W. Grimes } 736df8bae1dSRodney W. Grimes 737df8bae1dSRodney W. Grimes /* 738df8bae1dSRodney W. Grimes * Return target name of a symbolic link 739df8bae1dSRodney W. Grimes * Shouldn't we get the parent vnode and read the data from there? 740df8bae1dSRodney W. Grimes * This could eventually result in deadlocks in cd9660_lookup. 741df8bae1dSRodney W. Grimes * But otherwise the block read here is in the block buffer two times. 742df8bae1dSRodney W. Grimes */ 743df8bae1dSRodney W. Grimes typedef struct iso_directory_record ISODIR; 744df8bae1dSRodney W. Grimes typedef struct iso_node ISONODE; 745df8bae1dSRodney W. Grimes typedef struct iso_mnt ISOMNT; 746605e9724SPoul-Henning Kamp static int 747df8bae1dSRodney W. Grimes cd9660_readlink(ap) 748df8bae1dSRodney W. Grimes struct vop_readlink_args /* { 749df8bae1dSRodney W. Grimes struct vnode *a_vp; 750df8bae1dSRodney W. Grimes struct uio *a_uio; 751df8bae1dSRodney W. Grimes struct ucred *a_cred; 752df8bae1dSRodney W. Grimes } */ *ap; 753df8bae1dSRodney W. Grimes { 754df8bae1dSRodney W. Grimes ISONODE *ip; 755df8bae1dSRodney W. Grimes ISODIR *dirp; 756df8bae1dSRodney W. Grimes ISOMNT *imp; 757df8bae1dSRodney W. Grimes struct buf *bp; 758996c772fSJohn Dyson struct uio *uio; 759df8bae1dSRodney W. Grimes u_short symlen; 760df8bae1dSRodney W. Grimes int error; 761df8bae1dSRodney W. Grimes char *symname; 762df8bae1dSRodney W. Grimes 763df8bae1dSRodney W. Grimes ip = VTOI(ap->a_vp); 764df8bae1dSRodney W. Grimes imp = ip->i_mnt; 765996c772fSJohn Dyson uio = ap->a_uio; 766df8bae1dSRodney W. Grimes 767df8bae1dSRodney W. Grimes if (imp->iso_ftype != ISO_FTYPE_RRIP) 768996c772fSJohn Dyson return (EINVAL); 769df8bae1dSRodney W. Grimes 770df8bae1dSRodney W. Grimes /* 771df8bae1dSRodney W. Grimes * Get parents directory record block that this inode included. 772df8bae1dSRodney W. Grimes */ 773df8bae1dSRodney W. Grimes error = bread(imp->im_devvp, 774996c772fSJohn Dyson (ip->i_number >> imp->im_bshift) << 775996c772fSJohn Dyson (imp->im_bshift - DEV_BSHIFT), 776996c772fSJohn Dyson imp->logical_block_size, NOCRED, &bp); 777df8bae1dSRodney W. Grimes if (error) { 778df8bae1dSRodney W. Grimes brelse(bp); 779996c772fSJohn Dyson return (EINVAL); 780df8bae1dSRodney W. Grimes } 781df8bae1dSRodney W. Grimes 782df8bae1dSRodney W. Grimes /* 783df8bae1dSRodney W. Grimes * Setup the directory pointer for this inode 784df8bae1dSRodney W. Grimes */ 785996c772fSJohn Dyson dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask)); 786df8bae1dSRodney W. Grimes 787df8bae1dSRodney W. Grimes /* 788df8bae1dSRodney W. Grimes * Just make sure, we have a right one.... 789df8bae1dSRodney W. Grimes * 1: Check not cross boundary on block 790df8bae1dSRodney W. Grimes */ 791df8bae1dSRodney W. Grimes if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 79292579404SAlexander Langer > (unsigned)imp->logical_block_size) { 793df8bae1dSRodney W. Grimes brelse(bp); 794996c772fSJohn Dyson return (EINVAL); 795df8bae1dSRodney W. Grimes } 796df8bae1dSRodney W. Grimes 797df8bae1dSRodney W. Grimes /* 798df8bae1dSRodney W. Grimes * Now get a buffer 799df8bae1dSRodney W. Grimes * Abuse a namei buffer for now. 800df8bae1dSRodney W. Grimes */ 801996c772fSJohn Dyson if (uio->uio_segflg == UIO_SYSSPACE) 802996c772fSJohn Dyson symname = uio->uio_iov->iov_base; 803996c772fSJohn Dyson else 804df8bae1dSRodney W. Grimes MALLOC(symname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); 805df8bae1dSRodney W. Grimes 806df8bae1dSRodney W. Grimes /* 807df8bae1dSRodney W. Grimes * Ok, we just gathering a symbolic name in SL record. 808df8bae1dSRodney W. Grimes */ 809df8bae1dSRodney W. Grimes if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) { 810996c772fSJohn Dyson if (uio->uio_segflg != UIO_SYSSPACE) 811df8bae1dSRodney W. Grimes FREE(symname, M_NAMEI); 812df8bae1dSRodney W. Grimes brelse(bp); 813996c772fSJohn Dyson return (EINVAL); 814df8bae1dSRodney W. Grimes } 815df8bae1dSRodney W. Grimes /* 816df8bae1dSRodney W. Grimes * Don't forget before you leave from home ;-) 817df8bae1dSRodney W. Grimes */ 818df8bae1dSRodney W. Grimes brelse(bp); 819df8bae1dSRodney W. Grimes 820df8bae1dSRodney W. Grimes /* 821df8bae1dSRodney W. Grimes * return with the symbolic name to caller's. 822df8bae1dSRodney W. Grimes */ 823996c772fSJohn Dyson if (uio->uio_segflg != UIO_SYSSPACE) { 824996c772fSJohn Dyson error = uiomove(symname, symlen, uio); 825df8bae1dSRodney W. Grimes FREE(symname, M_NAMEI); 826996c772fSJohn Dyson return (error); 827996c772fSJohn Dyson } 828996c772fSJohn Dyson uio->uio_resid -= symlen; 829996c772fSJohn Dyson uio->uio_iov->iov_base += symlen; 830996c772fSJohn Dyson uio->uio_iov->iov_len -= symlen; 831996c772fSJohn Dyson return (0); 832df8bae1dSRodney W. Grimes } 833df8bae1dSRodney W. Grimes 834df8bae1dSRodney W. Grimes /* 835df8bae1dSRodney W. Grimes * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 836df8bae1dSRodney W. Grimes * done. If a buffer has been saved in anticipation of a CREATE, delete it. 837df8bae1dSRodney W. Grimes */ 838605e9724SPoul-Henning Kamp static int 839df8bae1dSRodney W. Grimes cd9660_abortop(ap) 840df8bae1dSRodney W. Grimes struct vop_abortop_args /* { 841df8bae1dSRodney W. Grimes struct vnode *a_dvp; 842df8bae1dSRodney W. Grimes struct componentname *a_cnp; 843df8bae1dSRodney W. Grimes } */ *ap; 844df8bae1dSRodney W. Grimes { 845df8bae1dSRodney W. Grimes if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 846df8bae1dSRodney W. Grimes FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 847996c772fSJohn Dyson return (0); 848df8bae1dSRodney W. Grimes } 849df8bae1dSRodney W. Grimes 850df8bae1dSRodney W. Grimes /* 851df8bae1dSRodney W. Grimes * Lock an inode. 852df8bae1dSRodney W. Grimes */ 853605e9724SPoul-Henning Kamp static int 854df8bae1dSRodney W. Grimes cd9660_lock(ap) 855df8bae1dSRodney W. Grimes struct vop_lock_args /* { 856df8bae1dSRodney W. Grimes struct vnode *a_vp; 857996c772fSJohn Dyson int a_flags; 858996c772fSJohn Dyson struct proc *a_p; 859df8bae1dSRodney W. Grimes } */ *ap; 860df8bae1dSRodney W. Grimes { 861996c772fSJohn Dyson struct vnode *vp = ap->a_vp; 862df8bae1dSRodney W. Grimes 863996c772fSJohn Dyson return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock, 864996c772fSJohn Dyson ap->a_p)); 865df8bae1dSRodney W. Grimes } 866df8bae1dSRodney W. Grimes 867df8bae1dSRodney W. Grimes /* 868df8bae1dSRodney W. Grimes * Unlock an inode. 869df8bae1dSRodney W. Grimes */ 870605e9724SPoul-Henning Kamp static int 871df8bae1dSRodney W. Grimes cd9660_unlock(ap) 872df8bae1dSRodney W. Grimes struct vop_unlock_args /* { 873df8bae1dSRodney W. Grimes struct vnode *a_vp; 874996c772fSJohn Dyson int a_flags; 875996c772fSJohn Dyson struct proc *a_p; 876df8bae1dSRodney W. Grimes } */ *ap; 877df8bae1dSRodney W. Grimes { 878996c772fSJohn Dyson struct vnode *vp = ap->a_vp; 879df8bae1dSRodney W. Grimes 880996c772fSJohn Dyson return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE, 881996c772fSJohn Dyson &vp->v_interlock, ap->a_p)); 882df8bae1dSRodney W. Grimes } 883df8bae1dSRodney W. Grimes 884df8bae1dSRodney W. Grimes /* 885df8bae1dSRodney W. Grimes * Calculate the logical to physical mapping if not done already, 886df8bae1dSRodney W. Grimes * then call the device strategy routine. 887df8bae1dSRodney W. Grimes */ 888605e9724SPoul-Henning Kamp static int 889df8bae1dSRodney W. Grimes cd9660_strategy(ap) 890df8bae1dSRodney W. Grimes struct vop_strategy_args /* { 891df8bae1dSRodney W. Grimes struct buf *a_bp; 892df8bae1dSRodney W. Grimes } */ *ap; 893df8bae1dSRodney W. Grimes { 894df8bae1dSRodney W. Grimes register struct buf *bp = ap->a_bp; 895df8bae1dSRodney W. Grimes register struct vnode *vp = bp->b_vp; 896df8bae1dSRodney W. Grimes register struct iso_node *ip; 897df8bae1dSRodney W. Grimes int error; 898df8bae1dSRodney W. Grimes 899df8bae1dSRodney W. Grimes ip = VTOI(vp); 900df8bae1dSRodney W. Grimes if (vp->v_type == VBLK || vp->v_type == VCHR) 901df8bae1dSRodney W. Grimes panic("cd9660_strategy: spec"); 902df8bae1dSRodney W. Grimes if (bp->b_blkno == bp->b_lblkno) { 9031295d82eSGary Palmer if ((error = 904c83ebe77SJohn Dyson VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL))) { 905df8bae1dSRodney W. Grimes bp->b_error = error; 906df8bae1dSRodney W. Grimes bp->b_flags |= B_ERROR; 907df8bae1dSRodney W. Grimes biodone(bp); 908df8bae1dSRodney W. Grimes return (error); 909df8bae1dSRodney W. Grimes } 910df8bae1dSRodney W. Grimes if ((long)bp->b_blkno == -1) 911df8bae1dSRodney W. Grimes clrbuf(bp); 912df8bae1dSRodney W. Grimes } 913df8bae1dSRodney W. Grimes if ((long)bp->b_blkno == -1) { 914df8bae1dSRodney W. Grimes biodone(bp); 915df8bae1dSRodney W. Grimes return (0); 916df8bae1dSRodney W. Grimes } 917df8bae1dSRodney W. Grimes vp = ip->i_devvp; 918df8bae1dSRodney W. Grimes bp->b_dev = vp->v_rdev; 919df8bae1dSRodney W. Grimes VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 920df8bae1dSRodney W. Grimes return (0); 921df8bae1dSRodney W. Grimes } 922df8bae1dSRodney W. Grimes 923df8bae1dSRodney W. Grimes /* 924df8bae1dSRodney W. Grimes * Print out the contents of an inode. 925df8bae1dSRodney W. Grimes */ 926605e9724SPoul-Henning Kamp static int 927df8bae1dSRodney W. Grimes cd9660_print(ap) 928df8bae1dSRodney W. Grimes struct vop_print_args /* { 929df8bae1dSRodney W. Grimes struct vnode *a_vp; 930df8bae1dSRodney W. Grimes } */ *ap; 931df8bae1dSRodney W. Grimes { 932996c772fSJohn Dyson 933df8bae1dSRodney W. Grimes printf("tag VT_ISOFS, isofs vnode\n"); 934996c772fSJohn Dyson return (0); 935df8bae1dSRodney W. Grimes } 936df8bae1dSRodney W. Grimes 937df8bae1dSRodney W. Grimes /* 938996c772fSJohn Dyson * Check for a locked inode. 939df8bae1dSRodney W. Grimes */ 940996c772fSJohn Dyson int 941996c772fSJohn Dyson cd9660_islocked(ap) 942996c772fSJohn Dyson struct vop_islocked_args /* { 943996c772fSJohn Dyson struct vnode *a_vp; 944996c772fSJohn Dyson } */ *ap; 945df8bae1dSRodney W. Grimes { 946df8bae1dSRodney W. Grimes 947996c772fSJohn Dyson return (lockstatus(&VTOI(ap->a_vp)->i_lock)); 948996c772fSJohn Dyson } 949996c772fSJohn Dyson 950996c772fSJohn Dyson /* 951996c772fSJohn Dyson * Return POSIX pathconf information applicable to cd9660 filesystems. 952996c772fSJohn Dyson */ 953996c772fSJohn Dyson int 954996c772fSJohn Dyson cd9660_pathconf(ap) 955996c772fSJohn Dyson struct vop_pathconf_args /* { 956996c772fSJohn Dyson struct vnode *a_vp; 957996c772fSJohn Dyson int a_name; 958996c772fSJohn Dyson register_t *a_retval; 959996c772fSJohn Dyson } */ *ap; 960996c772fSJohn Dyson { 961996c772fSJohn Dyson 962996c772fSJohn Dyson switch (ap->a_name) { 963996c772fSJohn Dyson case _PC_LINK_MAX: 964996c772fSJohn Dyson *ap->a_retval = 1; 965996c772fSJohn Dyson return (0); 966996c772fSJohn Dyson case _PC_NAME_MAX: 967996c772fSJohn Dyson if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP) 968996c772fSJohn Dyson *ap->a_retval = NAME_MAX; 969996c772fSJohn Dyson else 970996c772fSJohn Dyson *ap->a_retval = 37; 971996c772fSJohn Dyson return (0); 972996c772fSJohn Dyson case _PC_PATH_MAX: 973996c772fSJohn Dyson *ap->a_retval = PATH_MAX; 974996c772fSJohn Dyson return (0); 975996c772fSJohn Dyson case _PC_PIPE_BUF: 976996c772fSJohn Dyson *ap->a_retval = PIPE_BUF; 977996c772fSJohn Dyson return (0); 978996c772fSJohn Dyson case _PC_CHOWN_RESTRICTED: 979996c772fSJohn Dyson *ap->a_retval = 1; 980996c772fSJohn Dyson return (0); 981996c772fSJohn Dyson case _PC_NO_TRUNC: 982996c772fSJohn Dyson *ap->a_retval = 1; 983996c772fSJohn Dyson return (0); 984996c772fSJohn Dyson default: 985996c772fSJohn Dyson return (EINVAL); 986996c772fSJohn Dyson } 987996c772fSJohn Dyson /* NOTREACHED */ 988df8bae1dSRodney W. Grimes } 989df8bae1dSRodney W. Grimes 990df8bae1dSRodney W. Grimes /* 991df8bae1dSRodney W. Grimes * Global vfs data structures for isofs 992df8bae1dSRodney W. Grimes */ 993df8bae1dSRodney W. Grimes #define cd9660_create \ 994996c772fSJohn Dyson ((int (*) __P((struct vop_create_args *)))eopnotsupp) 995996c772fSJohn Dyson #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))eopnotsupp) 996996c772fSJohn Dyson #define cd9660_write ((int (*) __P((struct vop_write_args *)))eopnotsupp) 997996c772fSJohn Dyson #ifdef NFS 998996c772fSJohn Dyson #define cd9660_lease_check lease_check 999996c772fSJohn Dyson #else 1000996c772fSJohn Dyson #define cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop) 1001996c772fSJohn Dyson #endif 1002df8bae1dSRodney W. Grimes #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 1003df8bae1dSRodney W. Grimes #define cd9660_remove \ 1004996c772fSJohn Dyson ((int (*) __P((struct vop_remove_args *)))eopnotsupp) 1005996c772fSJohn Dyson #define cd9660_link ((int (*) __P((struct vop_link_args *)))eopnotsupp) 1006df8bae1dSRodney W. Grimes #define cd9660_rename \ 1007996c772fSJohn Dyson ((int (*) __P((struct vop_rename_args *)))eopnotsupp) 1008996c772fSJohn Dyson #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))eopnotsupp) 1009996c772fSJohn Dyson #define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))eopnotsupp) 1010df8bae1dSRodney W. Grimes #define cd9660_symlink \ 1011996c772fSJohn Dyson ((int (*) __P((struct vop_symlink_args *)))eopnotsupp) 1012df8bae1dSRodney W. Grimes #define cd9660_advlock \ 1013996c772fSJohn Dyson ((int (*) __P((struct vop_advlock_args *)))eopnotsupp) 1014df8bae1dSRodney W. Grimes #define cd9660_valloc ((int(*) __P(( \ 1015df8bae1dSRodney W. Grimes struct vnode *pvp, \ 1016df8bae1dSRodney W. Grimes int mode, \ 1017df8bae1dSRodney W. Grimes struct ucred *cred, \ 1018996c772fSJohn Dyson struct vnode **vpp))) eopnotsupp) 1019996c772fSJohn Dyson #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))eopnotsupp) 1020df8bae1dSRodney W. Grimes #define cd9660_truncate \ 1021996c772fSJohn Dyson ((int (*) __P((struct vop_truncate_args *)))eopnotsupp) 1022df8bae1dSRodney W. Grimes #define cd9660_update \ 1023996c772fSJohn Dyson ((int (*) __P((struct vop_update_args *)))eopnotsupp) 1024df8bae1dSRodney W. Grimes #define cd9660_bwrite \ 1025996c772fSJohn Dyson ((int (*) __P((struct vop_bwrite_args *)))eopnotsupp) 1026df8bae1dSRodney W. Grimes 1027df8bae1dSRodney W. Grimes /* 1028996c772fSJohn Dyson * Global vfs data structures for cd9660 1029df8bae1dSRodney W. Grimes */ 1030f57e6547SBruce Evans vop_t **cd9660_vnodeop_p; 1031996c772fSJohn Dyson struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { 1032996c772fSJohn Dyson 1033f57e6547SBruce Evans { &vop_default_desc, (vop_t *)vn_default_error }, 1034f57e6547SBruce Evans { &vop_lookup_desc, (vop_t *)cd9660_lookup }, /* lookup */ 1035f57e6547SBruce Evans { &vop_create_desc, (vop_t *)cd9660_create }, /* create */ 1036f57e6547SBruce Evans { &vop_mknod_desc, (vop_t *)cd9660_mknod }, /* mknod */ 1037f57e6547SBruce Evans { &vop_open_desc, (vop_t *)cd9660_open }, /* open */ 1038f57e6547SBruce Evans { &vop_close_desc, (vop_t *)cd9660_close }, /* close */ 1039f57e6547SBruce Evans { &vop_access_desc, (vop_t *)cd9660_access }, /* access */ 1040f57e6547SBruce Evans { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */ 1041f57e6547SBruce Evans { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */ 1042f57e6547SBruce Evans { &vop_read_desc, (vop_t *)cd9660_read }, /* read */ 1043f57e6547SBruce Evans { &vop_write_desc, (vop_t *)cd9660_write }, /* write */ 1044996c772fSJohn Dyson { &vop_lease_desc, (vop_t *)cd9660_lease_check },/* lease */ 1045f57e6547SBruce Evans { &vop_ioctl_desc, (vop_t *)cd9660_ioctl }, /* ioctl */ 1046f57e6547SBruce Evans { &vop_select_desc, (vop_t *)cd9660_select }, /* select */ 1047996c772fSJohn Dyson { &vop_revoke_desc, (vop_t *)cd9660_revoke }, /* revoke */ 1048f57e6547SBruce Evans { &vop_mmap_desc, (vop_t *)cd9660_mmap }, /* mmap */ 1049f57e6547SBruce Evans { &vop_fsync_desc, (vop_t *)cd9660_fsync }, /* fsync */ 1050f57e6547SBruce Evans { &vop_seek_desc, (vop_t *)cd9660_seek }, /* seek */ 1051f57e6547SBruce Evans { &vop_remove_desc, (vop_t *)cd9660_remove }, /* remove */ 1052f57e6547SBruce Evans { &vop_link_desc, (vop_t *)cd9660_link }, /* link */ 1053f57e6547SBruce Evans { &vop_rename_desc, (vop_t *)cd9660_rename }, /* rename */ 1054f57e6547SBruce Evans { &vop_mkdir_desc, (vop_t *)cd9660_mkdir }, /* mkdir */ 1055f57e6547SBruce Evans { &vop_rmdir_desc, (vop_t *)cd9660_rmdir }, /* rmdir */ 1056f57e6547SBruce Evans { &vop_symlink_desc, (vop_t *)cd9660_symlink }, /* symlink */ 1057f57e6547SBruce Evans { &vop_readdir_desc, (vop_t *)cd9660_readdir }, /* readdir */ 1058f57e6547SBruce Evans { &vop_readlink_desc, (vop_t *)cd9660_readlink },/* readlink */ 1059f57e6547SBruce Evans { &vop_abortop_desc, (vop_t *)cd9660_abortop }, /* abortop */ 1060f57e6547SBruce Evans { &vop_inactive_desc, (vop_t *)cd9660_inactive },/* inactive */ 1061f57e6547SBruce Evans { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */ 1062f57e6547SBruce Evans { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */ 1063f57e6547SBruce Evans { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */ 1064f57e6547SBruce Evans { &vop_bmap_desc, (vop_t *)cd9660_bmap }, /* bmap */ 1065f57e6547SBruce Evans { &vop_strategy_desc, (vop_t *)cd9660_strategy },/* strategy */ 1066f57e6547SBruce Evans { &vop_print_desc, (vop_t *)cd9660_print }, /* print */ 1067f57e6547SBruce Evans { &vop_islocked_desc, (vop_t *)cd9660_islocked },/* islocked */ 1068f57e6547SBruce Evans { &vop_pathconf_desc, (vop_t *)cd9660_pathconf },/* pathconf */ 1069f57e6547SBruce Evans { &vop_advlock_desc, (vop_t *)cd9660_advlock }, /* advlock */ 1070f57e6547SBruce Evans { &vop_blkatoff_desc, (vop_t *)cd9660_blkatoff },/* blkatoff */ 1071f57e6547SBruce Evans { &vop_valloc_desc, (vop_t *)cd9660_valloc }, /* valloc */ 1072f57e6547SBruce Evans { &vop_vfree_desc, (vop_t *)cd9660_vfree }, /* vfree */ 1073f57e6547SBruce Evans { &vop_truncate_desc, (vop_t *)cd9660_truncate },/* truncate */ 1074f57e6547SBruce Evans { &vop_update_desc, (vop_t *)cd9660_update }, /* update */ 1075996c772fSJohn Dyson { &vop_bwrite_desc, (vop_t *)vn_bwrite }, 1076f57e6547SBruce Evans { NULL, NULL } 1077df8bae1dSRodney W. Grimes }; 1078605e9724SPoul-Henning Kamp static struct vnodeopv_desc cd9660_vnodeop_opv_desc = 1079df8bae1dSRodney W. Grimes { &cd9660_vnodeop_p, cd9660_vnodeop_entries }; 1080c901836cSGarrett Wollman VNODEOP_SET(cd9660_vnodeop_opv_desc); 1081df8bae1dSRodney W. Grimes 1082df8bae1dSRodney W. Grimes /* 1083df8bae1dSRodney W. Grimes * Special device vnode ops 1084df8bae1dSRodney W. Grimes */ 1085f57e6547SBruce Evans vop_t **cd9660_specop_p; 1086996c772fSJohn Dyson struct vnodeopv_entry_desc cd9660_specop_entries[] = { 1087f57e6547SBruce Evans { &vop_default_desc, (vop_t *)vn_default_error }, 1088f57e6547SBruce Evans { &vop_lookup_desc, (vop_t *)spec_lookup }, /* lookup */ 1089996c772fSJohn Dyson { &vop_create_desc, (vop_t *)spec_create }, /* create */ 1090996c772fSJohn Dyson { &vop_mknod_desc, (vop_t *)spec_mknod }, /* mknod */ 1091f57e6547SBruce Evans { &vop_open_desc, (vop_t *)spec_open }, /* open */ 1092f57e6547SBruce Evans { &vop_close_desc, (vop_t *)spec_close }, /* close */ 1093f57e6547SBruce Evans { &vop_access_desc, (vop_t *)cd9660_access }, /* access */ 1094f57e6547SBruce Evans { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */ 1095f57e6547SBruce Evans { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */ 1096f57e6547SBruce Evans { &vop_read_desc, (vop_t *)spec_read }, /* read */ 1097f57e6547SBruce Evans { &vop_write_desc, (vop_t *)spec_write }, /* write */ 1098996c772fSJohn Dyson { &vop_lease_desc, (vop_t *)spec_lease_check }, /* lease */ 1099f57e6547SBruce Evans { &vop_ioctl_desc, (vop_t *)spec_ioctl }, /* ioctl */ 1100f57e6547SBruce Evans { &vop_select_desc, (vop_t *)spec_select }, /* select */ 1101996c772fSJohn Dyson { &vop_revoke_desc, (vop_t *)spec_revoke }, /* revoke */ 1102f57e6547SBruce Evans { &vop_mmap_desc, (vop_t *)spec_mmap }, /* mmap */ 1103f57e6547SBruce Evans { &vop_fsync_desc, (vop_t *)spec_fsync }, /* fsync */ 1104f57e6547SBruce Evans { &vop_seek_desc, (vop_t *)spec_seek }, /* seek */ 1105996c772fSJohn Dyson { &vop_remove_desc, (vop_t *)spec_remove }, /* remove */ 1106996c772fSJohn Dyson { &vop_link_desc, (vop_t *)spec_link }, /* link */ 1107996c772fSJohn Dyson { &vop_rename_desc, (vop_t *)spec_rename }, /* rename */ 1108996c772fSJohn Dyson { &vop_mkdir_desc, (vop_t *)spec_mkdir }, /* mkdir */ 1109996c772fSJohn Dyson { &vop_rmdir_desc, (vop_t *)spec_rmdir }, /* rmdir */ 1110996c772fSJohn Dyson { &vop_symlink_desc, (vop_t *)spec_symlink }, /* symlink */ 1111f57e6547SBruce Evans { &vop_readdir_desc, (vop_t *)spec_readdir }, /* readdir */ 1112f57e6547SBruce Evans { &vop_readlink_desc, (vop_t *)spec_readlink }, /* readlink */ 1113f57e6547SBruce Evans { &vop_abortop_desc, (vop_t *)spec_abortop }, /* abortop */ 1114f57e6547SBruce Evans { &vop_inactive_desc, (vop_t *)cd9660_inactive },/* inactive */ 1115f57e6547SBruce Evans { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */ 1116f57e6547SBruce Evans { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */ 1117f57e6547SBruce Evans { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */ 1118f57e6547SBruce Evans { &vop_bmap_desc, (vop_t *)spec_bmap }, /* bmap */ 1119f57e6547SBruce Evans { &vop_strategy_desc, (vop_t *)spec_strategy }, /* strategy */ 1120f57e6547SBruce Evans { &vop_print_desc, (vop_t *)cd9660_print }, /* print */ 1121f57e6547SBruce Evans { &vop_islocked_desc, (vop_t *)cd9660_islocked },/* islocked */ 1122f57e6547SBruce Evans { &vop_pathconf_desc, (vop_t *)spec_pathconf }, /* pathconf */ 1123f57e6547SBruce Evans { &vop_advlock_desc, (vop_t *)spec_advlock }, /* advlock */ 1124f57e6547SBruce Evans { &vop_blkatoff_desc, (vop_t *)spec_blkatoff }, /* blkatoff */ 1125f57e6547SBruce Evans { &vop_valloc_desc, (vop_t *)spec_valloc }, /* valloc */ 1126f57e6547SBruce Evans { &vop_vfree_desc, (vop_t *)spec_vfree }, /* vfree */ 1127f57e6547SBruce Evans { &vop_truncate_desc, (vop_t *)spec_truncate }, /* truncate */ 1128f57e6547SBruce Evans { &vop_update_desc, (vop_t *)cd9660_update }, /* update */ 1129996c772fSJohn Dyson { &vop_bwrite_desc, (vop_t *)vn_bwrite }, 1130f57e6547SBruce Evans { NULL, NULL } 1131df8bae1dSRodney W. Grimes }; 1132605e9724SPoul-Henning Kamp static struct vnodeopv_desc cd9660_specop_opv_desc = 1133df8bae1dSRodney W. Grimes { &cd9660_specop_p, cd9660_specop_entries }; 1134c901836cSGarrett Wollman VNODEOP_SET(cd9660_specop_opv_desc); 1135df8bae1dSRodney W. Grimes 1136f57e6547SBruce Evans vop_t **cd9660_fifoop_p; 1137996c772fSJohn Dyson struct vnodeopv_entry_desc cd9660_fifoop_entries[] = { 1138f57e6547SBruce Evans { &vop_default_desc, (vop_t *)vn_default_error }, 1139f57e6547SBruce Evans { &vop_lookup_desc, (vop_t *)fifo_lookup }, /* lookup */ 1140996c772fSJohn Dyson { &vop_create_desc, (vop_t *)fifo_create }, /* create */ 1141996c772fSJohn Dyson { &vop_mknod_desc, (vop_t *)fifo_mknod }, /* mknod */ 1142f57e6547SBruce Evans { &vop_open_desc, (vop_t *)fifo_open }, /* open */ 1143f57e6547SBruce Evans { &vop_close_desc, (vop_t *)fifo_close }, /* close */ 1144f57e6547SBruce Evans { &vop_access_desc, (vop_t *)cd9660_access }, /* access */ 1145f57e6547SBruce Evans { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */ 1146f57e6547SBruce Evans { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */ 1147f57e6547SBruce Evans { &vop_read_desc, (vop_t *)fifo_read }, /* read */ 1148f57e6547SBruce Evans { &vop_write_desc, (vop_t *)fifo_write }, /* write */ 1149996c772fSJohn Dyson { &vop_lease_desc, (vop_t *)fifo_lease_check }, /* lease */ 1150f57e6547SBruce Evans { &vop_ioctl_desc, (vop_t *)fifo_ioctl }, /* ioctl */ 1151f57e6547SBruce Evans { &vop_select_desc, (vop_t *)fifo_select }, /* select */ 1152996c772fSJohn Dyson { &vop_revoke_desc, (vop_t *)fifo_revoke }, /* revoke */ 1153f57e6547SBruce Evans { &vop_mmap_desc, (vop_t *)fifo_mmap }, /* mmap */ 1154f57e6547SBruce Evans { &vop_fsync_desc, (vop_t *)fifo_fsync }, /* fsync */ 1155f57e6547SBruce Evans { &vop_seek_desc, (vop_t *)fifo_seek }, /* seek */ 1156996c772fSJohn Dyson { &vop_remove_desc, (vop_t *)fifo_remove }, /* remove */ 1157996c772fSJohn Dyson { &vop_link_desc, (vop_t *)fifo_link } , /* link */ 1158996c772fSJohn Dyson { &vop_rename_desc, (vop_t *)fifo_rename }, /* rename */ 1159996c772fSJohn Dyson { &vop_mkdir_desc, (vop_t *)fifo_mkdir }, /* mkdir */ 1160996c772fSJohn Dyson { &vop_rmdir_desc, (vop_t *)fifo_rmdir }, /* rmdir */ 1161996c772fSJohn Dyson { &vop_symlink_desc, (vop_t *)fifo_symlink }, /* symlink */ 1162f57e6547SBruce Evans { &vop_readdir_desc, (vop_t *)fifo_readdir }, /* readdir */ 1163f57e6547SBruce Evans { &vop_readlink_desc, (vop_t *)fifo_readlink }, /* readlink */ 1164f57e6547SBruce Evans { &vop_abortop_desc, (vop_t *)fifo_abortop }, /* abortop */ 1165f57e6547SBruce Evans { &vop_inactive_desc, (vop_t *)cd9660_inactive },/* inactive */ 1166f57e6547SBruce Evans { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */ 1167f57e6547SBruce Evans { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */ 1168f57e6547SBruce Evans { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */ 1169f57e6547SBruce Evans { &vop_bmap_desc, (vop_t *)fifo_bmap }, /* bmap */ 1170996c772fSJohn Dyson { &vop_strategy_desc, (vop_t *)fifo_strategy }, /* strategy */ 1171f57e6547SBruce Evans { &vop_print_desc, (vop_t *)cd9660_print }, /* print */ 1172f57e6547SBruce Evans { &vop_islocked_desc, (vop_t *)cd9660_islocked },/* islocked */ 1173f57e6547SBruce Evans { &vop_pathconf_desc, (vop_t *)fifo_pathconf }, /* pathconf */ 1174f57e6547SBruce Evans { &vop_advlock_desc, (vop_t *)fifo_advlock }, /* advlock */ 1175f57e6547SBruce Evans { &vop_blkatoff_desc, (vop_t *)fifo_blkatoff }, /* blkatoff */ 1176f57e6547SBruce Evans { &vop_valloc_desc, (vop_t *)fifo_valloc }, /* valloc */ 1177f57e6547SBruce Evans { &vop_vfree_desc, (vop_t *)fifo_vfree }, /* vfree */ 1178f57e6547SBruce Evans { &vop_truncate_desc, (vop_t *)fifo_truncate }, /* truncate */ 1179f57e6547SBruce Evans { &vop_update_desc, (vop_t *)cd9660_update }, /* update */ 1180996c772fSJohn Dyson { &vop_bwrite_desc, (vop_t *)vn_bwrite }, 1181f57e6547SBruce Evans { NULL, NULL } 1182df8bae1dSRodney W. Grimes }; 1183605e9724SPoul-Henning Kamp static struct vnodeopv_desc cd9660_fifoop_opv_desc = 1184df8bae1dSRodney W. Grimes { &cd9660_fifoop_p, cd9660_fifoop_entries }; 1185c901836cSGarrett Wollman 1186c901836cSGarrett Wollman VNODEOP_SET(cd9660_fifoop_opv_desc); 1187