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*69742Smckusick * @(#)cd9660_vnops.c 8.19 (Berkeley) 05/27/95
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;
5768052Smckusick
5865789Smckusick vp = ndp->ni_vp;
5965789Smckusick ip = VTOI(vp);
6068052Smckusick
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 }
6968052Smckusick
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;
7868052Smckusick
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 /*
93*69742Smckusick * Setattr call. Only allowed for block and character special devices.
94*69742Smckusick */
95*69742Smckusick int
cd9660_setattr(ap)96*69742Smckusick cd9660_setattr(ap)
97*69742Smckusick struct vop_setattr_args /* {
98*69742Smckusick struct vnodeop_desc *a_desc;
99*69742Smckusick struct vnode *a_vp;
100*69742Smckusick struct vattr *a_vap;
101*69742Smckusick struct ucred *a_cred;
102*69742Smckusick struct proc *a_p;
103*69742Smckusick } */ *ap;
104*69742Smckusick {
105*69742Smckusick struct vnode *vp = ap->a_vp;
106*69742Smckusick struct vattr *vap = ap->a_vap;
107*69742Smckusick
108*69742Smckusick if (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
109*69742Smckusick vap->va_gid != (gid_t)VNOVAL || vap->va_atime.ts_sec != VNOVAL ||
110*69742Smckusick vap->va_mtime.ts_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL)
111*69742Smckusick return (EROFS);
112*69742Smckusick if (vap->va_size != VNOVAL) {
113*69742Smckusick switch (vp->v_type) {
114*69742Smckusick case VDIR:
115*69742Smckusick return (EISDIR);
116*69742Smckusick case VLNK:
117*69742Smckusick case VREG:
118*69742Smckusick return (EROFS);
119*69742Smckusick case VCHR:
120*69742Smckusick case VBLK:
121*69742Smckusick case VSOCK:
122*69742Smckusick case VFIFO:
123*69742Smckusick return (0);
124*69742Smckusick }
125*69742Smckusick }
126*69742Smckusick }
127*69742Smckusick
128*69742Smckusick /*
12965789Smckusick * Open called.
13065789Smckusick *
13165789Smckusick * Nothing to do.
13265789Smckusick */
13365789Smckusick /* ARGSUSED */
13465789Smckusick int
cd9660_open(ap)13565855Smckusick cd9660_open(ap)
13665789Smckusick struct vop_open_args /* {
13765789Smckusick struct vnode *a_vp;
13865789Smckusick int a_mode;
13965789Smckusick struct ucred *a_cred;
14065789Smckusick struct proc *a_p;
14165789Smckusick } */ *ap;
14265789Smckusick {
14365789Smckusick return (0);
14465789Smckusick }
14565789Smckusick
14665789Smckusick /*
14765789Smckusick * Close called
14865789Smckusick *
14965789Smckusick * Update the times on the inode on writeable file systems.
15065789Smckusick */
15165789Smckusick /* ARGSUSED */
15265789Smckusick int
cd9660_close(ap)15365855Smckusick cd9660_close(ap)
15465789Smckusick struct vop_close_args /* {
15565789Smckusick struct vnode *a_vp;
15665789Smckusick int a_fflag;
15765789Smckusick struct ucred *a_cred;
15865789Smckusick struct proc *a_p;
15965789Smckusick } */ *ap;
16065789Smckusick {
16165789Smckusick return (0);
16265789Smckusick }
16365789Smckusick
16465789Smckusick /*
16565789Smckusick * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
16665789Smckusick * The mode is shifted to select the owner/group/other fields. The
16765789Smckusick * super user is granted all permissions.
16865789Smckusick */
16965789Smckusick /* ARGSUSED */
17065855Smckusick cd9660_access(ap)
17165789Smckusick struct vop_access_args /* {
17265789Smckusick struct vnode *a_vp;
17365789Smckusick int a_mode;
17465789Smckusick struct ucred *a_cred;
17565789Smckusick struct proc *a_p;
17665789Smckusick } */ *ap;
17765789Smckusick {
178*69742Smckusick struct vnode *vp = ap->a_vp;
179*69742Smckusick struct iso_node *ip = VTOI(vp);
18067379Smkm struct ucred *cred = ap->a_cred;
18167379Smkm mode_t mask, mode = ap->a_mode;
18267379Smkm gid_t *gp;
18368052Smckusick int i;
18467379Smkm
185*69742Smckusick /*
186*69742Smckusick * Disallow write attempts unless the file is a socket,
187*69742Smckusick * fifo, or a block or character device resident on the
188*69742Smckusick * file system.
189*69742Smckusick */
190*69742Smckusick if (mode & VWRITE) {
191*69742Smckusick switch (vp->v_type) {
192*69742Smckusick case VDIR:
193*69742Smckusick case VLNK:
194*69742Smckusick case VREG:
195*69742Smckusick return (EROFS);
196*69742Smckusick }
197*69742Smckusick }
198*69742Smckusick
19967379Smkm /* User id 0 always gets access. */
20067379Smkm if (cred->cr_uid == 0)
20167379Smkm return (0);
20267379Smkm
20367379Smkm mask = 0;
20467379Smkm
20567379Smkm /* Otherwise, check the owner. */
20667379Smkm if (cred->cr_uid == ip->inode.iso_uid) {
20767379Smkm if (mode & VEXEC)
20867379Smkm mask |= S_IXUSR;
20967379Smkm if (mode & VREAD)
21067379Smkm mask |= S_IRUSR;
21167379Smkm if (mode & VWRITE)
21267379Smkm mask |= S_IWUSR;
21367379Smkm return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
21467379Smkm }
21567379Smkm
21667379Smkm /* Otherwise, check the groups. */
21767379Smkm for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
21867379Smkm if (ip->inode.iso_gid == *gp) {
21967379Smkm if (mode & VEXEC)
22067379Smkm mask |= S_IXGRP;
22167379Smkm if (mode & VREAD)
22267379Smkm mask |= S_IRGRP;
22367379Smkm if (mode & VWRITE)
22467379Smkm mask |= S_IWGRP;
22567379Smkm return ((ip->inode.iso_mode & mask) == mask ?
22667379Smkm 0 : EACCES);
22767379Smkm }
22867379Smkm
22967379Smkm /* Otherwise, check everyone else. */
23067379Smkm if (mode & VEXEC)
23167379Smkm mask |= S_IXOTH;
23267379Smkm if (mode & VREAD)
23367379Smkm mask |= S_IROTH;
23467379Smkm if (mode & VWRITE)
23567379Smkm mask |= S_IWOTH;
23667379Smkm return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
23765789Smckusick }
23865789Smckusick
23965855Smckusick cd9660_getattr(ap)
24065789Smckusick struct vop_getattr_args /* {
24165789Smckusick struct vnode *a_vp;
24265789Smckusick struct vattr *a_vap;
24365789Smckusick struct ucred *a_cred;
24465789Smckusick struct proc *a_p;
24565789Smckusick } */ *ap;
24665789Smckusick
24765789Smckusick {
24865789Smckusick struct vnode *vp = ap->a_vp;
24965789Smckusick register struct vattr *vap = ap->a_vap;
25065789Smckusick register struct iso_node *ip = VTOI(vp);
25165789Smckusick int i;
25265789Smckusick
25365789Smckusick vap->va_fsid = ip->i_dev;
25465789Smckusick vap->va_fileid = ip->i_number;
25565789Smckusick
25665789Smckusick vap->va_mode = ip->inode.iso_mode;
25765789Smckusick vap->va_nlink = ip->inode.iso_links;
25865789Smckusick vap->va_uid = ip->inode.iso_uid;
25965789Smckusick vap->va_gid = ip->inode.iso_gid;
26065789Smckusick vap->va_atime = ip->inode.iso_atime;
26165789Smckusick vap->va_mtime = ip->inode.iso_mtime;
26265789Smckusick vap->va_ctime = ip->inode.iso_ctime;
26365789Smckusick vap->va_rdev = ip->inode.iso_rdev;
26465789Smckusick
26565789Smckusick vap->va_size = (u_quad_t) ip->i_size;
26667703Smckusick if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) {
26767703Smckusick struct vop_readlink_args rdlnk;
26867703Smckusick struct iovec aiov;
26967703Smckusick struct uio auio;
27067703Smckusick char *cp;
27167703Smckusick
27267703Smckusick MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
27367703Smckusick aiov.iov_base = cp;
27467703Smckusick aiov.iov_len = MAXPATHLEN;
27567703Smckusick auio.uio_iov = &aiov;
27667703Smckusick auio.uio_iovcnt = 1;
27767703Smckusick auio.uio_offset = 0;
27867703Smckusick auio.uio_rw = UIO_READ;
27967703Smckusick auio.uio_segflg = UIO_SYSSPACE;
28067703Smckusick auio.uio_procp = ap->a_p;
28167703Smckusick auio.uio_resid = MAXPATHLEN;
28267703Smckusick rdlnk.a_uio = &auio;
28367703Smckusick rdlnk.a_vp = ap->a_vp;
28467703Smckusick rdlnk.a_cred = ap->a_cred;
28567703Smckusick if (cd9660_readlink(&rdlnk) == 0)
28667703Smckusick vap->va_size = MAXPATHLEN - auio.uio_resid;
28767703Smckusick FREE(cp, M_TEMP);
28867703Smckusick }
28965789Smckusick vap->va_flags = 0;
29065789Smckusick vap->va_gen = 1;
29165789Smckusick vap->va_blocksize = ip->i_mnt->logical_block_size;
29265789Smckusick vap->va_bytes = (u_quad_t) ip->i_size;
29365789Smckusick vap->va_type = vp->v_type;
29465789Smckusick return (0);
29565789Smckusick }
29665789Smckusick
29765789Smckusick #if ISO_DEFAULT_BLOCK_SIZE >= NBPG
29865789Smckusick #ifdef DEBUG
29965789Smckusick extern int doclusterread;
30065789Smckusick #else
30165789Smckusick #define doclusterread 1
30265789Smckusick #endif
30365789Smckusick #else
30465789Smckusick /* XXX until cluster routines can handle block sizes less than one page */
30565789Smckusick #define doclusterread 0
30665789Smckusick #endif
30765789Smckusick
30865789Smckusick /*
30965789Smckusick * Vnode op for reading.
31065789Smckusick */
31165855Smckusick cd9660_read(ap)
31265789Smckusick struct vop_read_args /* {
31365789Smckusick struct vnode *a_vp;
31465789Smckusick struct uio *a_uio;
31565789Smckusick int a_ioflag;
31665789Smckusick struct ucred *a_cred;
31765789Smckusick } */ *ap;
31865789Smckusick {
31965789Smckusick struct vnode *vp = ap->a_vp;
32065789Smckusick register struct uio *uio = ap->a_uio;
32165789Smckusick register struct iso_node *ip = VTOI(vp);
32265789Smckusick register struct iso_mnt *imp;
32365789Smckusick struct buf *bp;
32465789Smckusick daddr_t lbn, bn, rablock;
32565789Smckusick off_t diff;
32665789Smckusick int rasize, error = 0;
32765789Smckusick long size, n, on;
32868052Smckusick
32965789Smckusick if (uio->uio_resid == 0)
33065789Smckusick return (0);
33165789Smckusick if (uio->uio_offset < 0)
33265789Smckusick return (EINVAL);
33367526Smckusick ip->i_flag |= IN_ACCESS;
33465789Smckusick imp = ip->i_mnt;
33565789Smckusick do {
33668052Smckusick lbn = lblkno(imp, uio->uio_offset);
33768052Smckusick on = blkoff(imp, uio->uio_offset);
33868052Smckusick n = min((u_int)(imp->logical_block_size - on),
33965789Smckusick uio->uio_resid);
34065789Smckusick diff = (off_t)ip->i_size - uio->uio_offset;
34165789Smckusick if (diff <= 0)
34265789Smckusick return (0);
34365789Smckusick if (diff < n)
34465789Smckusick n = diff;
34568052Smckusick size = blksize(imp, ip, lbn);
34665789Smckusick rablock = lbn + 1;
34765789Smckusick if (doclusterread) {
34868052Smckusick if (lblktosize(imp, rablock) <= ip->i_size)
34965789Smckusick error = cluster_read(vp, (off_t)ip->i_size,
35065789Smckusick lbn, size, NOCRED, &bp);
35168052Smckusick else
35265789Smckusick error = bread(vp, lbn, size, NOCRED, &bp);
35365789Smckusick } else {
35465789Smckusick if (vp->v_lastr + 1 == lbn &&
35568052Smckusick lblktosize(imp, rablock) < ip->i_size) {
35668052Smckusick rasize = blksize(imp, ip, rablock);
35765789Smckusick error = breadn(vp, lbn, size, &rablock,
35865789Smckusick &rasize, 1, NOCRED, &bp);
35965789Smckusick } else
36065789Smckusick error = bread(vp, lbn, size, NOCRED, &bp);
36165789Smckusick }
36265789Smckusick vp->v_lastr = lbn;
36365789Smckusick n = min(n, size - bp->b_resid);
36465789Smckusick if (error) {
36565789Smckusick brelse(bp);
36665789Smckusick return (error);
36765789Smckusick }
36865789Smckusick
36968052Smckusick error = uiomove(bp->b_data + on, (int)n, uio);
37065789Smckusick if (n + on == imp->logical_block_size ||
37165789Smckusick uio->uio_offset == (off_t)ip->i_size)
37265789Smckusick bp->b_flags |= B_AGE;
37365789Smckusick brelse(bp);
37465789Smckusick } while (error == 0 && uio->uio_resid > 0 && n != 0);
37565789Smckusick return (error);
37665789Smckusick }
37765789Smckusick
37865789Smckusick /* ARGSUSED */
37965789Smckusick int
cd9660_ioctl(ap)38065855Smckusick cd9660_ioctl(ap)
38165789Smckusick struct vop_ioctl_args /* {
38265789Smckusick struct vnode *a_vp;
38368052Smckusick u_long a_command;
38465789Smckusick caddr_t a_data;
38565789Smckusick int a_fflag;
38665789Smckusick struct ucred *a_cred;
38765789Smckusick struct proc *a_p;
38865789Smckusick } */ *ap;
38965789Smckusick {
39065789Smckusick printf("You did ioctl for isofs !!\n");
39165789Smckusick return (ENOTTY);
39265789Smckusick }
39365789Smckusick
39465789Smckusick /* ARGSUSED */
39565789Smckusick int
cd9660_select(ap)39665855Smckusick cd9660_select(ap)
39765789Smckusick struct vop_select_args /* {
39865789Smckusick struct vnode *a_vp;
39965789Smckusick int a_which;
40065789Smckusick int a_fflags;
40165789Smckusick struct ucred *a_cred;
40265789Smckusick struct proc *a_p;
40365789Smckusick } */ *ap;
40465789Smckusick {
40565789Smckusick
40665789Smckusick /*
40765789Smckusick * We should really check to see if I/O is possible.
40865789Smckusick */
40965789Smckusick return (1);
41065789Smckusick }
41165789Smckusick
41265789Smckusick /*
41365789Smckusick * Mmap a file
41465789Smckusick *
41565789Smckusick * NB Currently unsupported.
41665789Smckusick */
41765789Smckusick /* ARGSUSED */
41865789Smckusick int
cd9660_mmap(ap)41965855Smckusick cd9660_mmap(ap)
42065789Smckusick struct vop_mmap_args /* {
42165789Smckusick struct vnode *a_vp;
42265789Smckusick int a_fflags;
42365789Smckusick struct ucred *a_cred;
42465789Smckusick struct proc *a_p;
42565789Smckusick } */ *ap;
42665789Smckusick {
42765789Smckusick
42865789Smckusick return (EINVAL);
42965789Smckusick }
43065789Smckusick
43165789Smckusick /*
43265789Smckusick * Seek on a file
43365789Smckusick *
43465789Smckusick * Nothing to do, so just return.
43565789Smckusick */
43665789Smckusick /* ARGSUSED */
43765789Smckusick int
cd9660_seek(ap)43865855Smckusick cd9660_seek(ap)
43965789Smckusick struct vop_seek_args /* {
44065789Smckusick struct vnode *a_vp;
44165789Smckusick off_t a_oldoff;
44265789Smckusick off_t a_newoff;
44365789Smckusick struct ucred *a_cred;
44465789Smckusick } */ *ap;
44565789Smckusick {
44665789Smckusick
44765789Smckusick return (0);
44865789Smckusick }
44965789Smckusick
45065789Smckusick /*
45165789Smckusick * Structure for reading directories
45265789Smckusick */
45365789Smckusick struct isoreaddir {
45465789Smckusick struct dirent saveent;
45565789Smckusick struct dirent assocent;
45665789Smckusick struct dirent current;
45765789Smckusick off_t saveoff;
45865789Smckusick off_t assocoff;
45965789Smckusick off_t curroff;
46065789Smckusick struct uio *uio;
46165789Smckusick off_t uio_off;
46267370Smckusick int eofflag;
46367370Smckusick u_long *cookies;
46465789Smckusick int ncookies;
46565789Smckusick };
46665789Smckusick
46768052Smckusick int
iso_uiodir(idp,dp,off)46865789Smckusick iso_uiodir(idp,dp,off)
46965789Smckusick struct isoreaddir *idp;
47065789Smckusick struct dirent *dp;
47165789Smckusick off_t off;
47265789Smckusick {
47365789Smckusick int error;
47468052Smckusick
47565789Smckusick dp->d_name[dp->d_namlen] = 0;
47665789Smckusick dp->d_reclen = DIRSIZ(dp);
47768052Smckusick
47865789Smckusick if (idp->uio->uio_resid < dp->d_reclen) {
47967370Smckusick idp->eofflag = 0;
48067370Smckusick return (-1);
48165789Smckusick }
48268052Smckusick
48367370Smckusick if (idp->cookies) {
48465789Smckusick if (idp->ncookies <= 0) {
48567370Smckusick idp->eofflag = 0;
48667370Smckusick return (-1);
48765789Smckusick }
48868052Smckusick
48967370Smckusick *idp->cookies++ = off;
49065789Smckusick --idp->ncookies;
49165789Smckusick }
49268052Smckusick
49365789Smckusick if (error = uiomove(dp,dp->d_reclen,idp->uio))
49467370Smckusick return (error);
49565789Smckusick idp->uio_off = off;
49667370Smckusick return (0);
49765789Smckusick }
49865789Smckusick
49968052Smckusick int
iso_shipdir(idp)50065789Smckusick iso_shipdir(idp)
50165789Smckusick struct isoreaddir *idp;
50265789Smckusick {
50365789Smckusick struct dirent *dp;
50465789Smckusick int cl, sl, assoc;
50565789Smckusick int error;
50665789Smckusick char *cname, *sname;
50768052Smckusick
50865789Smckusick cl = idp->current.d_namlen;
50965789Smckusick cname = idp->current.d_name;
51065789Smckusick if (assoc = cl > 1 && *cname == ASSOCCHAR) {
51165789Smckusick cl--;
51265789Smckusick cname++;
51365789Smckusick }
51468052Smckusick
51565789Smckusick dp = &idp->saveent;
51665789Smckusick sname = dp->d_name;
51765789Smckusick if (!(sl = dp->d_namlen)) {
51865789Smckusick dp = &idp->assocent;
51965789Smckusick sname = dp->d_name + 1;
52065789Smckusick sl = dp->d_namlen - 1;
52165789Smckusick }
52265789Smckusick if (sl > 0) {
52365789Smckusick if (sl != cl
52465789Smckusick || bcmp(sname,cname,sl)) {
52565789Smckusick if (idp->assocent.d_namlen) {
52665789Smckusick if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff))
52767379Smkm return (error);
52865789Smckusick idp->assocent.d_namlen = 0;
52965789Smckusick }
53065789Smckusick if (idp->saveent.d_namlen) {
53165789Smckusick if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))
53267379Smkm return (error);
53365789Smckusick idp->saveent.d_namlen = 0;
53465789Smckusick }
53565789Smckusick }
53665789Smckusick }
53765789Smckusick idp->current.d_reclen = DIRSIZ(&idp->current);
53865789Smckusick if (assoc) {
53965789Smckusick idp->assocoff = idp->curroff;
54065789Smckusick bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);
54165789Smckusick } else {
54265789Smckusick idp->saveoff = idp->curroff;
54365789Smckusick bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
54465789Smckusick }
54567379Smkm return (0);
54665789Smckusick }
54765789Smckusick
54865789Smckusick /*
54965789Smckusick * Vnode op for readdir
55065789Smckusick */
55165789Smckusick int
cd9660_readdir(ap)55265855Smckusick cd9660_readdir(ap)
55365789Smckusick struct vop_readdir_args /* {
55465789Smckusick struct vnode *a_vp;
55565789Smckusick struct uio *a_uio;
55665789Smckusick struct ucred *a_cred;
55767370Smckusick int *a_eofflag;
55868681Smckusick int *a_ncookies;
55967370Smckusick u_long *a_cookies;
56065789Smckusick } */ *ap;
56165789Smckusick {
56265789Smckusick register struct uio *uio = ap->a_uio;
56365789Smckusick struct isoreaddir *idp;
56468052Smckusick struct vnode *vdp = ap->a_vp;
56568052Smckusick struct iso_node *dp;
56668052Smckusick struct iso_mnt *imp;
56768052Smckusick struct buf *bp = NULL;
56868052Smckusick struct iso_directory_record *ep;
56965789Smckusick int entryoffsetinblock;
57068052Smckusick doff_t endsearch;
57168052Smckusick u_long bmask;
57265789Smckusick int error = 0;
57365789Smckusick int reclen;
57468052Smckusick u_short namelen;
57568681Smckusick int ncookies = 0;
57668681Smckusick u_long *cookies = NULL;
57768052Smckusick
57868052Smckusick dp = VTOI(vdp);
57968052Smckusick imp = dp->i_mnt;
58068052Smckusick bmask = imp->im_bmask;
58168052Smckusick
58267529Smckusick MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK);
58367529Smckusick idp->saveent.d_namlen = idp->assocent.d_namlen = 0;
58467529Smckusick /*
58567529Smckusick * XXX
58667529Smckusick * Is it worth trying to figure out the type?
58767529Smckusick */
58867529Smckusick idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
58967529Smckusick DT_UNKNOWN;
59065789Smckusick idp->uio = uio;
59168681Smckusick if (ap->a_ncookies == NULL) {
59268681Smckusick idp->cookies = NULL;
59368681Smckusick } else {
59468681Smckusick /*
59568681Smckusick * Guess the number of cookies needed.
59668681Smckusick */
59768681Smckusick ncookies = uio->uio_resid / 16;
59868681Smckusick MALLOC(cookies, u_int *, ncookies * sizeof(u_int), M_TEMP,
59968681Smckusick M_WAITOK);
60068681Smckusick idp->cookies = cookies;
60168681Smckusick idp->ncookies = ncookies;
60268681Smckusick }
60367370Smckusick idp->eofflag = 1;
60465789Smckusick idp->curroff = uio->uio_offset;
60568052Smckusick
60668052Smckusick if ((entryoffsetinblock = idp->curroff & bmask) &&
60768052Smckusick (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) {
60868052Smckusick FREE(idp, M_TEMP);
60968052Smckusick return (error);
61065789Smckusick }
61168052Smckusick endsearch = dp->i_size;
61268052Smckusick
61365789Smckusick while (idp->curroff < endsearch) {
61465789Smckusick /*
61565789Smckusick * If offset is on a block boundary,
61665789Smckusick * read the next directory block.
61765789Smckusick * Release previous if it exists.
61865789Smckusick */
61968052Smckusick if ((idp->curroff & bmask) == 0) {
62065789Smckusick if (bp != NULL)
62165789Smckusick brelse(bp);
62268052Smckusick if (error =
62368052Smckusick VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))
62465789Smckusick break;
62565789Smckusick entryoffsetinblock = 0;
62665789Smckusick }
62765789Smckusick /*
62865789Smckusick * Get pointer to next entry.
62965789Smckusick */
63065789Smckusick ep = (struct iso_directory_record *)
63168052Smckusick ((char *)bp->b_data + entryoffsetinblock);
63268052Smckusick
63368052Smckusick reclen = isonum_711(ep->length);
63465789Smckusick if (reclen == 0) {
63565789Smckusick /* skip to next block, if any */
63667559Smckusick idp->curroff =
63768052Smckusick (idp->curroff & ~bmask) + imp->logical_block_size;
63865789Smckusick continue;
63965789Smckusick }
64068052Smckusick
64165789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
64265789Smckusick error = EINVAL;
64365789Smckusick /* illegal entry, stop */
64465789Smckusick break;
64565789Smckusick }
64668052Smckusick
64765789Smckusick if (entryoffsetinblock + reclen > imp->logical_block_size) {
64865789Smckusick error = EINVAL;
64965789Smckusick /* illegal directory, so stop looking */
65065789Smckusick break;
65165789Smckusick }
65268052Smckusick
65367559Smckusick idp->current.d_namlen = isonum_711(ep->name_len);
65467559Smckusick
65565789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
65665789Smckusick error = EINVAL;
65765789Smckusick /* illegal entry, stop */
65865789Smckusick break;
65965789Smckusick }
66068052Smckusick
66167559Smckusick if (isonum_711(ep->flags)&2)
66268052Smckusick idp->current.d_fileno = isodirino(ep, imp);
66367559Smckusick else
66467559Smckusick idp->current.d_fileno = dbtob(bp->b_blkno) +
66567559Smckusick entryoffsetinblock;
66668052Smckusick
66765789Smckusick idp->curroff += reclen;
66867559Smckusick
66965789Smckusick switch (imp->iso_ftype) {
67065789Smckusick case ISO_FTYPE_RRIP:
67168052Smckusick cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
67265789Smckusick &idp->current.d_fileno,imp);
67368052Smckusick idp->current.d_namlen = (u_char)namelen;
67465789Smckusick if (idp->current.d_namlen)
67565789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff);
67665789Smckusick break;
67765789Smckusick default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */
67865789Smckusick strcpy(idp->current.d_name,"..");
67965789Smckusick switch (ep->name[0]) {
68065789Smckusick case 0:
68165789Smckusick idp->current.d_namlen = 1;
68265789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff);
68365789Smckusick break;
68465789Smckusick case 1:
68565789Smckusick idp->current.d_namlen = 2;
68665789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff);
68765789Smckusick break;
68865789Smckusick default:
68965789Smckusick isofntrans(ep->name,idp->current.d_namlen,
69068052Smckusick idp->current.d_name, &namelen,
69165789Smckusick imp->iso_ftype == ISO_FTYPE_9660,
69265789Smckusick isonum_711(ep->flags)&4);
69368052Smckusick idp->current.d_namlen = (u_char)namelen;
69465789Smckusick if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
69565789Smckusick error = iso_shipdir(idp);
69665789Smckusick else
69765789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff);
69865789Smckusick break;
69965789Smckusick }
70065789Smckusick }
70165789Smckusick if (error)
70265789Smckusick break;
70368052Smckusick
70465789Smckusick entryoffsetinblock += reclen;
70565789Smckusick }
70668052Smckusick
70765789Smckusick if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
70865789Smckusick idp->current.d_namlen = 0;
70965789Smckusick error = iso_shipdir(idp);
71065789Smckusick }
71165789Smckusick if (error < 0)
71265789Smckusick error = 0;
71368052Smckusick
71468681Smckusick if (ap->a_ncookies != NULL) {
71568681Smckusick if (error)
71668681Smckusick free(cookies, M_TEMP);
71768681Smckusick else {
71868681Smckusick /*
71968681Smckusick * Work out the number of cookies actually used.
72068681Smckusick */
72168681Smckusick *ap->a_ncookies = ncookies - idp->ncookies;
72268681Smckusick *ap->a_cookies = cookies;
72368681Smckusick }
72468681Smckusick }
72568681Smckusick
72665789Smckusick if (bp)
72765789Smckusick brelse (bp);
72868052Smckusick
72965789Smckusick uio->uio_offset = idp->uio_off;
73067370Smckusick *ap->a_eofflag = idp->eofflag;
73168052Smckusick
73268052Smckusick FREE(idp, M_TEMP);
73368052Smckusick
73465789Smckusick return (error);
73565789Smckusick }
73668052Smckusick
73765789Smckusick /*
73865789Smckusick * Return target name of a symbolic link
73965789Smckusick * Shouldn't we get the parent vnode and read the data from there?
74065855Smckusick * This could eventually result in deadlocks in cd9660_lookup.
74165789Smckusick * But otherwise the block read here is in the block buffer two times.
74265789Smckusick */
74365789Smckusick typedef struct iso_directory_record ISODIR;
74465789Smckusick typedef struct iso_node ISONODE;
74565789Smckusick typedef struct iso_mnt ISOMNT;
74665789Smckusick int
cd9660_readlink(ap)74765855Smckusick cd9660_readlink(ap)
74865789Smckusick struct vop_readlink_args /* {
74965789Smckusick struct vnode *a_vp;
75065789Smckusick struct uio *a_uio;
75165789Smckusick struct ucred *a_cred;
75265789Smckusick } */ *ap;
75365789Smckusick {
75465789Smckusick ISONODE *ip;
75568052Smckusick ISODIR *dirp;
75665789Smckusick ISOMNT *imp;
75765789Smckusick struct buf *bp;
75868054Smckusick struct uio *uio;
75965789Smckusick u_short symlen;
76065789Smckusick int error;
76165789Smckusick char *symname;
76265789Smckusick ino_t ino;
76368052Smckusick
76465789Smckusick ip = VTOI(ap->a_vp);
76565789Smckusick imp = ip->i_mnt;
76668054Smckusick uio = ap->a_uio;
76768052Smckusick
76865789Smckusick if (imp->iso_ftype != ISO_FTYPE_RRIP)
76967379Smkm return (EINVAL);
77068052Smckusick
77165789Smckusick /*
77265789Smckusick * Get parents directory record block that this inode included.
77365789Smckusick */
77465789Smckusick error = bread(imp->im_devvp,
77568052Smckusick (ip->i_number >> imp->im_bshift) <<
77668052Smckusick (imp->im_bshift - DEV_BSHIFT),
77768052Smckusick imp->logical_block_size, NOCRED, &bp);
77865789Smckusick if (error) {
77965789Smckusick brelse(bp);
78067379Smkm return (EINVAL);
78165789Smckusick }
78265789Smckusick
78365789Smckusick /*
78465789Smckusick * Setup the directory pointer for this inode
78565789Smckusick */
78668052Smckusick dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask));
78767379Smkm
78865789Smckusick /*
78965789Smckusick * Just make sure, we have a right one....
79065789Smckusick * 1: Check not cross boundary on block
79165789Smckusick */
79265789Smckusick if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
79365789Smckusick > imp->logical_block_size) {
79465789Smckusick brelse(bp);
79567379Smkm return (EINVAL);
79665789Smckusick }
79768052Smckusick
79865789Smckusick /*
79965789Smckusick * Now get a buffer
80065789Smckusick * Abuse a namei buffer for now.
80165789Smckusick */
80267710Smckusick if (uio->uio_segflg == UIO_SYSSPACE)
80367710Smckusick symname = uio->uio_iov->iov_base;
80467710Smckusick else
80567710Smckusick MALLOC(symname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
80665789Smckusick
80765789Smckusick /*
80865789Smckusick * Ok, we just gathering a symbolic name in SL record.
80965789Smckusick */
81067710Smckusick if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
81167710Smckusick if (uio->uio_segflg != UIO_SYSSPACE)
81267710Smckusick FREE(symname, M_NAMEI);
81365789Smckusick brelse(bp);
81467379Smkm return (EINVAL);
81565789Smckusick }
81665789Smckusick /*
81765789Smckusick * Don't forget before you leave from home ;-)
81865789Smckusick */
81965789Smckusick brelse(bp);
82065789Smckusick
82165789Smckusick /*
82265789Smckusick * return with the symbolic name to caller's.
82365789Smckusick */
82467710Smckusick if (uio->uio_segflg != UIO_SYSSPACE) {
82567710Smckusick error = uiomove(symname, symlen, uio);
82667710Smckusick FREE(symname, M_NAMEI);
82767710Smckusick return (error);
82867710Smckusick }
82967710Smckusick uio->uio_resid -= symlen;
83067710Smckusick uio->uio_iov->iov_base += symlen;
83167710Smckusick uio->uio_iov->iov_len -= symlen;
83267710Smckusick return (0);
83365789Smckusick }
83465789Smckusick
83565789Smckusick /*
83665789Smckusick * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
83765789Smckusick * done. If a buffer has been saved in anticipation of a CREATE, delete it.
83865789Smckusick */
83965789Smckusick int
cd9660_abortop(ap)84065855Smckusick cd9660_abortop(ap)
84165789Smckusick struct vop_abortop_args /* {
84265789Smckusick struct vnode *a_dvp;
84365789Smckusick struct componentname *a_cnp;
84465789Smckusick } */ *ap;
84565789Smckusick {
84665789Smckusick if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
84765789Smckusick FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
84867379Smkm return (0);
84965789Smckusick }
85065789Smckusick
85165789Smckusick /*
85265789Smckusick * Lock an inode.
85365789Smckusick */
85465789Smckusick int
cd9660_lock(ap)85565855Smckusick cd9660_lock(ap)
85665789Smckusick struct vop_lock_args /* {
85765789Smckusick struct vnode *a_vp;
85869427Smckusick int a_flags;
85969427Smckusick struct proc *a_p;
86065789Smckusick } */ *ap;
86165789Smckusick {
86269427Smckusick struct vnode *vp = ap->a_vp;
86365789Smckusick
86469427Smckusick return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock,
86569427Smckusick ap->a_p));
86665789Smckusick }
86765789Smckusick
86865789Smckusick /*
86965789Smckusick * Unlock an inode.
87065789Smckusick */
87165789Smckusick int
cd9660_unlock(ap)87265855Smckusick cd9660_unlock(ap)
87365789Smckusick struct vop_unlock_args /* {
87465789Smckusick struct vnode *a_vp;
87569427Smckusick int a_flags;
87669427Smckusick struct proc *a_p;
87765789Smckusick } */ *ap;
87865789Smckusick {
87969427Smckusick struct vnode *vp = ap->a_vp;
88065789Smckusick
88169427Smckusick return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE,
88269427Smckusick &vp->v_interlock, ap->a_p));
88365789Smckusick }
88465789Smckusick
88565789Smckusick /*
88665789Smckusick * Calculate the logical to physical mapping if not done already,
88765789Smckusick * then call the device strategy routine.
88865789Smckusick */
88965789Smckusick int
cd9660_strategy(ap)89065855Smckusick cd9660_strategy(ap)
89165789Smckusick struct vop_strategy_args /* {
89265789Smckusick struct buf *a_bp;
89365789Smckusick } */ *ap;
89465789Smckusick {
89565789Smckusick register struct buf *bp = ap->a_bp;
89665789Smckusick register struct vnode *vp = bp->b_vp;
89765789Smckusick register struct iso_node *ip;
89865789Smckusick int error;
89965789Smckusick
90065789Smckusick ip = VTOI(vp);
90165789Smckusick if (vp->v_type == VBLK || vp->v_type == VCHR)
90265855Smckusick panic("cd9660_strategy: spec");
90365789Smckusick if (bp->b_blkno == bp->b_lblkno) {
90465789Smckusick if (error =
90565789Smckusick VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) {
90665789Smckusick bp->b_error = error;
90765789Smckusick bp->b_flags |= B_ERROR;
90865789Smckusick biodone(bp);
90965789Smckusick return (error);
91065789Smckusick }
91165789Smckusick if ((long)bp->b_blkno == -1)
91265789Smckusick clrbuf(bp);
91365789Smckusick }
91465789Smckusick if ((long)bp->b_blkno == -1) {
91565789Smckusick biodone(bp);
91665789Smckusick return (0);
91765789Smckusick }
91865789Smckusick vp = ip->i_devvp;
91965789Smckusick bp->b_dev = vp->v_rdev;
92065789Smckusick VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
92165789Smckusick return (0);
92265789Smckusick }
92365789Smckusick
92465789Smckusick /*
92565789Smckusick * Print out the contents of an inode.
92665789Smckusick */
92765789Smckusick int
cd9660_print(ap)92865855Smckusick cd9660_print(ap)
92965789Smckusick struct vop_print_args /* {
93065789Smckusick struct vnode *a_vp;
93165789Smckusick } */ *ap;
93265789Smckusick {
93368052Smckusick
93465789Smckusick printf("tag VT_ISOFS, isofs vnode\n");
93567379Smkm return (0);
93665789Smckusick }
93765789Smckusick
93865789Smckusick /*
93968052Smckusick * Check for a locked inode.
94068052Smckusick */
94168052Smckusick int
cd9660_islocked(ap)94268052Smckusick cd9660_islocked(ap)
94368052Smckusick struct vop_islocked_args /* {
94468052Smckusick struct vnode *a_vp;
94568052Smckusick } */ *ap;
94668052Smckusick {
94768052Smckusick
94869427Smckusick return (lockstatus(&VTOI(ap->a_vp)->i_lock));
94968052Smckusick }
95068052Smckusick
95168052Smckusick /*
95268052Smckusick * Return POSIX pathconf information applicable to cd9660 filesystems.
95368052Smckusick */
95468052Smckusick int
cd9660_pathconf(ap)95568052Smckusick cd9660_pathconf(ap)
95668052Smckusick struct vop_pathconf_args /* {
95768052Smckusick struct vnode *a_vp;
95868052Smckusick int a_name;
95968052Smckusick register_t *a_retval;
96068052Smckusick } */ *ap;
96168052Smckusick {
96268052Smckusick
96368052Smckusick switch (ap->a_name) {
96468052Smckusick case _PC_LINK_MAX:
96568052Smckusick *ap->a_retval = 1;
96668052Smckusick return (0);
96768052Smckusick case _PC_NAME_MAX:
96868052Smckusick if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
96968052Smckusick *ap->a_retval = NAME_MAX;
97068052Smckusick else
97168052Smckusick *ap->a_retval = 37;
97268052Smckusick return (0);
97368052Smckusick case _PC_PATH_MAX:
97468052Smckusick *ap->a_retval = PATH_MAX;
97568052Smckusick return (0);
97668052Smckusick case _PC_PIPE_BUF:
97768052Smckusick *ap->a_retval = PIPE_BUF;
97868052Smckusick return (0);
97968052Smckusick case _PC_CHOWN_RESTRICTED:
98068052Smckusick *ap->a_retval = 1;
98168052Smckusick return (0);
98268052Smckusick case _PC_NO_TRUNC:
98368052Smckusick *ap->a_retval = 1;
98468052Smckusick return (0);
98568052Smckusick default:
98668052Smckusick return (EINVAL);
98768052Smckusick }
98868052Smckusick /* NOTREACHED */
98968052Smckusick }
99068052Smckusick
99168052Smckusick /*
99265789Smckusick * Global vfs data structures for isofs
99365789Smckusick */
99465855Smckusick #define cd9660_create \
99568681Smckusick ((int (*) __P((struct vop_create_args *)))eopnotsupp)
99668681Smckusick #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))eopnotsupp)
99768681Smckusick #define cd9660_write ((int (*) __P((struct vop_write_args *)))eopnotsupp)
99867652Smckusick #ifdef NFS
99967652Smckusick int lease_check __P((struct vop_lease_args *));
100067652Smckusick #define cd9660_lease_check lease_check
100167652Smckusick #else
100267652Smckusick #define cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop)
100367652Smckusick #endif
100465855Smckusick #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
100565855Smckusick #define cd9660_remove \
100668681Smckusick ((int (*) __P((struct vop_remove_args *)))eopnotsupp)
100768681Smckusick #define cd9660_link ((int (*) __P((struct vop_link_args *)))eopnotsupp)
100865855Smckusick #define cd9660_rename \
100968681Smckusick ((int (*) __P((struct vop_rename_args *)))eopnotsupp)
101068681Smckusick #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))eopnotsupp)
101168681Smckusick #define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))eopnotsupp)
101265855Smckusick #define cd9660_symlink \
101368681Smckusick ((int (*) __P((struct vop_symlink_args *)))eopnotsupp)
101465855Smckusick #define cd9660_advlock \
101568681Smckusick ((int (*) __P((struct vop_advlock_args *)))eopnotsupp)
101665855Smckusick #define cd9660_valloc ((int(*) __P(( \
101765789Smckusick struct vnode *pvp, \
101865789Smckusick int mode, \
101965789Smckusick struct ucred *cred, \
102068681Smckusick struct vnode **vpp))) eopnotsupp)
102168681Smckusick #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))eopnotsupp)
102265855Smckusick #define cd9660_truncate \
102368681Smckusick ((int (*) __P((struct vop_truncate_args *)))eopnotsupp)
102465855Smckusick #define cd9660_update \
102568681Smckusick ((int (*) __P((struct vop_update_args *)))eopnotsupp)
102665855Smckusick #define cd9660_bwrite \
102768681Smckusick ((int (*) __P((struct vop_bwrite_args *)))eopnotsupp)
102865789Smckusick
102965789Smckusick /*
103068052Smckusick * Global vfs data structures for cd9660
103165789Smckusick */
103265855Smckusick int (**cd9660_vnodeop_p)();
103365855Smckusick struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
103465789Smckusick { &vop_default_desc, vn_default_error },
103565855Smckusick { &vop_lookup_desc, cd9660_lookup }, /* lookup */
103665855Smckusick { &vop_create_desc, cd9660_create }, /* create */
103765855Smckusick { &vop_mknod_desc, cd9660_mknod }, /* mknod */
103865855Smckusick { &vop_open_desc, cd9660_open }, /* open */
103965855Smckusick { &vop_close_desc, cd9660_close }, /* close */
104065855Smckusick { &vop_access_desc, cd9660_access }, /* access */
104165855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */
104265855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */
104365855Smckusick { &vop_read_desc, cd9660_read }, /* read */
104465855Smckusick { &vop_write_desc, cd9660_write }, /* write */
104567652Smckusick { &vop_lease_desc, cd9660_lease_check },/* lease */
104665855Smckusick { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */
104765855Smckusick { &vop_select_desc, cd9660_select }, /* select */
104868454Smckusick { &vop_revoke_desc, cd9660_revoke }, /* revoke */
104965855Smckusick { &vop_mmap_desc, cd9660_mmap }, /* mmap */
105065855Smckusick { &vop_fsync_desc, cd9660_fsync }, /* fsync */
105165855Smckusick { &vop_seek_desc, cd9660_seek }, /* seek */
105265855Smckusick { &vop_remove_desc, cd9660_remove }, /* remove */
105365855Smckusick { &vop_link_desc, cd9660_link }, /* link */
105465855Smckusick { &vop_rename_desc, cd9660_rename }, /* rename */
105565855Smckusick { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */
105665855Smckusick { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */
105765855Smckusick { &vop_symlink_desc, cd9660_symlink }, /* symlink */
105865855Smckusick { &vop_readdir_desc, cd9660_readdir }, /* readdir */
105965855Smckusick { &vop_readlink_desc, cd9660_readlink },/* readlink */
106065855Smckusick { &vop_abortop_desc, cd9660_abortop }, /* abortop */
106165855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */
106265855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
106365855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */
106465855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */
106565855Smckusick { &vop_bmap_desc, cd9660_bmap }, /* bmap */
106665855Smckusick { &vop_strategy_desc, cd9660_strategy },/* strategy */
106765855Smckusick { &vop_print_desc, cd9660_print }, /* print */
106865855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */
106965855Smckusick { &vop_pathconf_desc, cd9660_pathconf },/* pathconf */
107065855Smckusick { &vop_advlock_desc, cd9660_advlock }, /* advlock */
107165855Smckusick { &vop_blkatoff_desc, cd9660_blkatoff },/* blkatoff */
107265855Smckusick { &vop_valloc_desc, cd9660_valloc }, /* valloc */
107365855Smckusick { &vop_vfree_desc, cd9660_vfree }, /* vfree */
107465855Smckusick { &vop_truncate_desc, cd9660_truncate },/* truncate */
107565855Smckusick { &vop_update_desc, cd9660_update }, /* update */
107665789Smckusick { &vop_bwrite_desc, vn_bwrite },
107765789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL }
107865789Smckusick };
107965855Smckusick struct vnodeopv_desc cd9660_vnodeop_opv_desc =
108065855Smckusick { &cd9660_vnodeop_p, cd9660_vnodeop_entries };
108165789Smckusick
108265789Smckusick /*
108365789Smckusick * Special device vnode ops
108465789Smckusick */
108565855Smckusick int (**cd9660_specop_p)();
108665855Smckusick struct vnodeopv_entry_desc cd9660_specop_entries[] = {
108765789Smckusick { &vop_default_desc, vn_default_error },
108865789Smckusick { &vop_lookup_desc, spec_lookup }, /* lookup */
108967891Smckusick { &vop_create_desc, spec_create }, /* create */
109067891Smckusick { &vop_mknod_desc, spec_mknod }, /* mknod */
109165789Smckusick { &vop_open_desc, spec_open }, /* open */
109265789Smckusick { &vop_close_desc, spec_close }, /* close */
109365855Smckusick { &vop_access_desc, cd9660_access }, /* access */
109465855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */
109565855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */
109665789Smckusick { &vop_read_desc, spec_read }, /* read */
109765789Smckusick { &vop_write_desc, spec_write }, /* write */
109867652Smckusick { &vop_lease_desc, spec_lease_check }, /* lease */
109965789Smckusick { &vop_ioctl_desc, spec_ioctl }, /* ioctl */
110065789Smckusick { &vop_select_desc, spec_select }, /* select */
110168454Smckusick { &vop_revoke_desc, spec_revoke }, /* revoke */
110265789Smckusick { &vop_mmap_desc, spec_mmap }, /* mmap */
110365789Smckusick { &vop_fsync_desc, spec_fsync }, /* fsync */
110465789Smckusick { &vop_seek_desc, spec_seek }, /* seek */
110567891Smckusick { &vop_remove_desc, spec_remove }, /* remove */
110667891Smckusick { &vop_link_desc, spec_link }, /* link */
110767891Smckusick { &vop_rename_desc, spec_rename }, /* rename */
110867891Smckusick { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
110967891Smckusick { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
111067891Smckusick { &vop_symlink_desc, spec_symlink }, /* symlink */
111165789Smckusick { &vop_readdir_desc, spec_readdir }, /* readdir */
111265789Smckusick { &vop_readlink_desc, spec_readlink }, /* readlink */
111365789Smckusick { &vop_abortop_desc, spec_abortop }, /* abortop */
111465855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */
111565855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
111665855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */
111765855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */
111865789Smckusick { &vop_bmap_desc, spec_bmap }, /* bmap */
111967891Smckusick { &vop_strategy_desc, spec_strategy }, /* strategy */
112065855Smckusick { &vop_print_desc, cd9660_print }, /* print */
112165855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */
112265789Smckusick { &vop_pathconf_desc, spec_pathconf }, /* pathconf */
112365789Smckusick { &vop_advlock_desc, spec_advlock }, /* advlock */
112465789Smckusick { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */
112565789Smckusick { &vop_valloc_desc, spec_valloc }, /* valloc */
112665789Smckusick { &vop_vfree_desc, spec_vfree }, /* vfree */
112765789Smckusick { &vop_truncate_desc, spec_truncate }, /* truncate */
112865855Smckusick { &vop_update_desc, cd9660_update }, /* update */
112965789Smckusick { &vop_bwrite_desc, vn_bwrite },
113065789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL }
113165789Smckusick };
113265855Smckusick struct vnodeopv_desc cd9660_specop_opv_desc =
113365855Smckusick { &cd9660_specop_p, cd9660_specop_entries };
113465789Smckusick
113565789Smckusick #ifdef FIFO
113665855Smckusick int (**cd9660_fifoop_p)();
113765855Smckusick struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
113865789Smckusick { &vop_default_desc, vn_default_error },
113965789Smckusick { &vop_lookup_desc, fifo_lookup }, /* lookup */
114067891Smckusick { &vop_create_desc, fifo_create }, /* create */
114167891Smckusick { &vop_mknod_desc, fifo_mknod }, /* mknod */
114265789Smckusick { &vop_open_desc, fifo_open }, /* open */
114365789Smckusick { &vop_close_desc, fifo_close }, /* close */
114465855Smckusick { &vop_access_desc, cd9660_access }, /* access */
114565855Smckusick { &vop_getattr_desc, cd9660_getattr }, /* getattr */
114665855Smckusick { &vop_setattr_desc, cd9660_setattr }, /* setattr */
114765789Smckusick { &vop_read_desc, fifo_read }, /* read */
114865789Smckusick { &vop_write_desc, fifo_write }, /* write */
114967652Smckusick { &vop_lease_desc, fifo_lease_check }, /* lease */
115065789Smckusick { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
115165789Smckusick { &vop_select_desc, fifo_select }, /* select */
115268454Smckusick { &vop_revoke_desc, fifo_revoke }, /* revoke */
115365789Smckusick { &vop_mmap_desc, fifo_mmap }, /* mmap */
115465789Smckusick { &vop_fsync_desc, fifo_fsync }, /* fsync */
115565789Smckusick { &vop_seek_desc, fifo_seek }, /* seek */
115667891Smckusick { &vop_remove_desc, fifo_remove }, /* remove */
115767891Smckusick { &vop_link_desc, fifo_link } , /* link */
115867891Smckusick { &vop_rename_desc, fifo_rename }, /* rename */
115967891Smckusick { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */
116067891Smckusick { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */
116167891Smckusick { &vop_symlink_desc, fifo_symlink }, /* symlink */
116265789Smckusick { &vop_readdir_desc, fifo_readdir }, /* readdir */
116365789Smckusick { &vop_readlink_desc, fifo_readlink }, /* readlink */
116465789Smckusick { &vop_abortop_desc, fifo_abortop }, /* abortop */
116565855Smckusick { &vop_inactive_desc, cd9660_inactive },/* inactive */
116665855Smckusick { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
116765855Smckusick { &vop_lock_desc, cd9660_lock }, /* lock */
116865855Smckusick { &vop_unlock_desc, cd9660_unlock }, /* unlock */
116965789Smckusick { &vop_bmap_desc, fifo_bmap }, /* bmap */
117067891Smckusick { &vop_strategy_desc, fifo_strategy }, /* strategy */
117165855Smckusick { &vop_print_desc, cd9660_print }, /* print */
117265855Smckusick { &vop_islocked_desc, cd9660_islocked },/* islocked */
117365789Smckusick { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */
117465789Smckusick { &vop_advlock_desc, fifo_advlock }, /* advlock */
117565789Smckusick { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */
117665789Smckusick { &vop_valloc_desc, fifo_valloc }, /* valloc */
117765789Smckusick { &vop_vfree_desc, fifo_vfree }, /* vfree */
117865789Smckusick { &vop_truncate_desc, fifo_truncate }, /* truncate */
117965855Smckusick { &vop_update_desc, cd9660_update }, /* update */
118065789Smckusick { &vop_bwrite_desc, vn_bwrite },
118165789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL }
118265789Smckusick };
118365855Smckusick struct vnodeopv_desc cd9660_fifoop_opv_desc =
118465855Smckusick { &cd9660_fifoop_p, cd9660_fifoop_entries };
118565789Smckusick #endif /* FIFO */
1186