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*67114Smckusick * @(#)cd9660_vnops.c 8.4 (Berkeley) 05/09/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); 5165789Smckusick 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); 6765789Smckusick 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 { 14265789Smckusick return (0); 14365789Smckusick } 14465789Smckusick 14565855Smckusick cd9660_getattr(ap) 14665789Smckusick struct vop_getattr_args /* { 14765789Smckusick struct vnode *a_vp; 14865789Smckusick struct vattr *a_vap; 14965789Smckusick struct ucred *a_cred; 15065789Smckusick struct proc *a_p; 15165789Smckusick } */ *ap; 15265789Smckusick 15365789Smckusick { 15465789Smckusick struct vnode *vp = ap->a_vp; 15565789Smckusick register struct vattr *vap = ap->a_vap; 15665789Smckusick register struct iso_node *ip = VTOI(vp); 15765789Smckusick int i; 15865789Smckusick 15965789Smckusick vap->va_fsid = ip->i_dev; 16065789Smckusick vap->va_fileid = ip->i_number; 16165789Smckusick 16265789Smckusick vap->va_mode = ip->inode.iso_mode; 16365789Smckusick vap->va_nlink = ip->inode.iso_links; 16465789Smckusick vap->va_uid = ip->inode.iso_uid; 16565789Smckusick vap->va_gid = ip->inode.iso_gid; 16665789Smckusick vap->va_atime = ip->inode.iso_atime; 16765789Smckusick vap->va_mtime = ip->inode.iso_mtime; 16865789Smckusick vap->va_ctime = ip->inode.iso_ctime; 16965789Smckusick vap->va_rdev = ip->inode.iso_rdev; 17065789Smckusick 17165789Smckusick vap->va_size = (u_quad_t) ip->i_size; 17265789Smckusick vap->va_flags = 0; 17365789Smckusick vap->va_gen = 1; 17465789Smckusick vap->va_blocksize = ip->i_mnt->logical_block_size; 17565789Smckusick vap->va_bytes = (u_quad_t) ip->i_size; 17665789Smckusick vap->va_type = vp->v_type; 17765789Smckusick return (0); 17865789Smckusick } 17965789Smckusick 18065789Smckusick #if ISO_DEFAULT_BLOCK_SIZE >= NBPG 18165789Smckusick #ifdef DEBUG 18265789Smckusick extern int doclusterread; 18365789Smckusick #else 18465789Smckusick #define doclusterread 1 18565789Smckusick #endif 18665789Smckusick #else 18765789Smckusick /* XXX until cluster routines can handle block sizes less than one page */ 18865789Smckusick #define doclusterread 0 18965789Smckusick #endif 19065789Smckusick 19165789Smckusick /* 19265789Smckusick * Vnode op for reading. 19365789Smckusick */ 19465855Smckusick cd9660_read(ap) 19565789Smckusick struct vop_read_args /* { 19665789Smckusick struct vnode *a_vp; 19765789Smckusick struct uio *a_uio; 19865789Smckusick int a_ioflag; 19965789Smckusick struct ucred *a_cred; 20065789Smckusick } */ *ap; 20165789Smckusick { 20265789Smckusick struct vnode *vp = ap->a_vp; 20365789Smckusick register struct uio *uio = ap->a_uio; 20465789Smckusick register struct iso_node *ip = VTOI(vp); 20565789Smckusick register struct iso_mnt *imp; 20665789Smckusick struct buf *bp; 20765789Smckusick daddr_t lbn, bn, rablock; 20865789Smckusick off_t diff; 20965789Smckusick int rasize, error = 0; 21065789Smckusick long size, n, on; 21165789Smckusick 21265789Smckusick if (uio->uio_resid == 0) 21365789Smckusick return (0); 21465789Smckusick if (uio->uio_offset < 0) 21565789Smckusick return (EINVAL); 21665789Smckusick ip->i_flag |= IACC; 21765789Smckusick imp = ip->i_mnt; 21865789Smckusick do { 21965789Smckusick lbn = iso_lblkno(imp, uio->uio_offset); 22065789Smckusick on = iso_blkoff(imp, uio->uio_offset); 22165789Smckusick n = min((unsigned)(imp->logical_block_size - on), 22265789Smckusick uio->uio_resid); 22365789Smckusick diff = (off_t)ip->i_size - uio->uio_offset; 22465789Smckusick if (diff <= 0) 22565789Smckusick return (0); 22665789Smckusick if (diff < n) 22765789Smckusick n = diff; 22865789Smckusick size = iso_blksize(imp, ip, lbn); 22965789Smckusick rablock = lbn + 1; 23065789Smckusick if (doclusterread) { 23165789Smckusick if (iso_lblktosize(imp, rablock) <= ip->i_size) 23265789Smckusick error = cluster_read(vp, (off_t)ip->i_size, 23365789Smckusick lbn, size, NOCRED, &bp); 23465789Smckusick else 23565789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 23665789Smckusick } else { 23765789Smckusick if (vp->v_lastr + 1 == lbn && 23865789Smckusick iso_lblktosize(imp, rablock) < ip->i_size) { 23965789Smckusick rasize = iso_blksize(imp, ip, rablock); 24065789Smckusick error = breadn(vp, lbn, size, &rablock, 24165789Smckusick &rasize, 1, NOCRED, &bp); 24265789Smckusick } else 24365789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 24465789Smckusick } 24565789Smckusick vp->v_lastr = lbn; 24665789Smckusick n = min(n, size - bp->b_resid); 24765789Smckusick if (error) { 24865789Smckusick brelse(bp); 24965789Smckusick return (error); 25065789Smckusick } 25165789Smckusick 25265789Smckusick error = uiomove(bp->b_un.b_addr + on, (int)n, uio); 25365789Smckusick if (n + on == imp->logical_block_size || 25465789Smckusick uio->uio_offset == (off_t)ip->i_size) 25565789Smckusick bp->b_flags |= B_AGE; 25665789Smckusick brelse(bp); 25765789Smckusick } while (error == 0 && uio->uio_resid > 0 && n != 0); 25865789Smckusick return (error); 25965789Smckusick } 26065789Smckusick 26165789Smckusick /* ARGSUSED */ 26265789Smckusick int 26365855Smckusick cd9660_ioctl(ap) 26465789Smckusick struct vop_ioctl_args /* { 26565789Smckusick struct vnode *a_vp; 26665789Smckusick int a_command; 26765789Smckusick caddr_t a_data; 26865789Smckusick int a_fflag; 26965789Smckusick struct ucred *a_cred; 27065789Smckusick struct proc *a_p; 27165789Smckusick } */ *ap; 27265789Smckusick { 27365789Smckusick printf("You did ioctl for isofs !!\n"); 27465789Smckusick return (ENOTTY); 27565789Smckusick } 27665789Smckusick 27765789Smckusick /* ARGSUSED */ 27865789Smckusick int 27965855Smckusick cd9660_select(ap) 28065789Smckusick struct vop_select_args /* { 28165789Smckusick struct vnode *a_vp; 28265789Smckusick int a_which; 28365789Smckusick int a_fflags; 28465789Smckusick struct ucred *a_cred; 28565789Smckusick struct proc *a_p; 28665789Smckusick } */ *ap; 28765789Smckusick { 28865789Smckusick 28965789Smckusick /* 29065789Smckusick * We should really check to see if I/O is possible. 29165789Smckusick */ 29265789Smckusick return (1); 29365789Smckusick } 29465789Smckusick 29565789Smckusick /* 29665789Smckusick * Mmap a file 29765789Smckusick * 29865789Smckusick * NB Currently unsupported. 29965789Smckusick */ 30065789Smckusick /* ARGSUSED */ 30165789Smckusick int 30265855Smckusick cd9660_mmap(ap) 30365789Smckusick struct vop_mmap_args /* { 30465789Smckusick struct vnode *a_vp; 30565789Smckusick int a_fflags; 30665789Smckusick struct ucred *a_cred; 30765789Smckusick struct proc *a_p; 30865789Smckusick } */ *ap; 30965789Smckusick { 31065789Smckusick 31165789Smckusick return (EINVAL); 31265789Smckusick } 31365789Smckusick 31465789Smckusick /* 31565789Smckusick * Seek on a file 31665789Smckusick * 31765789Smckusick * Nothing to do, so just return. 31865789Smckusick */ 31965789Smckusick /* ARGSUSED */ 32065789Smckusick int 32165855Smckusick cd9660_seek(ap) 32265789Smckusick struct vop_seek_args /* { 32365789Smckusick struct vnode *a_vp; 32465789Smckusick off_t a_oldoff; 32565789Smckusick off_t a_newoff; 32665789Smckusick struct ucred *a_cred; 32765789Smckusick } */ *ap; 32865789Smckusick { 32965789Smckusick 33065789Smckusick return (0); 33165789Smckusick } 33265789Smckusick 33365789Smckusick /* 33465789Smckusick * Structure for reading directories 33565789Smckusick */ 33665789Smckusick struct isoreaddir { 33765789Smckusick struct dirent saveent; 33865789Smckusick struct dirent assocent; 33965789Smckusick struct dirent current; 34065789Smckusick off_t saveoff; 34165789Smckusick off_t assocoff; 34265789Smckusick off_t curroff; 34365789Smckusick struct uio *uio; 34465789Smckusick off_t uio_off; 34565789Smckusick u_int *cookiep; 34665789Smckusick int ncookies; 34765789Smckusick int eof; 34865789Smckusick }; 34965789Smckusick 35065789Smckusick static int 35165789Smckusick iso_uiodir(idp,dp,off) 35265789Smckusick struct isoreaddir *idp; 35365789Smckusick struct dirent *dp; 35465789Smckusick off_t off; 35565789Smckusick { 35665789Smckusick int error; 35765789Smckusick 35865789Smckusick dp->d_name[dp->d_namlen] = 0; 35965789Smckusick dp->d_reclen = DIRSIZ(dp); 36065789Smckusick 36165789Smckusick if (idp->uio->uio_resid < dp->d_reclen) { 36265789Smckusick idp->eof = 0; 36365789Smckusick return -1; 36465789Smckusick } 36565789Smckusick 36665789Smckusick if (idp->cookiep) { 36765789Smckusick if (idp->ncookies <= 0) { 36865789Smckusick idp->eof = 0; 36965789Smckusick return -1; 37065789Smckusick } 37165789Smckusick 37265789Smckusick *idp->cookiep++ = off; 37365789Smckusick --idp->ncookies; 37465789Smckusick } 37565789Smckusick 37665789Smckusick if (error = uiomove(dp,dp->d_reclen,idp->uio)) 37765789Smckusick return error; 37865789Smckusick idp->uio_off = off; 37965789Smckusick return 0; 38065789Smckusick } 38165789Smckusick 38265789Smckusick static int 38365789Smckusick iso_shipdir(idp) 38465789Smckusick struct isoreaddir *idp; 38565789Smckusick { 38665789Smckusick struct dirent *dp; 38765789Smckusick int cl, sl, assoc; 38865789Smckusick int error; 38965789Smckusick char *cname, *sname; 39065789Smckusick 39165789Smckusick cl = idp->current.d_namlen; 39265789Smckusick cname = idp->current.d_name; 39365789Smckusick if (assoc = cl > 1 && *cname == ASSOCCHAR) { 39465789Smckusick cl--; 39565789Smckusick cname++; 39665789Smckusick } 39765789Smckusick 39865789Smckusick dp = &idp->saveent; 39965789Smckusick sname = dp->d_name; 40065789Smckusick if (!(sl = dp->d_namlen)) { 40165789Smckusick dp = &idp->assocent; 40265789Smckusick sname = dp->d_name + 1; 40365789Smckusick sl = dp->d_namlen - 1; 40465789Smckusick } 40565789Smckusick if (sl > 0) { 40665789Smckusick if (sl != cl 40765789Smckusick || bcmp(sname,cname,sl)) { 40865789Smckusick if (idp->assocent.d_namlen) { 40965789Smckusick if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) 41065789Smckusick return error; 41165789Smckusick idp->assocent.d_namlen = 0; 41265789Smckusick } 41365789Smckusick if (idp->saveent.d_namlen) { 41465789Smckusick if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) 41565789Smckusick return error; 41665789Smckusick idp->saveent.d_namlen = 0; 41765789Smckusick } 41865789Smckusick } 41965789Smckusick } 42065789Smckusick idp->current.d_reclen = DIRSIZ(&idp->current); 42165789Smckusick if (assoc) { 42265789Smckusick idp->assocoff = idp->curroff; 42365789Smckusick bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); 42465789Smckusick } else { 42565789Smckusick idp->saveoff = idp->curroff; 42665789Smckusick bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); 42765789Smckusick } 42865789Smckusick return 0; 42965789Smckusick } 43065789Smckusick 43165789Smckusick /* 43265789Smckusick * Vnode op for readdir 43365789Smckusick * XXX make sure everything still works now that eofflagp and cookiep 43465789Smckusick * are no longer args. 43565789Smckusick */ 43665789Smckusick int 43765855Smckusick cd9660_readdir(ap) 43865789Smckusick struct vop_readdir_args /* { 43965789Smckusick struct vnode *a_vp; 44065789Smckusick struct uio *a_uio; 44165789Smckusick struct ucred *a_cred; 44265789Smckusick } */ *ap; 44365789Smckusick { 44465789Smckusick register struct uio *uio = ap->a_uio; 44565789Smckusick struct isoreaddir *idp; 44665789Smckusick int entryoffsetinblock; 44765789Smckusick int error = 0; 44865789Smckusick int endsearch; 44965789Smckusick struct iso_directory_record *ep; 45065789Smckusick u_short elen; 45165789Smckusick int reclen; 45265789Smckusick struct iso_mnt *imp; 45365789Smckusick struct iso_node *ip; 45465789Smckusick struct buf *bp = NULL; 45565789Smckusick 45665789Smckusick ip = VTOI(ap->a_vp); 45765789Smckusick imp = ip->i_mnt; 45865789Smckusick 45965789Smckusick MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK); 46065789Smckusick idp->saveent.d_namlen = 0; 46165789Smckusick idp->assocent.d_namlen = 0; 46265789Smckusick idp->uio = uio; 46365789Smckusick #if 0 46465789Smckusick idp->cookiep = cookies; 46565789Smckusick idp->ncookies = ncookies; 46665789Smckusick idp->eof = 1; 46765789Smckusick #else 46865789Smckusick idp->cookiep = 0; 46965789Smckusick #endif 47065789Smckusick idp->curroff = uio->uio_offset; 47165789Smckusick 47265789Smckusick entryoffsetinblock = iso_blkoff(imp, idp->curroff); 47365789Smckusick if (entryoffsetinblock != 0) { 47465789Smckusick if (error = iso_blkatoff(ip, idp->curroff, &bp)) { 47565789Smckusick FREE(idp,M_TEMP); 47665789Smckusick return (error); 47765789Smckusick } 47865789Smckusick } 47965789Smckusick 48065789Smckusick endsearch = ip->i_size; 48165789Smckusick 48265789Smckusick while (idp->curroff < endsearch) { 48365789Smckusick /* 48465789Smckusick * If offset is on a block boundary, 48565789Smckusick * read the next directory block. 48665789Smckusick * Release previous if it exists. 48765789Smckusick */ 48865789Smckusick 48965789Smckusick if (iso_blkoff(imp, idp->curroff) == 0) { 49065789Smckusick if (bp != NULL) 49165789Smckusick brelse(bp); 49265789Smckusick if (error = iso_blkatoff(ip, idp->curroff, &bp)) 49365789Smckusick break; 49465789Smckusick entryoffsetinblock = 0; 49565789Smckusick } 49665789Smckusick /* 49765789Smckusick * Get pointer to next entry. 49865789Smckusick */ 49965789Smckusick 50065789Smckusick ep = (struct iso_directory_record *) 50165789Smckusick (bp->b_un.b_addr + entryoffsetinblock); 50265789Smckusick 50365789Smckusick reclen = isonum_711 (ep->length); 50465789Smckusick if (reclen == 0) { 50565789Smckusick /* skip to next block, if any */ 50665789Smckusick idp->curroff = roundup (idp->curroff, 50765789Smckusick imp->logical_block_size); 50865789Smckusick continue; 50965789Smckusick } 51065789Smckusick 51165789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 51265789Smckusick error = EINVAL; 51365789Smckusick /* illegal entry, stop */ 51465789Smckusick break; 51565789Smckusick } 51665789Smckusick 51765789Smckusick if (entryoffsetinblock + reclen > imp->logical_block_size) { 51865789Smckusick error = EINVAL; 51965789Smckusick /* illegal directory, so stop looking */ 52065789Smckusick break; 52165789Smckusick } 52265789Smckusick 52365789Smckusick idp->current.d_namlen = isonum_711 (ep->name_len); 52465789Smckusick if (isonum_711(ep->flags)&2) 52565789Smckusick isodirino(&idp->current.d_fileno,ep,imp); 52665789Smckusick else 52765789Smckusick idp->current.d_fileno = dbtob(bp->b_blkno) + 52865789Smckusick idp->curroff; 52965789Smckusick 53065789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 53165789Smckusick error = EINVAL; 53265789Smckusick /* illegal entry, stop */ 53365789Smckusick break; 53465789Smckusick } 53565789Smckusick 53665789Smckusick idp->curroff += reclen; 53765789Smckusick /* 53865789Smckusick * 53965789Smckusick */ 54065789Smckusick switch (imp->iso_ftype) { 54165789Smckusick case ISO_FTYPE_RRIP: 542*67114Smckusick cd9660_rrip_getname(ep,idp->current.d_name, &elen, 54365789Smckusick &idp->current.d_fileno,imp); 544*67114Smckusick idp->current.d_namlen = (u_char)elen; 54565789Smckusick if (idp->current.d_namlen) 54665789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 54765789Smckusick break; 54865789Smckusick default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ 54965789Smckusick strcpy(idp->current.d_name,".."); 55065789Smckusick switch (ep->name[0]) { 55165789Smckusick case 0: 55265789Smckusick idp->current.d_namlen = 1; 55365789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 55465789Smckusick break; 55565789Smckusick case 1: 55665789Smckusick idp->current.d_namlen = 2; 55765789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 55865789Smckusick break; 55965789Smckusick default: 56065789Smckusick isofntrans(ep->name,idp->current.d_namlen, 56165789Smckusick idp->current.d_name, &elen, 56265789Smckusick imp->iso_ftype == ISO_FTYPE_9660, 56365789Smckusick isonum_711(ep->flags)&4); 56465789Smckusick idp->current.d_namlen = (u_char)elen; 56565789Smckusick if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 56665789Smckusick error = iso_shipdir(idp); 56765789Smckusick else 56865789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 56965789Smckusick break; 57065789Smckusick } 57165789Smckusick } 57265789Smckusick if (error) 57365789Smckusick break; 57465789Smckusick 57565789Smckusick entryoffsetinblock += reclen; 57665789Smckusick } 57765789Smckusick 57865789Smckusick if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 57965789Smckusick idp->current.d_namlen = 0; 58065789Smckusick error = iso_shipdir(idp); 58165789Smckusick } 58265789Smckusick if (error < 0) 58365789Smckusick error = 0; 58465789Smckusick 58565789Smckusick if (bp) 58665789Smckusick brelse (bp); 58765789Smckusick 58865789Smckusick uio->uio_offset = idp->uio_off; 58965789Smckusick #if 0 59065789Smckusick *eofflagp = idp->eof; 59165789Smckusick #endif 59265789Smckusick 59365789Smckusick FREE(idp,M_TEMP); 59465789Smckusick 59565789Smckusick return (error); 59665789Smckusick } 59765789Smckusick 59865789Smckusick /* 59965789Smckusick * Return target name of a symbolic link 60065789Smckusick * Shouldn't we get the parent vnode and read the data from there? 60165855Smckusick * This could eventually result in deadlocks in cd9660_lookup. 60265789Smckusick * But otherwise the block read here is in the block buffer two times. 60365789Smckusick */ 60465789Smckusick typedef struct iso_directory_record ISODIR; 60565789Smckusick typedef struct iso_node ISONODE; 60665789Smckusick typedef struct iso_mnt ISOMNT; 60765789Smckusick int 60865855Smckusick cd9660_readlink(ap) 60965789Smckusick struct vop_readlink_args /* { 61065789Smckusick struct vnode *a_vp; 61165789Smckusick struct uio *a_uio; 61265789Smckusick struct ucred *a_cred; 61365789Smckusick } */ *ap; 61465789Smckusick { 61565789Smckusick ISONODE *ip; 61665789Smckusick ISODIR *dirp; 61765789Smckusick ISOMNT *imp; 61865789Smckusick struct buf *bp; 61965789Smckusick u_short symlen; 62065789Smckusick int error; 62165789Smckusick char *symname; 62265789Smckusick ino_t ino; 62365789Smckusick 62465789Smckusick ip = VTOI(ap->a_vp); 62565789Smckusick imp = ip->i_mnt; 62665789Smckusick 62765789Smckusick if (imp->iso_ftype != ISO_FTYPE_RRIP) 62865789Smckusick return EINVAL; 62965789Smckusick 63065789Smckusick /* 63165789Smckusick * Get parents directory record block that this inode included. 63265789Smckusick */ 63365789Smckusick error = bread(imp->im_devvp, 63465789Smckusick (daddr_t)(ip->i_number / DEV_BSIZE), 63565789Smckusick imp->logical_block_size, 63665789Smckusick NOCRED, 63765789Smckusick &bp); 63865789Smckusick if (error) { 63965789Smckusick brelse(bp); 64065789Smckusick return EINVAL; 64165789Smckusick } 64265789Smckusick 64365789Smckusick /* 64465789Smckusick * Setup the directory pointer for this inode 64565789Smckusick */ 64665789Smckusick dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask)); 64765789Smckusick #ifdef DEBUG 64865789Smckusick printf("lbn=%d,off=%d,bsize=%d,DEV_BSIZE=%d, dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n", 64965789Smckusick (daddr_t)(ip->i_number >> imp->im_bshift), 65065789Smckusick ip->i_number & imp->im_bmask, 65165789Smckusick imp->logical_block_size, 65265789Smckusick DEV_BSIZE, 65365789Smckusick dirp, 65465789Smckusick bp->b_un.b_addr, 65565789Smckusick ip->i_number, 65665789Smckusick ip->i_number & imp->im_bmask ); 65765789Smckusick #endif 65865789Smckusick 65965789Smckusick /* 66065789Smckusick * Just make sure, we have a right one.... 66165789Smckusick * 1: Check not cross boundary on block 66265789Smckusick */ 66365789Smckusick if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 66465789Smckusick > imp->logical_block_size) { 66565789Smckusick brelse(bp); 66665789Smckusick return EINVAL; 66765789Smckusick } 66865789Smckusick 66965789Smckusick /* 67065789Smckusick * Now get a buffer 67165789Smckusick * Abuse a namei buffer for now. 67265789Smckusick */ 67365789Smckusick MALLOC(symname,char *,MAXPATHLEN,M_NAMEI,M_WAITOK); 67465789Smckusick 67565789Smckusick /* 67665789Smckusick * Ok, we just gathering a symbolic name in SL record. 67765789Smckusick */ 67865855Smckusick if (cd9660_rrip_getsymname(dirp,symname,&symlen,imp) == 0) { 67965789Smckusick FREE(symname,M_NAMEI); 68065789Smckusick brelse(bp); 68165789Smckusick return EINVAL; 68265789Smckusick } 68365789Smckusick /* 68465789Smckusick * Don't forget before you leave from home ;-) 68565789Smckusick */ 68665789Smckusick brelse(bp); 68765789Smckusick 68865789Smckusick /* 68965789Smckusick * return with the symbolic name to caller's. 69065789Smckusick */ 69165789Smckusick error = uiomove(symname,symlen,ap->a_uio); 69265789Smckusick 69365789Smckusick FREE(symname,M_NAMEI); 69465789Smckusick 69565789Smckusick return error; 69665789Smckusick } 69765789Smckusick 69865789Smckusick /* 69965789Smckusick * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 70065789Smckusick * done. If a buffer has been saved in anticipation of a CREATE, delete it. 70165789Smckusick */ 70265789Smckusick int 70365855Smckusick cd9660_abortop(ap) 70465789Smckusick struct vop_abortop_args /* { 70565789Smckusick struct vnode *a_dvp; 70665789Smckusick struct componentname *a_cnp; 70765789Smckusick } */ *ap; 70865789Smckusick { 70965789Smckusick if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 71065789Smckusick FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 71165789Smckusick return 0; 71265789Smckusick } 71365789Smckusick 71465789Smckusick /* 71565789Smckusick * Lock an inode. 71665789Smckusick */ 71765789Smckusick int 71865855Smckusick cd9660_lock(ap) 71965789Smckusick struct vop_lock_args /* { 72065789Smckusick struct vnode *a_vp; 72165789Smckusick } */ *ap; 72265789Smckusick { 72365789Smckusick register struct iso_node *ip = VTOI(ap->a_vp); 72465789Smckusick 72565789Smckusick ISO_ILOCK(ip); 72665789Smckusick return 0; 72765789Smckusick } 72865789Smckusick 72965789Smckusick /* 73065789Smckusick * Unlock an inode. 73165789Smckusick */ 73265789Smckusick int 73365855Smckusick cd9660_unlock(ap) 73465789Smckusick struct vop_unlock_args /* { 73565789Smckusick struct vnode *a_vp; 73665789Smckusick } */ *ap; 73765789Smckusick { 73865789Smckusick register struct iso_node *ip = VTOI(ap->a_vp); 73965789Smckusick 74065789Smckusick if (!(ip->i_flag & ILOCKED)) 74165855Smckusick panic("cd9660_unlock NOT LOCKED"); 74265789Smckusick ISO_IUNLOCK(ip); 74365789Smckusick return 0; 74465789Smckusick } 74565789Smckusick 74665789Smckusick /* 74765789Smckusick * Check for a locked inode. 74865789Smckusick */ 74965789Smckusick int 75065855Smckusick cd9660_islocked(ap) 75165789Smckusick struct vop_islocked_args /* { 75265789Smckusick struct vnode *a_vp; 75365789Smckusick } */ *ap; 75465789Smckusick { 75565789Smckusick 75665789Smckusick if (VTOI(ap->a_vp)->i_flag & ILOCKED) 75765789Smckusick return 1; 75865789Smckusick return 0; 75965789Smckusick } 76065789Smckusick 76165789Smckusick /* 76265789Smckusick * Calculate the logical to physical mapping if not done already, 76365789Smckusick * then call the device strategy routine. 76465789Smckusick */ 76565789Smckusick int 76665855Smckusick cd9660_strategy(ap) 76765789Smckusick struct vop_strategy_args /* { 76865789Smckusick struct buf *a_bp; 76965789Smckusick } */ *ap; 77065789Smckusick { 77165789Smckusick register struct buf *bp = ap->a_bp; 77265789Smckusick register struct vnode *vp = bp->b_vp; 77365789Smckusick register struct iso_node *ip; 77465789Smckusick int error; 77565789Smckusick 77665789Smckusick ip = VTOI(vp); 77765789Smckusick if (vp->v_type == VBLK || vp->v_type == VCHR) 77865855Smckusick panic("cd9660_strategy: spec"); 77965789Smckusick if (bp->b_blkno == bp->b_lblkno) { 78065789Smckusick if (error = 78165789Smckusick VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) { 78265789Smckusick bp->b_error = error; 78365789Smckusick bp->b_flags |= B_ERROR; 78465789Smckusick biodone(bp); 78565789Smckusick return (error); 78665789Smckusick } 78765789Smckusick if ((long)bp->b_blkno == -1) 78865789Smckusick clrbuf(bp); 78965789Smckusick } 79065789Smckusick if ((long)bp->b_blkno == -1) { 79165789Smckusick biodone(bp); 79265789Smckusick return (0); 79365789Smckusick } 79465789Smckusick vp = ip->i_devvp; 79565789Smckusick bp->b_dev = vp->v_rdev; 79665789Smckusick VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 79765789Smckusick return (0); 79865789Smckusick } 79965789Smckusick 80065789Smckusick /* 80165789Smckusick * Print out the contents of an inode. 80265789Smckusick */ 80365789Smckusick int 80465855Smckusick cd9660_print(ap) 80565789Smckusick struct vop_print_args /* { 80665789Smckusick struct vnode *a_vp; 80765789Smckusick } */ *ap; 80865789Smckusick { 80965789Smckusick printf("tag VT_ISOFS, isofs vnode\n"); 81065789Smckusick return 0; 81165789Smckusick } 81265789Smckusick 81365789Smckusick /* 81465789Smckusick * Unsupported operation 81565789Smckusick */ 81665789Smckusick int 81765855Smckusick cd9660_enotsupp() 81865789Smckusick { 81965789Smckusick 82065789Smckusick return (EOPNOTSUPP); 82165789Smckusick } 82265789Smckusick 82365789Smckusick /* 82465789Smckusick * Global vfs data structures for isofs 82565789Smckusick */ 82665855Smckusick #define cd9660_create \ 82765855Smckusick ((int (*) __P((struct vop_create_args *)))cd9660_enotsupp) 82865855Smckusick #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))cd9660_enotsupp) 82965855Smckusick #define cd9660_setattr \ 83065855Smckusick ((int (*) __P((struct vop_setattr_args *)))cd9660_enotsupp) 83165855Smckusick #define cd9660_write ((int (*) __P((struct vop_write_args *)))cd9660_enotsupp) 83265855Smckusick #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 83365855Smckusick #define cd9660_remove \ 83465855Smckusick ((int (*) __P((struct vop_remove_args *)))cd9660_enotsupp) 83565855Smckusick #define cd9660_link ((int (*) __P((struct vop_link_args *)))cd9660_enotsupp) 83665855Smckusick #define cd9660_rename \ 83765855Smckusick ((int (*) __P((struct vop_rename_args *)))cd9660_enotsupp) 83865855Smckusick #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))cd9660_enotsupp) 83965855Smckusick #define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))cd9660_enotsupp) 84065855Smckusick #define cd9660_symlink \ 84165855Smckusick ((int (*) __P((struct vop_symlink_args *)))cd9660_enotsupp) 84265855Smckusick #define cd9660_pathconf \ 84365855Smckusick ((int (*) __P((struct vop_pathconf_args *)))cd9660_enotsupp) 84465855Smckusick #define cd9660_advlock \ 84565855Smckusick ((int (*) __P((struct vop_advlock_args *)))cd9660_enotsupp) 84665855Smckusick #define cd9660_blkatoff \ 84765855Smckusick ((int (*) __P((struct vop_blkatoff_args *)))cd9660_enotsupp) 84865855Smckusick #define cd9660_valloc ((int(*) __P(( \ 84965789Smckusick struct vnode *pvp, \ 85065789Smckusick int mode, \ 85165789Smckusick struct ucred *cred, \ 85265855Smckusick struct vnode **vpp))) cd9660_enotsupp) 85365855Smckusick #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))cd9660_enotsupp) 85465855Smckusick #define cd9660_truncate \ 85565855Smckusick ((int (*) __P((struct vop_truncate_args *)))cd9660_enotsupp) 85665855Smckusick #define cd9660_update \ 85765855Smckusick ((int (*) __P((struct vop_update_args *)))cd9660_enotsupp) 85865855Smckusick #define cd9660_bwrite \ 85965855Smckusick ((int (*) __P((struct vop_bwrite_args *)))cd9660_enotsupp) 86065789Smckusick 86165789Smckusick /* 86265789Smckusick * Global vfs data structures for nfs 86365789Smckusick */ 86465855Smckusick int (**cd9660_vnodeop_p)(); 86565855Smckusick struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { 86665789Smckusick { &vop_default_desc, vn_default_error }, 86765855Smckusick { &vop_lookup_desc, cd9660_lookup }, /* lookup */ 86865855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 86965855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 87065855Smckusick { &vop_open_desc, cd9660_open }, /* open */ 87165855Smckusick { &vop_close_desc, cd9660_close }, /* close */ 87265855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 87365855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 87465855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 87565855Smckusick { &vop_read_desc, cd9660_read }, /* read */ 87665855Smckusick { &vop_write_desc, cd9660_write }, /* write */ 87765855Smckusick { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */ 87865855Smckusick { &vop_select_desc, cd9660_select }, /* select */ 87965855Smckusick { &vop_mmap_desc, cd9660_mmap }, /* mmap */ 88065855Smckusick { &vop_fsync_desc, cd9660_fsync }, /* fsync */ 88165855Smckusick { &vop_seek_desc, cd9660_seek }, /* seek */ 88265855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 88365855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 88465855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 88565855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 88665855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 88765855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 88865855Smckusick { &vop_readdir_desc, cd9660_readdir }, /* readdir */ 88965855Smckusick { &vop_readlink_desc, cd9660_readlink },/* readlink */ 89065855Smckusick { &vop_abortop_desc, cd9660_abortop }, /* abortop */ 89165855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 89265855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 89365855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 89465855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 89565855Smckusick { &vop_bmap_desc, cd9660_bmap }, /* bmap */ 89665855Smckusick { &vop_strategy_desc, cd9660_strategy },/* strategy */ 89765855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 89865855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 89965855Smckusick { &vop_pathconf_desc, cd9660_pathconf },/* pathconf */ 90065855Smckusick { &vop_advlock_desc, cd9660_advlock }, /* advlock */ 90165855Smckusick { &vop_blkatoff_desc, cd9660_blkatoff },/* blkatoff */ 90265855Smckusick { &vop_valloc_desc, cd9660_valloc }, /* valloc */ 90365855Smckusick { &vop_vfree_desc, cd9660_vfree }, /* vfree */ 90465855Smckusick { &vop_truncate_desc, cd9660_truncate },/* truncate */ 90565855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 90665789Smckusick { &vop_bwrite_desc, vn_bwrite }, 90765789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 90865789Smckusick }; 90965855Smckusick struct vnodeopv_desc cd9660_vnodeop_opv_desc = 91065855Smckusick { &cd9660_vnodeop_p, cd9660_vnodeop_entries }; 91165789Smckusick 91265789Smckusick /* 91365789Smckusick * Special device vnode ops 91465789Smckusick */ 91565855Smckusick int (**cd9660_specop_p)(); 91665855Smckusick struct vnodeopv_entry_desc cd9660_specop_entries[] = { 91765789Smckusick { &vop_default_desc, vn_default_error }, 91865789Smckusick { &vop_lookup_desc, spec_lookup }, /* lookup */ 91965855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 92065855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 92165789Smckusick { &vop_open_desc, spec_open }, /* open */ 92265789Smckusick { &vop_close_desc, spec_close }, /* close */ 92365855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 92465855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 92565855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 92665789Smckusick { &vop_read_desc, spec_read }, /* read */ 92765789Smckusick { &vop_write_desc, spec_write }, /* write */ 92865789Smckusick { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 92965789Smckusick { &vop_select_desc, spec_select }, /* select */ 93065789Smckusick { &vop_mmap_desc, spec_mmap }, /* mmap */ 93165789Smckusick { &vop_fsync_desc, spec_fsync }, /* fsync */ 93265789Smckusick { &vop_seek_desc, spec_seek }, /* seek */ 93365855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 93465855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 93565855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 93665855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 93765855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 93865855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 93965789Smckusick { &vop_readdir_desc, spec_readdir }, /* readdir */ 94065789Smckusick { &vop_readlink_desc, spec_readlink }, /* readlink */ 94165789Smckusick { &vop_abortop_desc, spec_abortop }, /* abortop */ 94265855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 94365855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 94465855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 94565855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 94665789Smckusick { &vop_bmap_desc, spec_bmap }, /* bmap */ 94765789Smckusick /* XXX strategy: panics, should be notsupp instead? */ 94865855Smckusick { &vop_strategy_desc, cd9660_strategy },/* strategy */ 94965855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 95065855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 95165789Smckusick { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 95265789Smckusick { &vop_advlock_desc, spec_advlock }, /* advlock */ 95365789Smckusick { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 95465789Smckusick { &vop_valloc_desc, spec_valloc }, /* valloc */ 95565789Smckusick { &vop_vfree_desc, spec_vfree }, /* vfree */ 95665789Smckusick { &vop_truncate_desc, spec_truncate }, /* truncate */ 95765855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 95865789Smckusick { &vop_bwrite_desc, vn_bwrite }, 95965789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 96065789Smckusick }; 96165855Smckusick struct vnodeopv_desc cd9660_specop_opv_desc = 96265855Smckusick { &cd9660_specop_p, cd9660_specop_entries }; 96365789Smckusick 96465789Smckusick #ifdef FIFO 96565855Smckusick int (**cd9660_fifoop_p)(); 96665855Smckusick struct vnodeopv_entry_desc cd9660_fifoop_entries[] = { 96765789Smckusick { &vop_default_desc, vn_default_error }, 96865789Smckusick { &vop_lookup_desc, fifo_lookup }, /* lookup */ 96965855Smckusick { &vop_create_desc, cd9660_create }, /* create */ 97065855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 97165789Smckusick { &vop_open_desc, fifo_open }, /* open */ 97265789Smckusick { &vop_close_desc, fifo_close }, /* close */ 97365855Smckusick { &vop_access_desc, cd9660_access }, /* access */ 97465855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 97565855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 97665789Smckusick { &vop_read_desc, fifo_read }, /* read */ 97765789Smckusick { &vop_write_desc, fifo_write }, /* write */ 97865789Smckusick { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 97965789Smckusick { &vop_select_desc, fifo_select }, /* select */ 98065789Smckusick { &vop_mmap_desc, fifo_mmap }, /* mmap */ 98165789Smckusick { &vop_fsync_desc, fifo_fsync }, /* fsync */ 98265789Smckusick { &vop_seek_desc, fifo_seek }, /* seek */ 98365855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */ 98465855Smckusick { &vop_link_desc, cd9660_link }, /* link */ 98565855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */ 98665855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 98765855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 98865855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 98965789Smckusick { &vop_readdir_desc, fifo_readdir }, /* readdir */ 99065789Smckusick { &vop_readlink_desc, fifo_readlink }, /* readlink */ 99165789Smckusick { &vop_abortop_desc, fifo_abortop }, /* abortop */ 99265855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */ 99365855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 99465855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */ 99565855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */ 99665789Smckusick { &vop_bmap_desc, fifo_bmap }, /* bmap */ 99765789Smckusick { &vop_strategy_desc, fifo_badop }, /* strategy */ 99865855Smckusick { &vop_print_desc, cd9660_print }, /* print */ 99965855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */ 100065789Smckusick { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ 100165789Smckusick { &vop_advlock_desc, fifo_advlock }, /* advlock */ 100265789Smckusick { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 100365789Smckusick { &vop_valloc_desc, fifo_valloc }, /* valloc */ 100465789Smckusick { &vop_vfree_desc, fifo_vfree }, /* vfree */ 100565789Smckusick { &vop_truncate_desc, fifo_truncate }, /* truncate */ 100665855Smckusick { &vop_update_desc, cd9660_update }, /* update */ 100765789Smckusick { &vop_bwrite_desc, vn_bwrite }, 100865789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 100965789Smckusick }; 101065855Smckusick struct vnodeopv_desc cd9660_fifoop_opv_desc = 101165855Smckusick { &cd9660_fifoop_p, cd9660_fifoop_entries }; 101265789Smckusick #endif /* FIFO */ 1013