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*67529Smckusick * @(#)cd9660_vnops.c 8.8 (Berkeley) 07/13/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; 5765789Smckusick 5865789Smckusick vp = ndp->ni_vp; 5965789Smckusick ip = VTOI(vp); 6065789Smckusick 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 } 6965789Smckusick 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; 7865789Smckusick 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; 14667379Smkm int i, error; 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; 21565789Smckusick vap->va_flags = 0; 21665789Smckusick vap->va_gen = 1; 21765789Smckusick vap->va_blocksize = ip->i_mnt->logical_block_size; 21865789Smckusick vap->va_bytes = (u_quad_t) ip->i_size; 21965789Smckusick vap->va_type = vp->v_type; 22065789Smckusick return (0); 22165789Smckusick } 22265789Smckusick 22365789Smckusick #if ISO_DEFAULT_BLOCK_SIZE >= NBPG 22465789Smckusick #ifdef DEBUG 22565789Smckusick extern int doclusterread; 22665789Smckusick #else 22765789Smckusick #define doclusterread 1 22865789Smckusick #endif 22965789Smckusick #else 23065789Smckusick /* XXX until cluster routines can handle block sizes less than one page */ 23165789Smckusick #define doclusterread 0 23265789Smckusick #endif 23365789Smckusick 23465789Smckusick /* 23565789Smckusick * Vnode op for reading. 23665789Smckusick */ 23765855Smckusick cd9660_read(ap) 23865789Smckusick struct vop_read_args /* { 23965789Smckusick struct vnode *a_vp; 24065789Smckusick struct uio *a_uio; 24165789Smckusick int a_ioflag; 24265789Smckusick struct ucred *a_cred; 24365789Smckusick } */ *ap; 24465789Smckusick { 24565789Smckusick struct vnode *vp = ap->a_vp; 24665789Smckusick register struct uio *uio = ap->a_uio; 24765789Smckusick register struct iso_node *ip = VTOI(vp); 24865789Smckusick register struct iso_mnt *imp; 24965789Smckusick struct buf *bp; 25065789Smckusick daddr_t lbn, bn, rablock; 25165789Smckusick off_t diff; 25265789Smckusick int rasize, error = 0; 25365789Smckusick long size, n, on; 25465789Smckusick 25565789Smckusick if (uio->uio_resid == 0) 25665789Smckusick return (0); 25765789Smckusick if (uio->uio_offset < 0) 25865789Smckusick return (EINVAL); 25967526Smckusick ip->i_flag |= IN_ACCESS; 26065789Smckusick imp = ip->i_mnt; 26165789Smckusick do { 26265789Smckusick lbn = iso_lblkno(imp, uio->uio_offset); 26365789Smckusick on = iso_blkoff(imp, uio->uio_offset); 26465789Smckusick n = min((unsigned)(imp->logical_block_size - on), 26565789Smckusick uio->uio_resid); 26665789Smckusick diff = (off_t)ip->i_size - uio->uio_offset; 26765789Smckusick if (diff <= 0) 26865789Smckusick return (0); 26965789Smckusick if (diff < n) 27065789Smckusick n = diff; 27165789Smckusick size = iso_blksize(imp, ip, lbn); 27265789Smckusick rablock = lbn + 1; 27365789Smckusick if (doclusterread) { 27465789Smckusick if (iso_lblktosize(imp, rablock) <= ip->i_size) 27565789Smckusick error = cluster_read(vp, (off_t)ip->i_size, 27665789Smckusick lbn, size, NOCRED, &bp); 27765789Smckusick else 27865789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 27965789Smckusick } else { 28065789Smckusick if (vp->v_lastr + 1 == lbn && 28165789Smckusick iso_lblktosize(imp, rablock) < ip->i_size) { 28265789Smckusick rasize = iso_blksize(imp, ip, rablock); 28365789Smckusick error = breadn(vp, lbn, size, &rablock, 28465789Smckusick &rasize, 1, NOCRED, &bp); 28565789Smckusick } else 28665789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 28765789Smckusick } 28865789Smckusick vp->v_lastr = lbn; 28965789Smckusick n = min(n, size - bp->b_resid); 29065789Smckusick if (error) { 29165789Smckusick brelse(bp); 29265789Smckusick return (error); 29365789Smckusick } 29465789Smckusick 29565789Smckusick error = uiomove(bp->b_un.b_addr + on, (int)n, uio); 29665789Smckusick if (n + on == imp->logical_block_size || 29765789Smckusick uio->uio_offset == (off_t)ip->i_size) 29865789Smckusick bp->b_flags |= B_AGE; 29965789Smckusick brelse(bp); 30065789Smckusick } while (error == 0 && uio->uio_resid > 0 && n != 0); 30165789Smckusick return (error); 30265789Smckusick } 30365789Smckusick 30465789Smckusick /* ARGSUSED */ 30565789Smckusick int 30665855Smckusick cd9660_ioctl(ap) 30765789Smckusick struct vop_ioctl_args /* { 30865789Smckusick struct vnode *a_vp; 30965789Smckusick int a_command; 31065789Smckusick caddr_t a_data; 31165789Smckusick int a_fflag; 31265789Smckusick struct ucred *a_cred; 31365789Smckusick struct proc *a_p; 31465789Smckusick } */ *ap; 31565789Smckusick { 31665789Smckusick printf("You did ioctl for isofs !!\n"); 31765789Smckusick return (ENOTTY); 31865789Smckusick } 31965789Smckusick 32065789Smckusick /* ARGSUSED */ 32165789Smckusick int 32265855Smckusick cd9660_select(ap) 32365789Smckusick struct vop_select_args /* { 32465789Smckusick struct vnode *a_vp; 32565789Smckusick int a_which; 32665789Smckusick int a_fflags; 32765789Smckusick struct ucred *a_cred; 32865789Smckusick struct proc *a_p; 32965789Smckusick } */ *ap; 33065789Smckusick { 33165789Smckusick 33265789Smckusick /* 33365789Smckusick * We should really check to see if I/O is possible. 33465789Smckusick */ 33565789Smckusick return (1); 33665789Smckusick } 33765789Smckusick 33865789Smckusick /* 33965789Smckusick * Mmap a file 34065789Smckusick * 34165789Smckusick * NB Currently unsupported. 34265789Smckusick */ 34365789Smckusick /* ARGSUSED */ 34465789Smckusick int 34565855Smckusick cd9660_mmap(ap) 34665789Smckusick struct vop_mmap_args /* { 34765789Smckusick struct vnode *a_vp; 34865789Smckusick int a_fflags; 34965789Smckusick struct ucred *a_cred; 35065789Smckusick struct proc *a_p; 35165789Smckusick } */ *ap; 35265789Smckusick { 35365789Smckusick 35465789Smckusick return (EINVAL); 35565789Smckusick } 35665789Smckusick 35765789Smckusick /* 35865789Smckusick * Seek on a file 35965789Smckusick * 36065789Smckusick * Nothing to do, so just return. 36165789Smckusick */ 36265789Smckusick /* ARGSUSED */ 36365789Smckusick int 36465855Smckusick cd9660_seek(ap) 36565789Smckusick struct vop_seek_args /* { 36665789Smckusick struct vnode *a_vp; 36765789Smckusick off_t a_oldoff; 36865789Smckusick off_t a_newoff; 36965789Smckusick struct ucred *a_cred; 37065789Smckusick } */ *ap; 37165789Smckusick { 37265789Smckusick 37365789Smckusick return (0); 37465789Smckusick } 37565789Smckusick 37665789Smckusick /* 37765789Smckusick * Structure for reading directories 37865789Smckusick */ 37965789Smckusick struct isoreaddir { 38065789Smckusick struct dirent saveent; 38165789Smckusick struct dirent assocent; 38265789Smckusick struct dirent current; 38365789Smckusick off_t saveoff; 38465789Smckusick off_t assocoff; 38565789Smckusick off_t curroff; 38665789Smckusick struct uio *uio; 38765789Smckusick off_t uio_off; 38867370Smckusick int eofflag; 38967370Smckusick u_long *cookies; 39065789Smckusick int ncookies; 39165789Smckusick }; 39265789Smckusick 39365789Smckusick static int 39465789Smckusick iso_uiodir(idp,dp,off) 39565789Smckusick struct isoreaddir *idp; 39665789Smckusick struct dirent *dp; 39765789Smckusick off_t off; 39865789Smckusick { 39965789Smckusick int error; 40065789Smckusick 40165789Smckusick dp->d_name[dp->d_namlen] = 0; 40265789Smckusick dp->d_reclen = DIRSIZ(dp); 40365789Smckusick 40465789Smckusick if (idp->uio->uio_resid < dp->d_reclen) { 40567370Smckusick idp->eofflag = 0; 40667370Smckusick return (-1); 40765789Smckusick } 40865789Smckusick 40967370Smckusick if (idp->cookies) { 41065789Smckusick if (idp->ncookies <= 0) { 41167370Smckusick idp->eofflag = 0; 41267370Smckusick return (-1); 41365789Smckusick } 41465789Smckusick 41567370Smckusick *idp->cookies++ = off; 41665789Smckusick --idp->ncookies; 41765789Smckusick } 41865789Smckusick 41965789Smckusick if (error = uiomove(dp,dp->d_reclen,idp->uio)) 42067370Smckusick return (error); 42165789Smckusick idp->uio_off = off; 42267370Smckusick return (0); 42365789Smckusick } 42465789Smckusick 42565789Smckusick static int 42665789Smckusick iso_shipdir(idp) 42765789Smckusick struct isoreaddir *idp; 42865789Smckusick { 42965789Smckusick struct dirent *dp; 43065789Smckusick int cl, sl, assoc; 43165789Smckusick int error; 43265789Smckusick char *cname, *sname; 43365789Smckusick 43465789Smckusick cl = idp->current.d_namlen; 43565789Smckusick cname = idp->current.d_name; 43665789Smckusick if (assoc = cl > 1 && *cname == ASSOCCHAR) { 43765789Smckusick cl--; 43865789Smckusick cname++; 43965789Smckusick } 44065789Smckusick 44165789Smckusick dp = &idp->saveent; 44265789Smckusick sname = dp->d_name; 44365789Smckusick if (!(sl = dp->d_namlen)) { 44465789Smckusick dp = &idp->assocent; 44565789Smckusick sname = dp->d_name + 1; 44665789Smckusick sl = dp->d_namlen - 1; 44765789Smckusick } 44865789Smckusick if (sl > 0) { 44965789Smckusick if (sl != cl 45065789Smckusick || bcmp(sname,cname,sl)) { 45165789Smckusick if (idp->assocent.d_namlen) { 45265789Smckusick if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) 45367379Smkm return (error); 45465789Smckusick idp->assocent.d_namlen = 0; 45565789Smckusick } 45665789Smckusick if (idp->saveent.d_namlen) { 45765789Smckusick if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) 45867379Smkm return (error); 45965789Smckusick idp->saveent.d_namlen = 0; 46065789Smckusick } 46165789Smckusick } 46265789Smckusick } 46365789Smckusick idp->current.d_reclen = DIRSIZ(&idp->current); 46465789Smckusick if (assoc) { 46565789Smckusick idp->assocoff = idp->curroff; 46665789Smckusick bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); 46765789Smckusick } else { 46865789Smckusick idp->saveoff = idp->curroff; 46965789Smckusick bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); 47065789Smckusick } 47167379Smkm return (0); 47265789Smckusick } 47365789Smckusick 47465789Smckusick /* 47565789Smckusick * Vnode op for readdir 47665789Smckusick */ 47765789Smckusick int 47865855Smckusick cd9660_readdir(ap) 47965789Smckusick struct vop_readdir_args /* { 48065789Smckusick struct vnode *a_vp; 48165789Smckusick struct uio *a_uio; 48265789Smckusick struct ucred *a_cred; 48367370Smckusick int *a_eofflag; 48467370Smckusick u_long *a_cookies; 48567370Smckusick int a_ncookies; 48665789Smckusick } */ *ap; 48765789Smckusick { 48865789Smckusick register struct uio *uio = ap->a_uio; 48965789Smckusick struct isoreaddir *idp; 49065789Smckusick int entryoffsetinblock; 49165789Smckusick int error = 0; 49265789Smckusick int endsearch; 49365789Smckusick struct iso_directory_record *ep; 49465789Smckusick u_short elen; 49565789Smckusick int reclen; 49665789Smckusick struct iso_mnt *imp; 49765789Smckusick struct iso_node *ip; 49865789Smckusick struct buf *bp = NULL; 49965789Smckusick 50065789Smckusick ip = VTOI(ap->a_vp); 50165789Smckusick imp = ip->i_mnt; 50265789Smckusick 503*67529Smckusick MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK); 504*67529Smckusick idp->saveent.d_namlen = idp->assocent.d_namlen = 0; 505*67529Smckusick /* 506*67529Smckusick * XXX 507*67529Smckusick * Is it worth trying to figure out the type? 508*67529Smckusick */ 509*67529Smckusick idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = 510*67529Smckusick DT_UNKNOWN; 51165789Smckusick idp->uio = uio; 51267370Smckusick idp->eofflag = 1; 51367370Smckusick idp->cookies = ap->a_cookies; 51467370Smckusick idp->ncookies = ap->a_ncookies; 51565789Smckusick idp->curroff = uio->uio_offset; 51665789Smckusick 51765789Smckusick entryoffsetinblock = iso_blkoff(imp, idp->curroff); 51865789Smckusick if (entryoffsetinblock != 0) { 51965789Smckusick if (error = iso_blkatoff(ip, idp->curroff, &bp)) { 52065789Smckusick FREE(idp,M_TEMP); 52165789Smckusick return (error); 52265789Smckusick } 52365789Smckusick } 52465789Smckusick 52565789Smckusick endsearch = ip->i_size; 52665789Smckusick 52765789Smckusick while (idp->curroff < endsearch) { 52865789Smckusick /* 52965789Smckusick * If offset is on a block boundary, 53065789Smckusick * read the next directory block. 53165789Smckusick * Release previous if it exists. 53265789Smckusick */ 53365789Smckusick 53465789Smckusick if (iso_blkoff(imp, idp->curroff) == 0) { 53565789Smckusick if (bp != NULL) 53665789Smckusick brelse(bp); 53765789Smckusick if (error = iso_blkatoff(ip, idp->curroff, &bp)) 53865789Smckusick break; 53965789Smckusick entryoffsetinblock = 0; 54065789Smckusick } 54165789Smckusick /* 54265789Smckusick * Get pointer to next entry. 54365789Smckusick */ 54465789Smckusick 54565789Smckusick ep = (struct iso_directory_record *) 54665789Smckusick (bp->b_un.b_addr + entryoffsetinblock); 54765789Smckusick 54865789Smckusick reclen = isonum_711 (ep->length); 54965789Smckusick if (reclen == 0) { 55065789Smckusick /* skip to next block, if any */ 55165789Smckusick idp->curroff = roundup (idp->curroff, 55265789Smckusick imp->logical_block_size); 55365789Smckusick continue; 55465789Smckusick } 55565789Smckusick 55665789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 55765789Smckusick error = EINVAL; 55865789Smckusick /* illegal entry, stop */ 55965789Smckusick break; 56065789Smckusick } 56165789Smckusick 56265789Smckusick if (entryoffsetinblock + reclen > imp->logical_block_size) { 56365789Smckusick error = EINVAL; 56465789Smckusick /* illegal directory, so stop looking */ 56565789Smckusick break; 56665789Smckusick } 56765789Smckusick 56865789Smckusick idp->current.d_namlen = isonum_711 (ep->name_len); 56965789Smckusick if (isonum_711(ep->flags)&2) 57065789Smckusick isodirino(&idp->current.d_fileno,ep,imp); 57165789Smckusick else 57265789Smckusick idp->current.d_fileno = dbtob(bp->b_blkno) + 57365789Smckusick idp->curroff; 57465789Smckusick 57565789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 57665789Smckusick error = EINVAL; 57765789Smckusick /* illegal entry, stop */ 57865789Smckusick break; 57965789Smckusick } 58065789Smckusick 58165789Smckusick idp->curroff += reclen; 58265789Smckusick /* 58365789Smckusick * 58465789Smckusick */ 58565789Smckusick switch (imp->iso_ftype) { 58665789Smckusick case ISO_FTYPE_RRIP: 58767114Smckusick cd9660_rrip_getname(ep,idp->current.d_name, &elen, 58865789Smckusick &idp->current.d_fileno,imp); 58967114Smckusick idp->current.d_namlen = (u_char)elen; 59065789Smckusick if (idp->current.d_namlen) 59165789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 59265789Smckusick break; 59365789Smckusick default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ 59465789Smckusick strcpy(idp->current.d_name,".."); 59565789Smckusick switch (ep->name[0]) { 59665789Smckusick case 0: 59765789Smckusick idp->current.d_namlen = 1; 59865789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 59965789Smckusick break; 60065789Smckusick case 1: 60165789Smckusick idp->current.d_namlen = 2; 60265789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 60365789Smckusick break; 60465789Smckusick default: 60565789Smckusick isofntrans(ep->name,idp->current.d_namlen, 60665789Smckusick idp->current.d_name, &elen, 60765789Smckusick imp->iso_ftype == ISO_FTYPE_9660, 60865789Smckusick isonum_711(ep->flags)&4); 60965789Smckusick idp->current.d_namlen = (u_char)elen; 61065789Smckusick if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 61165789Smckusick error = iso_shipdir(idp); 61265789Smckusick else 61365789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 61465789Smckusick break; 61565789Smckusick } 61665789Smckusick } 61765789Smckusick if (error) 61865789Smckusick break; 61965789Smckusick 62065789Smckusick entryoffsetinblock += reclen; 62165789Smckusick } 62265789Smckusick 62365789Smckusick if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 62465789Smckusick idp->current.d_namlen = 0; 62565789Smckusick error = iso_shipdir(idp); 62665789Smckusick } 62765789Smckusick if (error < 0) 62865789Smckusick error = 0; 62965789Smckusick 63065789Smckusick if (bp) 63165789Smckusick brelse (bp); 63265789Smckusick 63365789Smckusick uio->uio_offset = idp->uio_off; 63467370Smckusick *ap->a_eofflag = idp->eofflag; 63565789Smckusick 63665789Smckusick FREE(idp,M_TEMP); 63765789Smckusick 63865789Smckusick return (error); 63965789Smckusick } 64065789Smckusick 64165789Smckusick /* 64265789Smckusick * Return target name of a symbolic link 64365789Smckusick * Shouldn't we get the parent vnode and read the data from there? 64465855Smckusick * This could eventually result in deadlocks in cd9660_lookup. 64565789Smckusick * But otherwise the block read here is in the block buffer two times. 64665789Smckusick */ 64765789Smckusick typedef struct iso_directory_record ISODIR; 64865789Smckusick typedef struct iso_node ISONODE; 64965789Smckusick typedef struct iso_mnt ISOMNT; 65065789Smckusick int 65165855Smckusick cd9660_readlink(ap) 65265789Smckusick struct vop_readlink_args /* { 65365789Smckusick struct vnode *a_vp; 65465789Smckusick struct uio *a_uio; 65565789Smckusick struct ucred *a_cred; 65665789Smckusick } */ *ap; 65765789Smckusick { 65865789Smckusick ISONODE *ip; 65965789Smckusick ISODIR *dirp; 66065789Smckusick ISOMNT *imp; 66165789Smckusick struct buf *bp; 66265789Smckusick u_short symlen; 66365789Smckusick int error; 66465789Smckusick char *symname; 66565789Smckusick ino_t ino; 66665789Smckusick 66765789Smckusick ip = VTOI(ap->a_vp); 66865789Smckusick imp = ip->i_mnt; 66965789Smckusick 67065789Smckusick if (imp->iso_ftype != ISO_FTYPE_RRIP) 67167379Smkm return (EINVAL); 67265789Smckusick 67365789Smckusick /* 67465789Smckusick * Get parents directory record block that this inode included. 67565789Smckusick */ 67665789Smckusick error = bread(imp->im_devvp, 67767379Smkm (daddr_t)((ip->i_number&~imp->im_bmask) / DEV_BSIZE), 67865789Smckusick imp->logical_block_size, 67965789Smckusick NOCRED, 68065789Smckusick &bp); 68165789Smckusick if (error) { 68265789Smckusick brelse(bp); 68367379Smkm return (EINVAL); 68465789Smckusick } 68565789Smckusick 68665789Smckusick /* 68765789Smckusick * Setup the directory pointer for this inode 68865789Smckusick */ 68965789Smckusick dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask)); 69067379Smkm 69165789Smckusick /* 69265789Smckusick * Just make sure, we have a right one.... 69365789Smckusick * 1: Check not cross boundary on block 69465789Smckusick */ 69565789Smckusick if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 69665789Smckusick > imp->logical_block_size) { 69765789Smckusick brelse(bp); 69867379Smkm return (EINVAL); 69965789Smckusick } 70065789Smckusick 70165789Smckusick /* 70265789Smckusick * Now get a buffer 70365789Smckusick * Abuse a namei buffer for now. 70465789Smckusick */ 70565789Smckusick MALLOC(symname,char *,MAXPATHLEN,M_NAMEI,M_WAITOK); 70665789Smckusick 70765789Smckusick /* 70865789Smckusick * Ok, we just gathering a symbolic name in SL record. 70965789Smckusick */ 71065855Smckusick if (cd9660_rrip_getsymname(dirp,symname,&symlen,imp) == 0) { 71165789Smckusick FREE(symname,M_NAMEI); 71265789Smckusick brelse(bp); 71367379Smkm return (EINVAL); 71465789Smckusick } 71565789Smckusick /* 71665789Smckusick * Don't forget before you leave from home ;-) 71765789Smckusick */ 71865789Smckusick brelse(bp); 71965789Smckusick 72065789Smckusick /* 72165789Smckusick * return with the symbolic name to caller's. 72265789Smckusick */ 72365789Smckusick error = uiomove(symname,symlen,ap->a_uio); 72465789Smckusick 72565789Smckusick FREE(symname,M_NAMEI); 72665789Smckusick 72767379Smkm return (error); 72865789Smckusick } 72965789Smckusick 73065789Smckusick /* 73165789Smckusick * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 73265789Smckusick * done. If a buffer has been saved in anticipation of a CREATE, delete it. 73365789Smckusick */ 73465789Smckusick int 73565855Smckusick cd9660_abortop(ap) 73665789Smckusick struct vop_abortop_args /* { 73765789Smckusick struct vnode *a_dvp; 73865789Smckusick struct componentname *a_cnp; 73965789Smckusick } */ *ap; 74065789Smckusick { 74165789Smckusick if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 74265789Smckusick FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 74367379Smkm return (0); 74465789Smckusick } 74565789Smckusick 74665789Smckusick /* 74765789Smckusick * Lock an inode. 74865789Smckusick */ 74965789Smckusick int 75065855Smckusick cd9660_lock(ap) 75165789Smckusick struct vop_lock_args /* { 75265789Smckusick struct vnode *a_vp; 75365789Smckusick } */ *ap; 75465789Smckusick { 75567526Smckusick register struct vnode *vp = ap->a_vp; 75667526Smckusick register struct iso_node *ip; 75767526Smckusick struct proc *p = curproc; /* XXX */ 75865789Smckusick 75967526Smckusick start: 76067526Smckusick while (vp->v_flag & VXLOCK) { 76167526Smckusick vp->v_flag |= VXWANT; 76267526Smckusick sleep((caddr_t)vp, PINOD); 76367526Smckusick } 76467526Smckusick if (vp->v_tag == VT_NON) 76567526Smckusick return (ENOENT); 76667526Smckusick ip = VTOI(vp); 76767526Smckusick if (ip->i_flag & IN_LOCKED) { 76867526Smckusick ip->i_flag |= IN_WANTED; 76967526Smckusick #ifdef DIAGNOSTIC 77067526Smckusick if (p) { 77167526Smckusick if (p->p_pid == ip->i_lockholder) 77267526Smckusick panic("locking against myself"); 77367526Smckusick ip->i_lockwaiter = p->p_pid; 77467526Smckusick } else 77567526Smckusick ip->i_lockwaiter = -1; 77667526Smckusick #endif 77767526Smckusick (void) sleep((caddr_t)ip, PINOD); 77867526Smckusick } 77967526Smckusick #ifdef DIAGNOSTIC 78067526Smckusick ip->i_lockwaiter = 0; 78167526Smckusick if (ip->i_lockholder != 0) 78267526Smckusick panic("lockholder (%d) != 0", ip->i_lockholder); 78367526Smckusick if (p && p->p_pid == 0) 78467526Smckusick printf("locking by process 0\n"); 78567526Smckusick if (p) 78667526Smckusick ip->i_lockholder = p->p_pid; 78767526Smckusick else 78867526Smckusick ip->i_lockholder = -1; 78967526Smckusick #endif 79067526Smckusick ip->i_flag |= IN_LOCKED; 79167379Smkm return (0); 79265789Smckusick } 79365789Smckusick 79465789Smckusick /* 79565789Smckusick * Unlock an inode. 79665789Smckusick */ 79765789Smckusick int 79865855Smckusick cd9660_unlock(ap) 79965789Smckusick struct vop_unlock_args /* { 80065789Smckusick struct vnode *a_vp; 80165789Smckusick } */ *ap; 80265789Smckusick { 80365789Smckusick register struct iso_node *ip = VTOI(ap->a_vp); 80467526Smckusick struct proc *p = curproc; /* XXX */ 80565789Smckusick 80667526Smckusick #ifdef DIAGNOSTIC 80767526Smckusick if ((ip->i_flag & IN_LOCKED) == 0) { 80867526Smckusick vprint("ufs_unlock: unlocked inode", ap->a_vp); 80967526Smckusick panic("ufs_unlock NOT LOCKED"); 81067526Smckusick } 81167526Smckusick if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 && 81267526Smckusick ip->i_lockholder > -1/* && lockcount++ < 100*/) 81367526Smckusick panic("unlocker (%d) != lock holder (%d)", 81467526Smckusick p->p_pid, ip->i_lockholder); 81567526Smckusick ip->i_lockholder = 0; 81667526Smckusick #endif 81767526Smckusick ip->i_flag &= ~IN_LOCKED; 81867526Smckusick if (ip->i_flag & IN_WANTED) { 81967526Smckusick ip->i_flag &= ~IN_WANTED; 82067526Smckusick wakeup((caddr_t)ip); 82167526Smckusick } 82267379Smkm return (0); 82365789Smckusick } 82465789Smckusick 82565789Smckusick /* 82665789Smckusick * Check for a locked inode. 82765789Smckusick */ 82865789Smckusick int 82965855Smckusick cd9660_islocked(ap) 83065789Smckusick struct vop_islocked_args /* { 83165789Smckusick struct vnode *a_vp; 83265789Smckusick } */ *ap; 83365789Smckusick { 83465789Smckusick 83567526Smckusick if (VTOI(ap->a_vp)->i_flag & IN_LOCKED) 83667379Smkm return (1); 83767379Smkm return (0); 83865789Smckusick } 83965789Smckusick 84065789Smckusick /* 84165789Smckusick * Calculate the logical to physical mapping if not done already, 84265789Smckusick * then call the device strategy routine. 84365789Smckusick */ 84465789Smckusick int 84565855Smckusick cd9660_strategy(ap) 84665789Smckusick struct vop_strategy_args /* { 84765789Smckusick struct buf *a_bp; 84865789Smckusick } */ *ap; 84965789Smckusick { 85065789Smckusick register struct buf *bp = ap->a_bp; 85165789Smckusick register struct vnode *vp = bp->b_vp; 85265789Smckusick register struct iso_node *ip; 85365789Smckusick int error; 85465789Smckusick 85565789Smckusick ip = VTOI(vp); 85665789Smckusick if (vp->v_type == VBLK || vp->v_type == VCHR) 85765855Smckusick panic("cd9660_strategy: spec"); 85865789Smckusick if (bp->b_blkno == bp->b_lblkno) { 85965789Smckusick if (error = 86065789Smckusick VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) { 86165789Smckusick bp->b_error = error; 86265789Smckusick bp->b_flags |= B_ERROR; 86365789Smckusick biodone(bp); 86465789Smckusick return (error); 86565789Smckusick } 86665789Smckusick if ((long)bp->b_blkno == -1) 86765789Smckusick clrbuf(bp); 86865789Smckusick } 86965789Smckusick if ((long)bp->b_blkno == -1) { 87065789Smckusick biodone(bp); 87165789Smckusick return (0); 87265789Smckusick } 87365789Smckusick vp = ip->i_devvp; 87465789Smckusick bp->b_dev = vp->v_rdev; 87565789Smckusick VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 87665789Smckusick return (0); 87765789Smckusick } 87865789Smckusick 87965789Smckusick /* 88065789Smckusick * Print out the contents of an inode. 88165789Smckusick */ 88265789Smckusick int 88365855Smckusick cd9660_print(ap) 88465789Smckusick struct vop_print_args /* { 88565789Smckusick struct vnode *a_vp; 88665789Smckusick } */ *ap; 88765789Smckusick { 88865789Smckusick printf("tag VT_ISOFS, isofs vnode\n"); 88967379Smkm return (0); 89065789Smckusick } 89165789Smckusick 89265789Smckusick /* 89365789Smckusick * Unsupported operation 89465789Smckusick */ 89565789Smckusick int 89665855Smckusick cd9660_enotsupp() 89765789Smckusick { 89865789Smckusick 89965789Smckusick return (EOPNOTSUPP); 90065789Smckusick } 90165789Smckusick 90265789Smckusick /* 90365789Smckusick * Global vfs data structures for isofs 90465789Smckusick */ 90565855Smckusick #define cd9660_create \ 90665855Smckusick ((int (*) __P((struct vop_create_args *)))cd9660_enotsupp) 90765855Smckusick #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))cd9660_enotsupp) 90865855Smckusick #define cd9660_setattr \ 90965855Smckusick ((int (*) __P((struct vop_setattr_args *)))cd9660_enotsupp) 91065855Smckusick #define cd9660_write ((int (*) __P((struct vop_write_args *)))cd9660_enotsupp) 91165855Smckusick #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 91265855Smckusick #define cd9660_remove \ 91365855Smckusick ((int (*) __P((struct vop_remove_args *)))cd9660_enotsupp) 91465855Smckusick #define cd9660_link ((int (*) __P((struct vop_link_args *)))cd9660_enotsupp) 91565855Smckusick #define cd9660_rename \ 91665855Smckusick ((int (*) __P((struct vop_rename_args *)))cd9660_enotsupp) 91765855Smckusick #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))cd9660_enotsupp) 91865855Smckusick #define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))cd9660_enotsupp) 91965855Smckusick #define cd9660_symlink \ 92065855Smckusick ((int (*) __P((struct vop_symlink_args *)))cd9660_enotsupp) 92165855Smckusick #define cd9660_pathconf \ 92265855Smckusick ((int (*) __P((struct vop_pathconf_args *)))cd9660_enotsupp) 92365855Smckusick #define cd9660_advlock \ 92465855Smckusick ((int (*) __P((struct vop_advlock_args *)))cd9660_enotsupp) 92565855Smckusick #define cd9660_blkatoff \ 92665855Smckusick ((int (*) __P((struct vop_blkatoff_args *)))cd9660_enotsupp) 92765855Smckusick #define cd9660_valloc ((int(*) __P(( \ 92865789Smckusick struct vnode *pvp, \ 92965789Smckusick int mode, \ 93065789Smckusick struct ucred *cred, \ 93165855Smckusick struct vnode **vpp))) cd9660_enotsupp) 93265855Smckusick #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))cd9660_enotsupp) 93365855Smckusick #define cd9660_truncate \ 93465855Smckusick ((int (*) __P((struct vop_truncate_args *)))cd9660_enotsupp) 93565855Smckusick #define cd9660_update \ 93665855Smckusick ((int (*) __P((struct vop_update_args *)))cd9660_enotsupp) 93765855Smckusick #define cd9660_bwrite \ 93865855Smckusick ((int (*) __P((struct vop_bwrite_args *)))cd9660_enotsupp) 93965789Smckusick 94065789Smckusick /* 94165789Smckusick * Global vfs data structures for nfs 94265789Smckusick */ 94365855Smckusick int (**cd9660_vnodeop_p)(); 94465855Smckusick struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { 94565789Smckusick { &vop_default_desc, vn_default_error }, 94665855Smckusick { &vop_lookup_desc, cd9660_lookup }, /* lookup */ 94765855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 94865855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 94965855Smckusick { &vop_open_desc, cd9660_open }, /* open */ 95065855Smckusick { &vop_close_desc, cd9660_close }, /* close */ 95165855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 95265855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 95365855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 95465855Smckusick { &vop_read_desc, cd9660_read }, /* read */ 95565855Smckusick { &vop_write_desc, cd9660_write }, /* write */ 95665855Smckusick { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */ 95765855Smckusick { &vop_select_desc, cd9660_select }, /* select */ 95865855Smckusick { &vop_mmap_desc, cd9660_mmap }, /* mmap */ 95965855Smckusick { &vop_fsync_desc, cd9660_fsync }, /* fsync */ 96065855Smckusick { &vop_seek_desc, cd9660_seek }, /* seek */ 96165855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 96265855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 96365855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 96465855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 96565855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 96665855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 96765855Smckusick { &vop_readdir_desc, cd9660_readdir }, /* readdir */ 96865855Smckusick { &vop_readlink_desc, cd9660_readlink },/* readlink */ 96965855Smckusick { &vop_abortop_desc, cd9660_abortop }, /* abortop */ 97065855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 97165855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 97265855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 97365855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 97465855Smckusick { &vop_bmap_desc, cd9660_bmap }, /* bmap */ 97565855Smckusick { &vop_strategy_desc, cd9660_strategy },/* strategy */ 97665855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 97765855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 97865855Smckusick { &vop_pathconf_desc, cd9660_pathconf },/* pathconf */ 97965855Smckusick { &vop_advlock_desc, cd9660_advlock }, /* advlock */ 98065855Smckusick { &vop_blkatoff_desc, cd9660_blkatoff },/* blkatoff */ 98165855Smckusick { &vop_valloc_desc, cd9660_valloc }, /* valloc */ 98265855Smckusick { &vop_vfree_desc, cd9660_vfree }, /* vfree */ 98365855Smckusick { &vop_truncate_desc, cd9660_truncate },/* truncate */ 98465855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 98565789Smckusick { &vop_bwrite_desc, vn_bwrite }, 98665789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 98765789Smckusick }; 98865855Smckusick struct vnodeopv_desc cd9660_vnodeop_opv_desc = 98965855Smckusick { &cd9660_vnodeop_p, cd9660_vnodeop_entries }; 99065789Smckusick 99165789Smckusick /* 99265789Smckusick * Special device vnode ops 99365789Smckusick */ 99465855Smckusick int (**cd9660_specop_p)(); 99565855Smckusick struct vnodeopv_entry_desc cd9660_specop_entries[] = { 99665789Smckusick { &vop_default_desc, vn_default_error }, 99765789Smckusick { &vop_lookup_desc, spec_lookup }, /* lookup */ 99865855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 99965855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 100065789Smckusick { &vop_open_desc, spec_open }, /* open */ 100165789Smckusick { &vop_close_desc, spec_close }, /* close */ 100265855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 100365855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 100465855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 100565789Smckusick { &vop_read_desc, spec_read }, /* read */ 100665789Smckusick { &vop_write_desc, spec_write }, /* write */ 100765789Smckusick { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 100865789Smckusick { &vop_select_desc, spec_select }, /* select */ 100965789Smckusick { &vop_mmap_desc, spec_mmap }, /* mmap */ 101065789Smckusick { &vop_fsync_desc, spec_fsync }, /* fsync */ 101165789Smckusick { &vop_seek_desc, spec_seek }, /* seek */ 101265855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 101365855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 101465855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 101565855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 101665855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 101765855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 101865789Smckusick { &vop_readdir_desc, spec_readdir }, /* readdir */ 101965789Smckusick { &vop_readlink_desc, spec_readlink }, /* readlink */ 102065789Smckusick { &vop_abortop_desc, spec_abortop }, /* abortop */ 102165855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 102265855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 102365855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 102465855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 102565789Smckusick { &vop_bmap_desc, spec_bmap }, /* bmap */ 102665789Smckusick /* XXX strategy: panics, should be notsupp instead? */ 102765855Smckusick { &vop_strategy_desc, cd9660_strategy },/* strategy */ 102865855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 102965855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 103065789Smckusick { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 103165789Smckusick { &vop_advlock_desc, spec_advlock }, /* advlock */ 103265789Smckusick { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 103365789Smckusick { &vop_valloc_desc, spec_valloc }, /* valloc */ 103465789Smckusick { &vop_vfree_desc, spec_vfree }, /* vfree */ 103565789Smckusick { &vop_truncate_desc, spec_truncate }, /* truncate */ 103665855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 103765789Smckusick { &vop_bwrite_desc, vn_bwrite }, 103865789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 103965789Smckusick }; 104065855Smckusick struct vnodeopv_desc cd9660_specop_opv_desc = 104165855Smckusick { &cd9660_specop_p, cd9660_specop_entries }; 104265789Smckusick 104365789Smckusick #ifdef FIFO 104465855Smckusick int (**cd9660_fifoop_p)(); 104565855Smckusick struct vnodeopv_entry_desc cd9660_fifoop_entries[] = { 104665789Smckusick { &vop_default_desc, vn_default_error }, 104765789Smckusick { &vop_lookup_desc, fifo_lookup }, /* lookup */ 104865855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 104965855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 105065789Smckusick { &vop_open_desc, fifo_open }, /* open */ 105165789Smckusick { &vop_close_desc, fifo_close }, /* close */ 105265855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 105365855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 105465855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 105565789Smckusick { &vop_read_desc, fifo_read }, /* read */ 105665789Smckusick { &vop_write_desc, fifo_write }, /* write */ 105765789Smckusick { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 105865789Smckusick { &vop_select_desc, fifo_select }, /* select */ 105965789Smckusick { &vop_mmap_desc, fifo_mmap }, /* mmap */ 106065789Smckusick { &vop_fsync_desc, fifo_fsync }, /* fsync */ 106165789Smckusick { &vop_seek_desc, fifo_seek }, /* seek */ 106265855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 106365855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 106465855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 106565855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 106665855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 106765855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 106865789Smckusick { &vop_readdir_desc, fifo_readdir }, /* readdir */ 106965789Smckusick { &vop_readlink_desc, fifo_readlink }, /* readlink */ 107065789Smckusick { &vop_abortop_desc, fifo_abortop }, /* abortop */ 107165855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 107265855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 107365855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 107465855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 107565789Smckusick { &vop_bmap_desc, fifo_bmap }, /* bmap */ 107665789Smckusick { &vop_strategy_desc, fifo_badop }, /* strategy */ 107765855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 107865855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 107965789Smckusick { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ 108065789Smckusick { &vop_advlock_desc, fifo_advlock }, /* advlock */ 108165789Smckusick { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 108265789Smckusick { &vop_valloc_desc, fifo_valloc }, /* valloc */ 108365789Smckusick { &vop_vfree_desc, fifo_vfree }, /* vfree */ 108465789Smckusick { &vop_truncate_desc, fifo_truncate }, /* truncate */ 108565855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 108665789Smckusick { &vop_bwrite_desc, vn_bwrite }, 108765789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 108865789Smckusick }; 108965855Smckusick struct vnodeopv_desc cd9660_fifoop_opv_desc = 109065855Smckusick { &cd9660_fifoop_p, cd9660_fifoop_entries }; 109165789Smckusick #endif /* FIFO */ 1092