165789Smckusick /*- 265789Smckusick * Copyright (c) 1994 365789Smckusick * The Regents of the University of California. All rights reserved. 465789Smckusick * 565789Smckusick * This code is derived from software contributed to Berkeley 665789Smckusick * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 765789Smckusick * Support code is derived from software contributed to Berkeley 865789Smckusick * by Atsushi Murai (amurai@spec.co.jp). 965789Smckusick * 1065789Smckusick * %sccs.include.redist.c% 1165789Smckusick * 12*68052Smckusick * @(#)cd9660_vnops.c 8.14 (Berkeley) 12/05/94 1365789Smckusick */ 1465789Smckusick 1565789Smckusick #include <sys/param.h> 1665789Smckusick #include <sys/systm.h> 1765789Smckusick #include <sys/namei.h> 1865789Smckusick #include <sys/resourcevar.h> 1965789Smckusick #include <sys/kernel.h> 2065789Smckusick #include <sys/file.h> 2165789Smckusick #include <sys/stat.h> 2265789Smckusick #include <sys/buf.h> 2365789Smckusick #include <sys/proc.h> 2465789Smckusick #include <sys/conf.h> 2565789Smckusick #include <sys/mount.h> 2665789Smckusick #include <sys/vnode.h> 2765789Smckusick #include <miscfs/specfs/specdev.h> 2865789Smckusick #include <miscfs/fifofs/fifo.h> 2965789Smckusick #include <sys/malloc.h> 3065789Smckusick #include <sys/dir.h> 3165789Smckusick 3265789Smckusick #include <isofs/cd9660/iso.h> 3365855Smckusick #include <isofs/cd9660/cd9660_node.h> 3465789Smckusick #include <isofs/cd9660/iso_rrip.h> 3565789Smckusick 3665789Smckusick #if 0 3765789Smckusick /* 3865789Smckusick * Mknod vnode call 3965789Smckusick * Actually remap the device number 4065789Smckusick */ 4165855Smckusick cd9660_mknod(ndp, vap, cred, p) 4265789Smckusick struct nameidata *ndp; 4365789Smckusick struct ucred *cred; 4465789Smckusick struct vattr *vap; 4565789Smckusick struct proc *p; 4665789Smckusick { 4765789Smckusick #ifndef ISODEVMAP 4865789Smckusick free(ndp->ni_pnbuf, M_NAMEI); 4965789Smckusick vput(ndp->ni_dvp); 5065789Smckusick vput(ndp->ni_vp); 5167379Smkm return (EINVAL); 5265789Smckusick #else 5365789Smckusick register struct vnode *vp; 5465789Smckusick struct iso_node *ip; 5565789Smckusick struct iso_dnode *dp; 5665789Smckusick int error; 57*68052Smckusick 5865789Smckusick vp = ndp->ni_vp; 5965789Smckusick ip = VTOI(vp); 60*68052Smckusick 6165789Smckusick if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP 6265789Smckusick || vap->va_type != vp->v_type 6365789Smckusick || (vap->va_type != VCHR && vap->va_type != VBLK)) { 6465789Smckusick free(ndp->ni_pnbuf, M_NAMEI); 6565789Smckusick vput(ndp->ni_dvp); 6665789Smckusick vput(ndp->ni_vp); 6767379Smkm return (EINVAL); 6865789Smckusick } 69*68052Smckusick 7065789Smckusick dp = iso_dmap(ip->i_dev,ip->i_number,1); 7165789Smckusick if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) { 7265789Smckusick /* same as the unmapped one, delete the mapping */ 7365789Smckusick remque(dp); 7465789Smckusick FREE(dp,M_CACHE); 7565789Smckusick } else 7665789Smckusick /* enter new mapping */ 7765789Smckusick dp->d_dev = vap->va_rdev; 78*68052Smckusick 7965789Smckusick /* 8065789Smckusick * Remove inode so that it will be reloaded by iget and 8165789Smckusick * checked to see if it is an alias of an existing entry 8265789Smckusick * in the inode cache. 8365789Smckusick */ 8465789Smckusick vput(vp); 8565789Smckusick vp->v_type = VNON; 8665789Smckusick vgone(vp); 8765789Smckusick return (0); 8865789Smckusick #endif 8965789Smckusick } 9065789Smckusick #endif 9165789Smckusick 9265789Smckusick /* 9365789Smckusick * Open called. 9465789Smckusick * 9565789Smckusick * Nothing to do. 9665789Smckusick */ 9765789Smckusick /* ARGSUSED */ 9865789Smckusick int 9965855Smckusick cd9660_open(ap) 10065789Smckusick struct vop_open_args /* { 10165789Smckusick struct vnode *a_vp; 10265789Smckusick int a_mode; 10365789Smckusick struct ucred *a_cred; 10465789Smckusick struct proc *a_p; 10565789Smckusick } */ *ap; 10665789Smckusick { 10765789Smckusick return (0); 10865789Smckusick } 10965789Smckusick 11065789Smckusick /* 11165789Smckusick * Close called 11265789Smckusick * 11365789Smckusick * Update the times on the inode on writeable file systems. 11465789Smckusick */ 11565789Smckusick /* ARGSUSED */ 11665789Smckusick int 11765855Smckusick cd9660_close(ap) 11865789Smckusick struct vop_close_args /* { 11965789Smckusick struct vnode *a_vp; 12065789Smckusick int a_fflag; 12165789Smckusick struct ucred *a_cred; 12265789Smckusick struct proc *a_p; 12365789Smckusick } */ *ap; 12465789Smckusick { 12565789Smckusick return (0); 12665789Smckusick } 12765789Smckusick 12865789Smckusick /* 12965789Smckusick * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 13065789Smckusick * The mode is shifted to select the owner/group/other fields. The 13165789Smckusick * super user is granted all permissions. 13265789Smckusick */ 13365789Smckusick /* ARGSUSED */ 13465855Smckusick cd9660_access(ap) 13565789Smckusick struct vop_access_args /* { 13665789Smckusick struct vnode *a_vp; 13765789Smckusick int a_mode; 13865789Smckusick struct ucred *a_cred; 13965789Smckusick struct proc *a_p; 14065789Smckusick } */ *ap; 14165789Smckusick { 14267379Smkm struct iso_node *ip = VTOI(ap->a_vp); 14367379Smkm struct ucred *cred = ap->a_cred; 14467379Smkm mode_t mask, mode = ap->a_mode; 14567379Smkm gid_t *gp; 146*68052Smckusick int i; 14767379Smkm 14867379Smkm /* User id 0 always gets access. */ 14967379Smkm if (cred->cr_uid == 0) 15067379Smkm return (0); 15167379Smkm 15267379Smkm mask = 0; 15367379Smkm 15467379Smkm /* Otherwise, check the owner. */ 15567379Smkm if (cred->cr_uid == ip->inode.iso_uid) { 15667379Smkm if (mode & VEXEC) 15767379Smkm mask |= S_IXUSR; 15867379Smkm if (mode & VREAD) 15967379Smkm mask |= S_IRUSR; 16067379Smkm if (mode & VWRITE) 16167379Smkm mask |= S_IWUSR; 16267379Smkm return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); 16367379Smkm } 16467379Smkm 16567379Smkm /* Otherwise, check the groups. */ 16667379Smkm for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++) 16767379Smkm if (ip->inode.iso_gid == *gp) { 16867379Smkm if (mode & VEXEC) 16967379Smkm mask |= S_IXGRP; 17067379Smkm if (mode & VREAD) 17167379Smkm mask |= S_IRGRP; 17267379Smkm if (mode & VWRITE) 17367379Smkm mask |= S_IWGRP; 17467379Smkm return ((ip->inode.iso_mode & mask) == mask ? 17567379Smkm 0 : EACCES); 17667379Smkm } 17767379Smkm 17867379Smkm /* Otherwise, check everyone else. */ 17967379Smkm if (mode & VEXEC) 18067379Smkm mask |= S_IXOTH; 18167379Smkm if (mode & VREAD) 18267379Smkm mask |= S_IROTH; 18367379Smkm if (mode & VWRITE) 18467379Smkm mask |= S_IWOTH; 18567379Smkm return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES); 18665789Smckusick } 18765789Smckusick 18865855Smckusick cd9660_getattr(ap) 18965789Smckusick struct vop_getattr_args /* { 19065789Smckusick struct vnode *a_vp; 19165789Smckusick struct vattr *a_vap; 19265789Smckusick struct ucred *a_cred; 19365789Smckusick struct proc *a_p; 19465789Smckusick } */ *ap; 19565789Smckusick 19665789Smckusick { 19765789Smckusick struct vnode *vp = ap->a_vp; 19865789Smckusick register struct vattr *vap = ap->a_vap; 19965789Smckusick register struct iso_node *ip = VTOI(vp); 20065789Smckusick int i; 20165789Smckusick 20265789Smckusick vap->va_fsid = ip->i_dev; 20365789Smckusick vap->va_fileid = ip->i_number; 20465789Smckusick 20565789Smckusick vap->va_mode = ip->inode.iso_mode; 20665789Smckusick vap->va_nlink = ip->inode.iso_links; 20765789Smckusick vap->va_uid = ip->inode.iso_uid; 20865789Smckusick vap->va_gid = ip->inode.iso_gid; 20965789Smckusick vap->va_atime = ip->inode.iso_atime; 21065789Smckusick vap->va_mtime = ip->inode.iso_mtime; 21165789Smckusick vap->va_ctime = ip->inode.iso_ctime; 21265789Smckusick vap->va_rdev = ip->inode.iso_rdev; 21365789Smckusick 21465789Smckusick vap->va_size = (u_quad_t) ip->i_size; 21567703Smckusick if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) { 21667703Smckusick struct vop_readlink_args rdlnk; 21767703Smckusick struct iovec aiov; 21867703Smckusick struct uio auio; 21967703Smckusick char *cp; 22067703Smckusick 22167703Smckusick MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK); 22267703Smckusick aiov.iov_base = cp; 22367703Smckusick aiov.iov_len = MAXPATHLEN; 22467703Smckusick auio.uio_iov = &aiov; 22567703Smckusick auio.uio_iovcnt = 1; 22667703Smckusick auio.uio_offset = 0; 22767703Smckusick auio.uio_rw = UIO_READ; 22867703Smckusick auio.uio_segflg = UIO_SYSSPACE; 22967703Smckusick auio.uio_procp = ap->a_p; 23067703Smckusick auio.uio_resid = MAXPATHLEN; 23167703Smckusick rdlnk.a_uio = &auio; 23267703Smckusick rdlnk.a_vp = ap->a_vp; 23367703Smckusick rdlnk.a_cred = ap->a_cred; 23467703Smckusick if (cd9660_readlink(&rdlnk) == 0) 23567703Smckusick vap->va_size = MAXPATHLEN - auio.uio_resid; 23667703Smckusick FREE(cp, M_TEMP); 23767703Smckusick } 23865789Smckusick vap->va_flags = 0; 23965789Smckusick vap->va_gen = 1; 24065789Smckusick vap->va_blocksize = ip->i_mnt->logical_block_size; 24165789Smckusick vap->va_bytes = (u_quad_t) ip->i_size; 24265789Smckusick vap->va_type = vp->v_type; 24365789Smckusick return (0); 24465789Smckusick } 24565789Smckusick 24665789Smckusick #if ISO_DEFAULT_BLOCK_SIZE >= NBPG 24765789Smckusick #ifdef DEBUG 24865789Smckusick extern int doclusterread; 24965789Smckusick #else 25065789Smckusick #define doclusterread 1 25165789Smckusick #endif 25265789Smckusick #else 25365789Smckusick /* XXX until cluster routines can handle block sizes less than one page */ 25465789Smckusick #define doclusterread 0 25565789Smckusick #endif 25665789Smckusick 25765789Smckusick /* 25865789Smckusick * Vnode op for reading. 25965789Smckusick */ 26065855Smckusick cd9660_read(ap) 26165789Smckusick struct vop_read_args /* { 26265789Smckusick struct vnode *a_vp; 26365789Smckusick struct uio *a_uio; 26465789Smckusick int a_ioflag; 26565789Smckusick struct ucred *a_cred; 26665789Smckusick } */ *ap; 26765789Smckusick { 26865789Smckusick struct vnode *vp = ap->a_vp; 26965789Smckusick register struct uio *uio = ap->a_uio; 27065789Smckusick register struct iso_node *ip = VTOI(vp); 27165789Smckusick register struct iso_mnt *imp; 27265789Smckusick struct buf *bp; 27365789Smckusick daddr_t lbn, bn, rablock; 27465789Smckusick off_t diff; 27565789Smckusick int rasize, error = 0; 27665789Smckusick long size, n, on; 277*68052Smckusick 27865789Smckusick if (uio->uio_resid == 0) 27965789Smckusick return (0); 28065789Smckusick if (uio->uio_offset < 0) 28165789Smckusick return (EINVAL); 28267526Smckusick ip->i_flag |= IN_ACCESS; 28365789Smckusick imp = ip->i_mnt; 28465789Smckusick do { 285*68052Smckusick lbn = lblkno(imp, uio->uio_offset); 286*68052Smckusick on = blkoff(imp, uio->uio_offset); 287*68052Smckusick n = min((u_int)(imp->logical_block_size - on), 28865789Smckusick uio->uio_resid); 28965789Smckusick diff = (off_t)ip->i_size - uio->uio_offset; 29065789Smckusick if (diff <= 0) 29165789Smckusick return (0); 29265789Smckusick if (diff < n) 29365789Smckusick n = diff; 294*68052Smckusick size = blksize(imp, ip, lbn); 29565789Smckusick rablock = lbn + 1; 29665789Smckusick if (doclusterread) { 297*68052Smckusick if (lblktosize(imp, rablock) <= ip->i_size) 29865789Smckusick error = cluster_read(vp, (off_t)ip->i_size, 29965789Smckusick lbn, size, NOCRED, &bp); 300*68052Smckusick else 30165789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 30265789Smckusick } else { 30365789Smckusick if (vp->v_lastr + 1 == lbn && 304*68052Smckusick lblktosize(imp, rablock) < ip->i_size) { 305*68052Smckusick rasize = blksize(imp, ip, rablock); 30665789Smckusick error = breadn(vp, lbn, size, &rablock, 30765789Smckusick &rasize, 1, NOCRED, &bp); 30865789Smckusick } else 30965789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 31065789Smckusick } 31165789Smckusick vp->v_lastr = lbn; 31265789Smckusick n = min(n, size - bp->b_resid); 31365789Smckusick if (error) { 31465789Smckusick brelse(bp); 31565789Smckusick return (error); 31665789Smckusick } 31765789Smckusick 318*68052Smckusick error = uiomove(bp->b_data + on, (int)n, uio); 31965789Smckusick if (n + on == imp->logical_block_size || 32065789Smckusick uio->uio_offset == (off_t)ip->i_size) 32165789Smckusick bp->b_flags |= B_AGE; 32265789Smckusick brelse(bp); 32365789Smckusick } while (error == 0 && uio->uio_resid > 0 && n != 0); 32465789Smckusick return (error); 32565789Smckusick } 32665789Smckusick 32765789Smckusick /* ARGSUSED */ 32865789Smckusick int 32965855Smckusick cd9660_ioctl(ap) 33065789Smckusick struct vop_ioctl_args /* { 33165789Smckusick struct vnode *a_vp; 332*68052Smckusick u_long a_command; 33365789Smckusick caddr_t a_data; 33465789Smckusick int a_fflag; 33565789Smckusick struct ucred *a_cred; 33665789Smckusick struct proc *a_p; 33765789Smckusick } */ *ap; 33865789Smckusick { 33965789Smckusick printf("You did ioctl for isofs !!\n"); 34065789Smckusick return (ENOTTY); 34165789Smckusick } 34265789Smckusick 34365789Smckusick /* ARGSUSED */ 34465789Smckusick int 34565855Smckusick cd9660_select(ap) 34665789Smckusick struct vop_select_args /* { 34765789Smckusick struct vnode *a_vp; 34865789Smckusick int a_which; 34965789Smckusick int a_fflags; 35065789Smckusick struct ucred *a_cred; 35165789Smckusick struct proc *a_p; 35265789Smckusick } */ *ap; 35365789Smckusick { 35465789Smckusick 35565789Smckusick /* 35665789Smckusick * We should really check to see if I/O is possible. 35765789Smckusick */ 35865789Smckusick return (1); 35965789Smckusick } 36065789Smckusick 36165789Smckusick /* 36265789Smckusick * Mmap a file 36365789Smckusick * 36465789Smckusick * NB Currently unsupported. 36565789Smckusick */ 36665789Smckusick /* ARGSUSED */ 36765789Smckusick int 36865855Smckusick cd9660_mmap(ap) 36965789Smckusick struct vop_mmap_args /* { 37065789Smckusick struct vnode *a_vp; 37165789Smckusick int a_fflags; 37265789Smckusick struct ucred *a_cred; 37365789Smckusick struct proc *a_p; 37465789Smckusick } */ *ap; 37565789Smckusick { 37665789Smckusick 37765789Smckusick return (EINVAL); 37865789Smckusick } 37965789Smckusick 38065789Smckusick /* 38165789Smckusick * Seek on a file 38265789Smckusick * 38365789Smckusick * Nothing to do, so just return. 38465789Smckusick */ 38565789Smckusick /* ARGSUSED */ 38665789Smckusick int 38765855Smckusick cd9660_seek(ap) 38865789Smckusick struct vop_seek_args /* { 38965789Smckusick struct vnode *a_vp; 39065789Smckusick off_t a_oldoff; 39165789Smckusick off_t a_newoff; 39265789Smckusick struct ucred *a_cred; 39365789Smckusick } */ *ap; 39465789Smckusick { 39565789Smckusick 39665789Smckusick return (0); 39765789Smckusick } 39865789Smckusick 39965789Smckusick /* 40065789Smckusick * Structure for reading directories 40165789Smckusick */ 40265789Smckusick struct isoreaddir { 40365789Smckusick struct dirent saveent; 40465789Smckusick struct dirent assocent; 40565789Smckusick struct dirent current; 40665789Smckusick off_t saveoff; 40765789Smckusick off_t assocoff; 40865789Smckusick off_t curroff; 40965789Smckusick struct uio *uio; 41065789Smckusick off_t uio_off; 41167370Smckusick int eofflag; 41267370Smckusick u_long *cookies; 41365789Smckusick int ncookies; 41465789Smckusick }; 41565789Smckusick 416*68052Smckusick int 41765789Smckusick iso_uiodir(idp,dp,off) 41865789Smckusick struct isoreaddir *idp; 41965789Smckusick struct dirent *dp; 42065789Smckusick off_t off; 42165789Smckusick { 42265789Smckusick int error; 423*68052Smckusick 42465789Smckusick dp->d_name[dp->d_namlen] = 0; 42565789Smckusick dp->d_reclen = DIRSIZ(dp); 426*68052Smckusick 42765789Smckusick if (idp->uio->uio_resid < dp->d_reclen) { 42867370Smckusick idp->eofflag = 0; 42967370Smckusick return (-1); 43065789Smckusick } 431*68052Smckusick 43267370Smckusick if (idp->cookies) { 43365789Smckusick if (idp->ncookies <= 0) { 43467370Smckusick idp->eofflag = 0; 43567370Smckusick return (-1); 43665789Smckusick } 437*68052Smckusick 43867370Smckusick *idp->cookies++ = off; 43965789Smckusick --idp->ncookies; 44065789Smckusick } 441*68052Smckusick 44265789Smckusick if (error = uiomove(dp,dp->d_reclen,idp->uio)) 44367370Smckusick return (error); 44465789Smckusick idp->uio_off = off; 44567370Smckusick return (0); 44665789Smckusick } 44765789Smckusick 448*68052Smckusick int 44965789Smckusick iso_shipdir(idp) 45065789Smckusick struct isoreaddir *idp; 45165789Smckusick { 45265789Smckusick struct dirent *dp; 45365789Smckusick int cl, sl, assoc; 45465789Smckusick int error; 45565789Smckusick char *cname, *sname; 456*68052Smckusick 45765789Smckusick cl = idp->current.d_namlen; 45865789Smckusick cname = idp->current.d_name; 45965789Smckusick if (assoc = cl > 1 && *cname == ASSOCCHAR) { 46065789Smckusick cl--; 46165789Smckusick cname++; 46265789Smckusick } 463*68052Smckusick 46465789Smckusick dp = &idp->saveent; 46565789Smckusick sname = dp->d_name; 46665789Smckusick if (!(sl = dp->d_namlen)) { 46765789Smckusick dp = &idp->assocent; 46865789Smckusick sname = dp->d_name + 1; 46965789Smckusick sl = dp->d_namlen - 1; 47065789Smckusick } 47165789Smckusick if (sl > 0) { 47265789Smckusick if (sl != cl 47365789Smckusick || bcmp(sname,cname,sl)) { 47465789Smckusick if (idp->assocent.d_namlen) { 47565789Smckusick if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) 47667379Smkm return (error); 47765789Smckusick idp->assocent.d_namlen = 0; 47865789Smckusick } 47965789Smckusick if (idp->saveent.d_namlen) { 48065789Smckusick if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) 48167379Smkm return (error); 48265789Smckusick idp->saveent.d_namlen = 0; 48365789Smckusick } 48465789Smckusick } 48565789Smckusick } 48665789Smckusick idp->current.d_reclen = DIRSIZ(&idp->current); 48765789Smckusick if (assoc) { 48865789Smckusick idp->assocoff = idp->curroff; 48965789Smckusick bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); 49065789Smckusick } else { 49165789Smckusick idp->saveoff = idp->curroff; 49265789Smckusick bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); 49365789Smckusick } 49467379Smkm return (0); 49565789Smckusick } 49665789Smckusick 49765789Smckusick /* 49865789Smckusick * Vnode op for readdir 49965789Smckusick */ 50065789Smckusick int 50165855Smckusick cd9660_readdir(ap) 50265789Smckusick struct vop_readdir_args /* { 50365789Smckusick struct vnode *a_vp; 50465789Smckusick struct uio *a_uio; 50565789Smckusick struct ucred *a_cred; 50667370Smckusick int *a_eofflag; 50767370Smckusick u_long *a_cookies; 50867370Smckusick int a_ncookies; 50965789Smckusick } */ *ap; 51065789Smckusick { 51165789Smckusick register struct uio *uio = ap->a_uio; 51265789Smckusick struct isoreaddir *idp; 513*68052Smckusick struct vnode *vdp = ap->a_vp; 514*68052Smckusick struct iso_node *dp; 515*68052Smckusick struct iso_mnt *imp; 516*68052Smckusick struct buf *bp = NULL; 517*68052Smckusick struct iso_directory_record *ep; 51865789Smckusick int entryoffsetinblock; 519*68052Smckusick doff_t endsearch; 520*68052Smckusick u_long bmask; 52165789Smckusick int error = 0; 52265789Smckusick int reclen; 523*68052Smckusick u_short namelen; 524*68052Smckusick 525*68052Smckusick dp = VTOI(vdp); 526*68052Smckusick imp = dp->i_mnt; 527*68052Smckusick bmask = imp->im_bmask; 528*68052Smckusick 52967529Smckusick MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK); 53067529Smckusick idp->saveent.d_namlen = idp->assocent.d_namlen = 0; 53167529Smckusick /* 53267529Smckusick * XXX 53367529Smckusick * Is it worth trying to figure out the type? 53467529Smckusick */ 53567529Smckusick idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = 53667529Smckusick DT_UNKNOWN; 53765789Smckusick idp->uio = uio; 53867370Smckusick idp->eofflag = 1; 53967370Smckusick idp->cookies = ap->a_cookies; 54067370Smckusick idp->ncookies = ap->a_ncookies; 54165789Smckusick idp->curroff = uio->uio_offset; 542*68052Smckusick 543*68052Smckusick if ((entryoffsetinblock = idp->curroff & bmask) && 544*68052Smckusick (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) { 545*68052Smckusick FREE(idp, M_TEMP); 546*68052Smckusick return (error); 54765789Smckusick } 548*68052Smckusick endsearch = dp->i_size; 549*68052Smckusick 55065789Smckusick while (idp->curroff < endsearch) { 55165789Smckusick /* 55265789Smckusick * If offset is on a block boundary, 55365789Smckusick * read the next directory block. 55465789Smckusick * Release previous if it exists. 55565789Smckusick */ 556*68052Smckusick if ((idp->curroff & bmask) == 0) { 55765789Smckusick if (bp != NULL) 55865789Smckusick brelse(bp); 559*68052Smckusick if (error = 560*68052Smckusick VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp)) 56165789Smckusick break; 56265789Smckusick entryoffsetinblock = 0; 56365789Smckusick } 56465789Smckusick /* 56565789Smckusick * Get pointer to next entry. 56665789Smckusick */ 56765789Smckusick ep = (struct iso_directory_record *) 568*68052Smckusick ((char *)bp->b_data + entryoffsetinblock); 569*68052Smckusick 570*68052Smckusick reclen = isonum_711(ep->length); 57165789Smckusick if (reclen == 0) { 57265789Smckusick /* skip to next block, if any */ 57367559Smckusick idp->curroff = 574*68052Smckusick (idp->curroff & ~bmask) + imp->logical_block_size; 57565789Smckusick continue; 57665789Smckusick } 577*68052Smckusick 57865789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 57965789Smckusick error = EINVAL; 58065789Smckusick /* illegal entry, stop */ 58165789Smckusick break; 58265789Smckusick } 583*68052Smckusick 58465789Smckusick if (entryoffsetinblock + reclen > imp->logical_block_size) { 58565789Smckusick error = EINVAL; 58665789Smckusick /* illegal directory, so stop looking */ 58765789Smckusick break; 58865789Smckusick } 589*68052Smckusick 59067559Smckusick idp->current.d_namlen = isonum_711(ep->name_len); 59167559Smckusick 59265789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 59365789Smckusick error = EINVAL; 59465789Smckusick /* illegal entry, stop */ 59565789Smckusick break; 59665789Smckusick } 597*68052Smckusick 59867559Smckusick if (isonum_711(ep->flags)&2) 599*68052Smckusick idp->current.d_fileno = isodirino(ep, imp); 60067559Smckusick else 60167559Smckusick idp->current.d_fileno = dbtob(bp->b_blkno) + 60267559Smckusick entryoffsetinblock; 603*68052Smckusick 60465789Smckusick idp->curroff += reclen; 60567559Smckusick 60665789Smckusick switch (imp->iso_ftype) { 60765789Smckusick case ISO_FTYPE_RRIP: 608*68052Smckusick cd9660_rrip_getname(ep,idp->current.d_name, &namelen, 60965789Smckusick &idp->current.d_fileno,imp); 610*68052Smckusick idp->current.d_namlen = (u_char)namelen; 61165789Smckusick if (idp->current.d_namlen) 61265789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 61365789Smckusick break; 61465789Smckusick default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ 61565789Smckusick strcpy(idp->current.d_name,".."); 61665789Smckusick switch (ep->name[0]) { 61765789Smckusick case 0: 61865789Smckusick idp->current.d_namlen = 1; 61965789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 62065789Smckusick break; 62165789Smckusick case 1: 62265789Smckusick idp->current.d_namlen = 2; 62365789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 62465789Smckusick break; 62565789Smckusick default: 62665789Smckusick isofntrans(ep->name,idp->current.d_namlen, 627*68052Smckusick idp->current.d_name, &namelen, 62865789Smckusick imp->iso_ftype == ISO_FTYPE_9660, 62965789Smckusick isonum_711(ep->flags)&4); 630*68052Smckusick idp->current.d_namlen = (u_char)namelen; 63165789Smckusick if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 63265789Smckusick error = iso_shipdir(idp); 63365789Smckusick else 63465789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 63565789Smckusick break; 63665789Smckusick } 63765789Smckusick } 63865789Smckusick if (error) 63965789Smckusick break; 640*68052Smckusick 64165789Smckusick entryoffsetinblock += reclen; 64265789Smckusick } 643*68052Smckusick 64465789Smckusick if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 64565789Smckusick idp->current.d_namlen = 0; 64665789Smckusick error = iso_shipdir(idp); 64765789Smckusick } 64865789Smckusick if (error < 0) 64965789Smckusick error = 0; 650*68052Smckusick 65165789Smckusick if (bp) 65265789Smckusick brelse (bp); 653*68052Smckusick 65465789Smckusick uio->uio_offset = idp->uio_off; 65567370Smckusick *ap->a_eofflag = idp->eofflag; 656*68052Smckusick 657*68052Smckusick FREE(idp, M_TEMP); 658*68052Smckusick 65965789Smckusick return (error); 66065789Smckusick } 661*68052Smckusick 66265789Smckusick /* 66365789Smckusick * Return target name of a symbolic link 66465789Smckusick * Shouldn't we get the parent vnode and read the data from there? 66565855Smckusick * This could eventually result in deadlocks in cd9660_lookup. 66665789Smckusick * But otherwise the block read here is in the block buffer two times. 66765789Smckusick */ 66865789Smckusick typedef struct iso_directory_record ISODIR; 66965789Smckusick typedef struct iso_node ISONODE; 67065789Smckusick typedef struct iso_mnt ISOMNT; 67165789Smckusick int 67265855Smckusick cd9660_readlink(ap) 67365789Smckusick struct vop_readlink_args /* { 67465789Smckusick struct vnode *a_vp; 67565789Smckusick struct uio *a_uio; 67665789Smckusick struct ucred *a_cred; 67765789Smckusick } */ *ap; 67865789Smckusick { 67965789Smckusick ISONODE *ip; 680*68052Smckusick ISODIR *dirp; 68165789Smckusick ISOMNT *imp; 68265789Smckusick struct buf *bp; 68365789Smckusick u_short symlen; 68465789Smckusick int error; 68565789Smckusick char *symname; 68665789Smckusick ino_t ino; 687*68052Smckusick 68865789Smckusick ip = VTOI(ap->a_vp); 68965789Smckusick imp = ip->i_mnt; 690*68052Smckusick 69165789Smckusick if (imp->iso_ftype != ISO_FTYPE_RRIP) 69267379Smkm return (EINVAL); 693*68052Smckusick 69465789Smckusick /* 69565789Smckusick * Get parents directory record block that this inode included. 69665789Smckusick */ 69765789Smckusick error = bread(imp->im_devvp, 698*68052Smckusick (ip->i_number >> imp->im_bshift) << 699*68052Smckusick (imp->im_bshift - DEV_BSHIFT), 700*68052Smckusick imp->logical_block_size, NOCRED, &bp); 70165789Smckusick if (error) { 70265789Smckusick brelse(bp); 70367379Smkm return (EINVAL); 70465789Smckusick } 70565789Smckusick 70665789Smckusick /* 70765789Smckusick * Setup the directory pointer for this inode 70865789Smckusick */ 709*68052Smckusick dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask)); 71067379Smkm 71165789Smckusick /* 71265789Smckusick * Just make sure, we have a right one.... 71365789Smckusick * 1: Check not cross boundary on block 71465789Smckusick */ 71565789Smckusick if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 71665789Smckusick > imp->logical_block_size) { 71765789Smckusick brelse(bp); 71867379Smkm return (EINVAL); 71965789Smckusick } 720*68052Smckusick 72165789Smckusick /* 72265789Smckusick * Now get a buffer 72365789Smckusick * Abuse a namei buffer for now. 72465789Smckusick */ 72567710Smckusick if (uio->uio_segflg == UIO_SYSSPACE) 72667710Smckusick symname = uio->uio_iov->iov_base; 72767710Smckusick else 72867710Smckusick MALLOC(symname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); 72965789Smckusick 73065789Smckusick /* 73165789Smckusick * Ok, we just gathering a symbolic name in SL record. 73265789Smckusick */ 73367710Smckusick if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) { 73467710Smckusick if (uio->uio_segflg != UIO_SYSSPACE) 73567710Smckusick FREE(symname, M_NAMEI); 73665789Smckusick brelse(bp); 73767379Smkm return (EINVAL); 73865789Smckusick } 73965789Smckusick /* 74065789Smckusick * Don't forget before you leave from home ;-) 74165789Smckusick */ 74265789Smckusick brelse(bp); 74365789Smckusick 74465789Smckusick /* 74565789Smckusick * return with the symbolic name to caller's. 74665789Smckusick */ 74767710Smckusick if (uio->uio_segflg != UIO_SYSSPACE) { 74867710Smckusick error = uiomove(symname, symlen, uio); 74967710Smckusick FREE(symname, M_NAMEI); 75067710Smckusick return (error); 75167710Smckusick } 75267710Smckusick uio->uio_resid -= symlen; 75367710Smckusick uio->uio_iov->iov_base += symlen; 75467710Smckusick uio->uio_iov->iov_len -= symlen; 75567710Smckusick return (0); 75665789Smckusick } 75765789Smckusick 75865789Smckusick /* 75965789Smckusick * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 76065789Smckusick * done. If a buffer has been saved in anticipation of a CREATE, delete it. 76165789Smckusick */ 76265789Smckusick int 76365855Smckusick cd9660_abortop(ap) 76465789Smckusick struct vop_abortop_args /* { 76565789Smckusick struct vnode *a_dvp; 76665789Smckusick struct componentname *a_cnp; 76765789Smckusick } */ *ap; 76865789Smckusick { 76965789Smckusick if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 77065789Smckusick FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 77167379Smkm return (0); 77265789Smckusick } 77365789Smckusick 77465789Smckusick /* 77565789Smckusick * Lock an inode. 77665789Smckusick */ 77765789Smckusick int 77865855Smckusick cd9660_lock(ap) 77965789Smckusick struct vop_lock_args /* { 78065789Smckusick struct vnode *a_vp; 78165789Smckusick } */ *ap; 78265789Smckusick { 78367526Smckusick register struct vnode *vp = ap->a_vp; 78467526Smckusick register struct iso_node *ip; 78567526Smckusick struct proc *p = curproc; /* XXX */ 78665789Smckusick 78767526Smckusick start: 78867526Smckusick while (vp->v_flag & VXLOCK) { 78967526Smckusick vp->v_flag |= VXWANT; 79067526Smckusick sleep((caddr_t)vp, PINOD); 79167526Smckusick } 79267526Smckusick if (vp->v_tag == VT_NON) 79367526Smckusick return (ENOENT); 79467526Smckusick ip = VTOI(vp); 79567526Smckusick if (ip->i_flag & IN_LOCKED) { 79667526Smckusick ip->i_flag |= IN_WANTED; 79767526Smckusick #ifdef DIAGNOSTIC 79867526Smckusick if (p) { 79967526Smckusick if (p->p_pid == ip->i_lockholder) 80067526Smckusick panic("locking against myself"); 80167526Smckusick ip->i_lockwaiter = p->p_pid; 80267526Smckusick } else 80367526Smckusick ip->i_lockwaiter = -1; 80467526Smckusick #endif 80567526Smckusick (void) sleep((caddr_t)ip, PINOD); 80667526Smckusick } 80767526Smckusick #ifdef DIAGNOSTIC 80867526Smckusick ip->i_lockwaiter = 0; 80967526Smckusick if (ip->i_lockholder != 0) 81067526Smckusick panic("lockholder (%d) != 0", ip->i_lockholder); 81167526Smckusick if (p && p->p_pid == 0) 81267526Smckusick printf("locking by process 0\n"); 81367526Smckusick if (p) 81467526Smckusick ip->i_lockholder = p->p_pid; 81567526Smckusick else 81667526Smckusick ip->i_lockholder = -1; 81767526Smckusick #endif 81867526Smckusick ip->i_flag |= IN_LOCKED; 81967379Smkm return (0); 82065789Smckusick } 82165789Smckusick 82265789Smckusick /* 82365789Smckusick * Unlock an inode. 82465789Smckusick */ 82565789Smckusick int 82665855Smckusick cd9660_unlock(ap) 82765789Smckusick struct vop_unlock_args /* { 82865789Smckusick struct vnode *a_vp; 82965789Smckusick } */ *ap; 83065789Smckusick { 83165789Smckusick register struct iso_node *ip = VTOI(ap->a_vp); 83267526Smckusick struct proc *p = curproc; /* XXX */ 83365789Smckusick 83467526Smckusick #ifdef DIAGNOSTIC 83567526Smckusick if ((ip->i_flag & IN_LOCKED) == 0) { 83667526Smckusick vprint("ufs_unlock: unlocked inode", ap->a_vp); 83767526Smckusick panic("ufs_unlock NOT LOCKED"); 83867526Smckusick } 83967526Smckusick if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 && 84067526Smckusick ip->i_lockholder > -1/* && lockcount++ < 100*/) 84167526Smckusick panic("unlocker (%d) != lock holder (%d)", 84267526Smckusick p->p_pid, ip->i_lockholder); 84367526Smckusick ip->i_lockholder = 0; 84467526Smckusick #endif 84567526Smckusick ip->i_flag &= ~IN_LOCKED; 84667526Smckusick if (ip->i_flag & IN_WANTED) { 84767526Smckusick ip->i_flag &= ~IN_WANTED; 84867526Smckusick wakeup((caddr_t)ip); 84967526Smckusick } 85067379Smkm return (0); 85165789Smckusick } 85265789Smckusick 85365789Smckusick /* 85465789Smckusick * Calculate the logical to physical mapping if not done already, 85565789Smckusick * then call the device strategy routine. 85665789Smckusick */ 85765789Smckusick int 85865855Smckusick cd9660_strategy(ap) 85965789Smckusick struct vop_strategy_args /* { 86065789Smckusick struct buf *a_bp; 86165789Smckusick } */ *ap; 86265789Smckusick { 86365789Smckusick register struct buf *bp = ap->a_bp; 86465789Smckusick register struct vnode *vp = bp->b_vp; 86565789Smckusick register struct iso_node *ip; 86665789Smckusick int error; 86765789Smckusick 86865789Smckusick ip = VTOI(vp); 86965789Smckusick if (vp->v_type == VBLK || vp->v_type == VCHR) 87065855Smckusick panic("cd9660_strategy: spec"); 87165789Smckusick if (bp->b_blkno == bp->b_lblkno) { 87265789Smckusick if (error = 87365789Smckusick VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) { 87465789Smckusick bp->b_error = error; 87565789Smckusick bp->b_flags |= B_ERROR; 87665789Smckusick biodone(bp); 87765789Smckusick return (error); 87865789Smckusick } 87965789Smckusick if ((long)bp->b_blkno == -1) 88065789Smckusick clrbuf(bp); 88165789Smckusick } 88265789Smckusick if ((long)bp->b_blkno == -1) { 88365789Smckusick biodone(bp); 88465789Smckusick return (0); 88565789Smckusick } 88665789Smckusick vp = ip->i_devvp; 88765789Smckusick bp->b_dev = vp->v_rdev; 88865789Smckusick VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 88965789Smckusick return (0); 89065789Smckusick } 89165789Smckusick 89265789Smckusick /* 89365789Smckusick * Print out the contents of an inode. 89465789Smckusick */ 89565789Smckusick int 89665855Smckusick cd9660_print(ap) 89765789Smckusick struct vop_print_args /* { 89865789Smckusick struct vnode *a_vp; 89965789Smckusick } */ *ap; 90065789Smckusick { 901*68052Smckusick 90265789Smckusick printf("tag VT_ISOFS, isofs vnode\n"); 90367379Smkm return (0); 90465789Smckusick } 90565789Smckusick 90665789Smckusick /* 907*68052Smckusick * Check for a locked inode. 908*68052Smckusick */ 909*68052Smckusick int 910*68052Smckusick cd9660_islocked(ap) 911*68052Smckusick struct vop_islocked_args /* { 912*68052Smckusick struct vnode *a_vp; 913*68052Smckusick } */ *ap; 914*68052Smckusick { 915*68052Smckusick 916*68052Smckusick if (VTOI(ap->a_vp)->i_flag & IN_LOCKED) 917*68052Smckusick return (1); 918*68052Smckusick return (0); 919*68052Smckusick } 920*68052Smckusick 921*68052Smckusick /* 922*68052Smckusick * Return POSIX pathconf information applicable to cd9660 filesystems. 923*68052Smckusick */ 924*68052Smckusick int 925*68052Smckusick cd9660_pathconf(ap) 926*68052Smckusick struct vop_pathconf_args /* { 927*68052Smckusick struct vnode *a_vp; 928*68052Smckusick int a_name; 929*68052Smckusick register_t *a_retval; 930*68052Smckusick } */ *ap; 931*68052Smckusick { 932*68052Smckusick 933*68052Smckusick switch (ap->a_name) { 934*68052Smckusick case _PC_LINK_MAX: 935*68052Smckusick *ap->a_retval = 1; 936*68052Smckusick return (0); 937*68052Smckusick case _PC_NAME_MAX: 938*68052Smckusick if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP) 939*68052Smckusick *ap->a_retval = NAME_MAX; 940*68052Smckusick else 941*68052Smckusick *ap->a_retval = 37; 942*68052Smckusick return (0); 943*68052Smckusick case _PC_PATH_MAX: 944*68052Smckusick *ap->a_retval = PATH_MAX; 945*68052Smckusick return (0); 946*68052Smckusick case _PC_PIPE_BUF: 947*68052Smckusick *ap->a_retval = PIPE_BUF; 948*68052Smckusick return (0); 949*68052Smckusick case _PC_CHOWN_RESTRICTED: 950*68052Smckusick *ap->a_retval = 1; 951*68052Smckusick return (0); 952*68052Smckusick case _PC_NO_TRUNC: 953*68052Smckusick *ap->a_retval = 1; 954*68052Smckusick return (0); 955*68052Smckusick default: 956*68052Smckusick return (EINVAL); 957*68052Smckusick } 958*68052Smckusick /* NOTREACHED */ 959*68052Smckusick } 960*68052Smckusick 961*68052Smckusick /* 96265789Smckusick * Unsupported operation 96365789Smckusick */ 96465789Smckusick int 96565855Smckusick cd9660_enotsupp() 96665789Smckusick { 96765789Smckusick 96865789Smckusick return (EOPNOTSUPP); 96965789Smckusick } 97065789Smckusick 97165789Smckusick /* 97265789Smckusick * Global vfs data structures for isofs 97365789Smckusick */ 97465855Smckusick #define cd9660_create \ 97565855Smckusick ((int (*) __P((struct vop_create_args *)))cd9660_enotsupp) 97665855Smckusick #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))cd9660_enotsupp) 97765855Smckusick #define cd9660_setattr \ 97865855Smckusick ((int (*) __P((struct vop_setattr_args *)))cd9660_enotsupp) 97965855Smckusick #define cd9660_write ((int (*) __P((struct vop_write_args *)))cd9660_enotsupp) 98067652Smckusick #ifdef NFS 98167652Smckusick int lease_check __P((struct vop_lease_args *)); 98267652Smckusick #define cd9660_lease_check lease_check 98367652Smckusick #else 98467652Smckusick #define cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop) 98567652Smckusick #endif 98665855Smckusick #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 98765855Smckusick #define cd9660_remove \ 98865855Smckusick ((int (*) __P((struct vop_remove_args *)))cd9660_enotsupp) 98965855Smckusick #define cd9660_link ((int (*) __P((struct vop_link_args *)))cd9660_enotsupp) 99065855Smckusick #define cd9660_rename \ 99165855Smckusick ((int (*) __P((struct vop_rename_args *)))cd9660_enotsupp) 99265855Smckusick #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))cd9660_enotsupp) 99365855Smckusick #define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))cd9660_enotsupp) 99465855Smckusick #define cd9660_symlink \ 99565855Smckusick ((int (*) __P((struct vop_symlink_args *)))cd9660_enotsupp) 99665855Smckusick #define cd9660_advlock \ 99765855Smckusick ((int (*) __P((struct vop_advlock_args *)))cd9660_enotsupp) 99865855Smckusick #define cd9660_valloc ((int(*) __P(( \ 99965789Smckusick struct vnode *pvp, \ 100065789Smckusick int mode, \ 100165789Smckusick struct ucred *cred, \ 100265855Smckusick struct vnode **vpp))) cd9660_enotsupp) 100365855Smckusick #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))cd9660_enotsupp) 100465855Smckusick #define cd9660_truncate \ 100565855Smckusick ((int (*) __P((struct vop_truncate_args *)))cd9660_enotsupp) 100665855Smckusick #define cd9660_update \ 100765855Smckusick ((int (*) __P((struct vop_update_args *)))cd9660_enotsupp) 100865855Smckusick #define cd9660_bwrite \ 100965855Smckusick ((int (*) __P((struct vop_bwrite_args *)))cd9660_enotsupp) 101065789Smckusick 101165789Smckusick /* 1012*68052Smckusick * Global vfs data structures for cd9660 101365789Smckusick */ 101465855Smckusick int (**cd9660_vnodeop_p)(); 101565855Smckusick struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { 101665789Smckusick { &vop_default_desc, vn_default_error }, 101765855Smckusick { &vop_lookup_desc, cd9660_lookup }, /* lookup */ 101865855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 101965855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 102065855Smckusick { &vop_open_desc, cd9660_open }, /* open */ 102165855Smckusick { &vop_close_desc, cd9660_close }, /* close */ 102265855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 102365855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 102465855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 102565855Smckusick { &vop_read_desc, cd9660_read }, /* read */ 102665855Smckusick { &vop_write_desc, cd9660_write }, /* write */ 102767652Smckusick { &vop_lease_desc, cd9660_lease_check },/* lease */ 102865855Smckusick { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */ 102965855Smckusick { &vop_select_desc, cd9660_select }, /* select */ 103065855Smckusick { &vop_mmap_desc, cd9660_mmap }, /* mmap */ 103165855Smckusick { &vop_fsync_desc, cd9660_fsync }, /* fsync */ 103265855Smckusick { &vop_seek_desc, cd9660_seek }, /* seek */ 103365855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 103465855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 103565855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 103665855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 103765855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 103865855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 103965855Smckusick { &vop_readdir_desc, cd9660_readdir }, /* readdir */ 104065855Smckusick { &vop_readlink_desc, cd9660_readlink },/* readlink */ 104165855Smckusick { &vop_abortop_desc, cd9660_abortop }, /* abortop */ 104265855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 104365855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 104465855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 104565855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 104665855Smckusick { &vop_bmap_desc, cd9660_bmap }, /* bmap */ 104765855Smckusick { &vop_strategy_desc, cd9660_strategy },/* strategy */ 104865855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 104965855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 105065855Smckusick { &vop_pathconf_desc, cd9660_pathconf },/* pathconf */ 105165855Smckusick { &vop_advlock_desc, cd9660_advlock }, /* advlock */ 105265855Smckusick { &vop_blkatoff_desc, cd9660_blkatoff },/* blkatoff */ 105365855Smckusick { &vop_valloc_desc, cd9660_valloc }, /* valloc */ 105465855Smckusick { &vop_vfree_desc, cd9660_vfree }, /* vfree */ 105565855Smckusick { &vop_truncate_desc, cd9660_truncate },/* truncate */ 105665855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 105765789Smckusick { &vop_bwrite_desc, vn_bwrite }, 105865789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 105965789Smckusick }; 106065855Smckusick struct vnodeopv_desc cd9660_vnodeop_opv_desc = 106165855Smckusick { &cd9660_vnodeop_p, cd9660_vnodeop_entries }; 106265789Smckusick 106365789Smckusick /* 106465789Smckusick * Special device vnode ops 106565789Smckusick */ 106665855Smckusick int (**cd9660_specop_p)(); 106765855Smckusick struct vnodeopv_entry_desc cd9660_specop_entries[] = { 106865789Smckusick { &vop_default_desc, vn_default_error }, 106965789Smckusick { &vop_lookup_desc, spec_lookup }, /* lookup */ 107067891Smckusick { &vop_create_desc, spec_create }, /* create */ 107167891Smckusick { &vop_mknod_desc, spec_mknod }, /* mknod */ 107265789Smckusick { &vop_open_desc, spec_open }, /* open */ 107365789Smckusick { &vop_close_desc, spec_close }, /* close */ 107465855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 107565855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 107665855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 107765789Smckusick { &vop_read_desc, spec_read }, /* read */ 107865789Smckusick { &vop_write_desc, spec_write }, /* write */ 107967652Smckusick { &vop_lease_desc, spec_lease_check }, /* lease */ 108065789Smckusick { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 108165789Smckusick { &vop_select_desc, spec_select }, /* select */ 108265789Smckusick { &vop_mmap_desc, spec_mmap }, /* mmap */ 108365789Smckusick { &vop_fsync_desc, spec_fsync }, /* fsync */ 108465789Smckusick { &vop_seek_desc, spec_seek }, /* seek */ 108567891Smckusick { &vop_remove_desc, spec_remove }, /* remove */ 108667891Smckusick { &vop_link_desc, spec_link }, /* link */ 108767891Smckusick { &vop_rename_desc, spec_rename }, /* rename */ 108867891Smckusick { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 108967891Smckusick { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 109067891Smckusick { &vop_symlink_desc, spec_symlink }, /* symlink */ 109165789Smckusick { &vop_readdir_desc, spec_readdir }, /* readdir */ 109265789Smckusick { &vop_readlink_desc, spec_readlink }, /* readlink */ 109365789Smckusick { &vop_abortop_desc, spec_abortop }, /* abortop */ 109465855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 109565855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 109665855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 109765855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 109865789Smckusick { &vop_bmap_desc, spec_bmap }, /* bmap */ 109967891Smckusick { &vop_strategy_desc, spec_strategy }, /* strategy */ 110065855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 110165855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 110265789Smckusick { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 110365789Smckusick { &vop_advlock_desc, spec_advlock }, /* advlock */ 110465789Smckusick { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 110565789Smckusick { &vop_valloc_desc, spec_valloc }, /* valloc */ 110665789Smckusick { &vop_vfree_desc, spec_vfree }, /* vfree */ 110765789Smckusick { &vop_truncate_desc, spec_truncate }, /* truncate */ 110865855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 110965789Smckusick { &vop_bwrite_desc, vn_bwrite }, 111065789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 111165789Smckusick }; 111265855Smckusick struct vnodeopv_desc cd9660_specop_opv_desc = 111365855Smckusick { &cd9660_specop_p, cd9660_specop_entries }; 111465789Smckusick 111565789Smckusick #ifdef FIFO 111665855Smckusick int (**cd9660_fifoop_p)(); 111765855Smckusick struct vnodeopv_entry_desc cd9660_fifoop_entries[] = { 111865789Smckusick { &vop_default_desc, vn_default_error }, 111965789Smckusick { &vop_lookup_desc, fifo_lookup }, /* lookup */ 112067891Smckusick { &vop_create_desc, fifo_create }, /* create */ 112167891Smckusick { &vop_mknod_desc, fifo_mknod }, /* mknod */ 112265789Smckusick { &vop_open_desc, fifo_open }, /* open */ 112365789Smckusick { &vop_close_desc, fifo_close }, /* close */ 112465855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 112565855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 112665855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 112765789Smckusick { &vop_read_desc, fifo_read }, /* read */ 112865789Smckusick { &vop_write_desc, fifo_write }, /* write */ 112967652Smckusick { &vop_lease_desc, fifo_lease_check }, /* lease */ 113065789Smckusick { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 113165789Smckusick { &vop_select_desc, fifo_select }, /* select */ 113265789Smckusick { &vop_mmap_desc, fifo_mmap }, /* mmap */ 113365789Smckusick { &vop_fsync_desc, fifo_fsync }, /* fsync */ 113465789Smckusick { &vop_seek_desc, fifo_seek }, /* seek */ 113567891Smckusick { &vop_remove_desc, fifo_remove }, /* remove */ 113667891Smckusick { &vop_link_desc, fifo_link } , /* link */ 113767891Smckusick { &vop_rename_desc, fifo_rename }, /* rename */ 113867891Smckusick { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ 113967891Smckusick { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ 114067891Smckusick { &vop_symlink_desc, fifo_symlink }, /* symlink */ 114165789Smckusick { &vop_readdir_desc, fifo_readdir }, /* readdir */ 114265789Smckusick { &vop_readlink_desc, fifo_readlink }, /* readlink */ 114365789Smckusick { &vop_abortop_desc, fifo_abortop }, /* abortop */ 114465855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 114565855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 114665855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 114765855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 114865789Smckusick { &vop_bmap_desc, fifo_bmap }, /* bmap */ 114967891Smckusick { &vop_strategy_desc, fifo_strategy }, /* strategy */ 115065855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 115165855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 115265789Smckusick { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ 115365789Smckusick { &vop_advlock_desc, fifo_advlock }, /* advlock */ 115465789Smckusick { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 115565789Smckusick { &vop_valloc_desc, fifo_valloc }, /* valloc */ 115665789Smckusick { &vop_vfree_desc, fifo_vfree }, /* vfree */ 115765789Smckusick { &vop_truncate_desc, fifo_truncate }, /* truncate */ 115865855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 115965789Smckusick { &vop_bwrite_desc, vn_bwrite }, 116065789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 116165789Smckusick }; 116265855Smckusick struct vnodeopv_desc cd9660_fifoop_opv_desc = 116365855Smckusick { &cd9660_fifoop_p, cd9660_fifoop_entries }; 116465789Smckusick #endif /* FIFO */ 1165