|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* $NetBSD: cd9660_vnops.c,v 1.22 1994/12/27 19:05:12 mycroft Exp $ */
23:
24: /*-
25: * Copyright (c) 1994
26: * The Regents of the University of California. All rights reserved.
27: *
28: * This code is derived from software contributed to Berkeley
29: * by Pace Willisson ([email protected]). The Rock Ridge Extension
30: * Support code is derived from software contributed to Berkeley
31: * by Atsushi Murai ([email protected]).
32: *
33: * Redistribution and use in source and binary forms, with or without
34: * modification, are permitted provided that the following conditions
35: * are met:
36: * 1. Redistributions of source code must retain the above copyright
37: * notice, this list of conditions and the following disclaimer.
38: * 2. Redistributions in binary form must reproduce the above copyright
39: * notice, this list of conditions and the following disclaimer in the
40: * documentation and/or other materials provided with the distribution.
41: * 3. All advertising materials mentioning features or use of this software
42: * must display the following acknowledgement:
43: * This product includes software developed by the University of
44: * California, Berkeley and its contributors.
45: * 4. Neither the name of the University nor the names of its contributors
46: * may be used to endorse or promote products derived from this software
47: * without specific prior written permission.
48: *
49: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59: * SUCH DAMAGE.
60: *
61: * @(#)cd9660_vnops.c 8.15 (Berkeley) 12/5/94
62: *
63: * HISTORY
64: * 02-Feb-00 chw Add cd9660_copyfile to return error
65: * 29-Sep-98 djb Add cd9660_getattrlist VOP for VDI support.
66: * 15-sep-98 added cd9660_rmdir to do proper unlocking - chw
67: * 12-aug-98 added cd9660_remove which will do proper unlocking - chw
68: * 17-Feb-98 radar 1669467 - changed lock protocols to use the lock manager - chw
69: * 22-Jan-98 radar 1669467 - ISO 9660 CD support - jwc
70: */
71:
72: #include <sys/param.h>
73: #include <sys/systm.h>
74: #include <sys/namei.h>
75: #include <sys/resourcevar.h>
76: #include <sys/kernel.h>
77: #include <sys/file.h>
78: #include <sys/stat.h>
79: #include <sys/buf.h>
80: #include <sys/proc.h>
81: #include <sys/conf.h>
82: #include <sys/mount.h>
83: #include <sys/vnode.h>
84: #include <miscfs/specfs/specdev.h>
85: #include <miscfs/fifofs/fifo.h>
86: #include <sys/malloc.h>
87: #include <sys/dir.h>
88: #include <sys/attr.h>
89: #include <vfs/vfs_support.h>
90:
91: // radar 1669467 Using the lock manager now so include lock.h
92: #include <sys/lock.h>
93:
94: #include <isofs/cd9660/iso.h>
95: #include <isofs/cd9660/cd9660_node.h>
96: #include <isofs/cd9660/iso_rrip.h>
97:
98:
99: #if 0
100: /*
101: * Mknod vnode call
102: * Actually remap the device number
103: */
104: cd9660_mknod(ndp, vap, cred, p)
105: struct nameidata *ndp;
106: struct ucred *cred;
107: struct vattr *vap;
108: struct proc *p;
109: {
110: #ifndef ISODEVMAP
111: FREE_ZONE(ndp->ni_pnbuf, ndp->ni_pnlen, M_NAMEI);
112: vput(ndp->ni_dvp);
113: vput(ndp->ni_vp);
114: return (EINVAL);
115: #else
116: register struct vnode *vp;
117: struct iso_node *ip;
118: struct iso_dnode *dp;
119: int error;
120:
121: vp = ndp->ni_vp;
122: ip = VTOI(vp);
123:
124: if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP
125: || vap->va_type != vp->v_type
126: || (vap->va_type != VCHR && vap->va_type != VBLK)) {
127: FREE_ZONE(ndp->ni_pnbuf, ndp->ni_pnlen, M_NAMEI);
128: vput(ndp->ni_dvp);
129: vput(ndp->ni_vp);
130: return (EINVAL);
131: }
132:
133: dp = iso_dmap(ip->i_dev,ip->i_number,1);
134: if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) {
135: /* same as the unmapped one, delete the mapping */
136: remque(dp);
137: FREE(dp,M_CACHE);
138: } else
139: /* enter new mapping */
140: dp->d_dev = vap->va_rdev;
141:
142: /*
143: * Remove inode so that it will be reloaded by iget and
144: * checked to see if it is an alias of an existing entry
145: * in the inode cache.
146: */
147: vput(vp);
148: vp->v_type = VNON;
149: vgone(vp);
150: return (0);
151: #endif
152: }
153: #endif
154:
155: /*
156: * Open called.
157: *
158: * Nothing to do.
159: */
160: /* ARGSUSED */
161: int
162: cd9660_open(ap)
163: struct vop_open_args /* {
164: struct vnode *a_vp;
165: int a_mode;
166: struct ucred *a_cred;
167: struct proc *a_p;
168: } */ *ap;
169: {
170: return (0);
171: }
172:
173: /*
174: * Close called
175: *
176: * Update the times on the inode on writeable file systems.
177: */
178: /* ARGSUSED */
179: int
180: cd9660_close(ap)
181: struct vop_close_args /* {
182: struct vnode *a_vp;
183: int a_fflag;
184: struct ucred *a_cred;
185: struct proc *a_p;
186: } */ *ap;
187: {
188: return (0);
189: }
190:
191: /*
192: * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
193: * The mode is shifted to select the owner/group/other fields. The
194: * super user is granted all permissions.
195: */
196: /* ARGSUSED */
197: int
198: cd9660_access(ap)
199: struct vop_access_args /* {
200: struct vnode *a_vp;
201: int a_mode;
202: struct ucred *a_cred;
203: struct proc *a_p;
204: } */ *ap;
205: {
206: struct vnode *vp = ap->a_vp;
207: struct iso_node *ip = VTOI(vp);
208: struct ucred *cred = ap->a_cred;
209: mode_t mask, mode = ap->a_mode;
210: register gid_t *gp;
211: int i, error;
212:
213: /*
214: * Disallow write attempts on read-only file systems;
215: * unless the file is a socket, fifo, or a block or
216: * character device resident on the file system.
217: */
218: if (mode & VWRITE) {
219: switch (vp->v_type) {
220: case VDIR:
221: case VLNK:
222: case VREG:
223: if (vp->v_mount->mnt_flag & MNT_RDONLY)
224: return (EROFS);
225: #if QUOTA
226: if ( (error = getinoquota(ip)) )
227: return (error);
228: #endif
229: break;
230: default: // radar 1669467 - fix compiler warning
231: break;
232: }
233: }
234:
235: /* If immutable bit set, nobody gets to write it. */
236: if ((mode & VWRITE) && (ip->i_flag & IMMUTABLE))
237: return (EPERM);
238:
239: /* Otherwise, user id 0 always gets access. */
240: if (cred->cr_uid == 0)
241: return (0);
242:
243: mask = 0;
244:
245: /* Otherwise, check the owner. */
246: if (cred->cr_uid == ip->inode.iso_uid) {
247: if (mode & VEXEC)
248: mask |= S_IXUSR;
249: if (mode & VREAD)
250: mask |= S_IRUSR;
251: if (mode & VWRITE)
252: mask |= S_IWUSR;
253: return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
254: }
255:
256: /* Otherwise, check the groups. */
257: for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
258: if (ip->inode.iso_gid == *gp) {
259: if (mode & VEXEC)
260: mask |= S_IXGRP;
261: if (mode & VREAD)
262: mask |= S_IRGRP;
263: if (mode & VWRITE)
264: mask |= S_IWGRP;
265: return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
266: }
267:
268: /* Otherwise, check everyone else. */
269: if (mode & VEXEC)
270: mask |= S_IXOTH;
271: if (mode & VREAD)
272: mask |= S_IROTH;
273: if (mode & VWRITE)
274: mask |= S_IWOTH;
275: return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
276: }
277:
278: int
279: cd9660_getattr(ap)
280: struct vop_getattr_args /* {
281: struct vnode *a_vp;
282: struct vattr *a_vap;
283: struct ucred *a_cred;
284: struct proc *a_p;
285: } */ *ap;
286:
287: {
288: struct vnode *vp = ap->a_vp;
289: register struct vattr *vap = ap->a_vap;
290: register struct iso_node *ip = VTOI(vp);
291:
292: vap->va_fsid = ip->i_dev;
293: vap->va_fileid = ip->i_number;
294:
295: vap->va_mode = ip->inode.iso_mode;
296: vap->va_nlink = ip->inode.iso_links;
297: vap->va_uid = ip->inode.iso_uid;
298: vap->va_gid = ip->inode.iso_gid;
299: vap->va_atime = ip->inode.iso_atime;
300: vap->va_mtime = ip->inode.iso_mtime;
301: vap->va_ctime = ip->inode.iso_ctime;
302: vap->va_rdev = ip->inode.iso_rdev;
303:
304: vap->va_size = (u_quad_t) ip->i_size;
305: if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) {
306: struct vop_readlink_args rdlnk;
307: struct iovec aiov;
308: struct uio auio;
309: char *cp;
310:
311: MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
312: aiov.iov_base = cp;
313: aiov.iov_len = MAXPATHLEN;
314: auio.uio_iov = &aiov;
315: auio.uio_iovcnt = 1;
316: auio.uio_offset = 0;
317: auio.uio_rw = UIO_READ;
318: auio.uio_segflg = UIO_SYSSPACE;
319: auio.uio_procp = ap->a_p;
320: auio.uio_resid = MAXPATHLEN;
321: rdlnk.a_uio = &auio;
322: rdlnk.a_vp = ap->a_vp;
323: rdlnk.a_cred = ap->a_cred;
324: if (cd9660_readlink(&rdlnk) == 0)
325: vap->va_size = MAXPATHLEN - auio.uio_resid;
326: FREE(cp, M_TEMP);
327: }
328: vap->va_flags = 0;
329: vap->va_gen = 1;
330: vap->va_blocksize = ip->i_mnt->logical_block_size;
331: vap->va_bytes = (u_quad_t) ip->i_size;
332: vap->va_type = vp->v_type;
333:
334: return (0);
335: }
336:
337: #if ISO_DEFAULT_BLOCK_SIZE >= NBPG
338: #ifdef DEBUG
339: extern int doclusterread;
340: #else
341: #define doclusterread 1
342: #endif
343: #else
344: /* XXX until cluster routines can handle block sizes less than one page */
345: #define doclusterread 0
346: #endif
347:
348: /*
349: * Vnode op for reading.
350: */
351: int
352: cd9660_read(ap)
353: struct vop_read_args /* {
354: struct vnode *a_vp;
355: struct uio *a_uio;
356: int a_ioflag;
357: struct ucred *a_cred;
358: } */ *ap;
359: {
360: struct vnode *vp = ap->a_vp;
361: register struct uio *uio = ap->a_uio;
362: register struct iso_node *ip = VTOI(vp);
363: register struct iso_mnt *imp;
364: struct buf *bp;
365: daddr_t lbn, rablock;
366: off_t diff;
367: int rasize, error = 0;
368: long size, n, on;
369: #ifdef NeXT
370: int firstpass;
371: int seq;
372: int devBlockSize;
373: #endif /* NeXT */
374:
375: if (uio->uio_resid == 0)
376: return (0);
377: if (uio->uio_offset < 0)
378: return (EINVAL);
379: ip->i_flag |= IN_ACCESS;
380: imp = ip->i_mnt;
381: #ifdef NeXT
382: firstpass=TRUE;
383: VOP_DEVBLOCKSIZE(ip->i_devvp, &devBlockSize);
384: #endif /* NeXT */
385: do {
386: lbn = lblkno(imp, uio->uio_offset);
387: on = blkoff(imp, uio->uio_offset);
388: n = min((u_int)(imp->logical_block_size - on),
389: uio->uio_resid);
390: diff = (off_t)ip->i_size - uio->uio_offset;
391: if (diff <= 0)
392: return (0);
393: if (diff < n)
394: n = diff;
395: size = blksize(imp, ip, lbn);
396: rablock = lbn + 1;
397: if (doclusterread) {
398: if (lblktosize(imp, rablock) <= ip->i_size)
399: #ifdef NeXT
400: error = cluster_read(vp, (off_t)ip->i_size,
401: lbn, size, NOCRED, &bp, devBlockSize,
402: firstpass, (uio->uio_resid + on), &seq);
403: #else
404: error = cluster_read(vp, (off_t)ip->i_size,
405: lbn, size, NOCRED, &bp);
406: #endif /* NeXT */
407: else
408: error = bread(vp, lbn, size, NOCRED, &bp);
409: } else {
410: if (vp->v_lastr + 1 == lbn &&
411: lblktosize(imp, rablock) < ip->i_size) {
412: rasize = blksize(imp, ip, rablock);
413: error = breadn(vp, lbn, size, &rablock,
414: &rasize, 1, NOCRED, &bp);
415: } else
416: error = bread(vp, lbn, size, NOCRED, &bp);
417: }
418: vp->v_lastr = lbn;
419: n = min(n, size - bp->b_resid);
420: if (error) {
421: brelse(bp);
422: return (error);
423: }
424:
425: error = uiomove(bp->b_data + on, (int)n, uio);
426: if (n + on == imp->logical_block_size ||
427: uio->uio_offset == (off_t)ip->i_size)
428: bp->b_flags |= B_AGE;
429: brelse(bp);
430: firstpass = FALSE;
431: } while (error == 0 && uio->uio_resid > 0 && n != 0);
432: return (error);
433: }
434:
435: /* ARGSUSED */
436: int
437: cd9660_ioctl(ap)
438: struct vop_ioctl_args /* {
439: struct vnode *a_vp;
440: u_long a_command;
441: caddr_t a_data;
442: int a_fflag;
443: struct ucred *a_cred;
444: struct proc *a_p;
445: } */ *ap;
446: {
447: printf("You did ioctl for isofs !!\n");
448: return (ENOTTY);
449: }
450:
451: /* ARGSUSED */
452: int
453: cd9660_select(ap)
454: struct vop_select_args /* {
455: struct vnode *a_vp;
456: int a_which;
457: int a_fflags;
458: struct ucred *a_cred;
459: struct proc *a_p;
460: } */ *ap;
461: {
462: /*
463: * We should really check to see if I/O is possible.
464: */
465: return (1);
466: }
467:
468: /*
469: * Mmap a file
470: *
471: * NB Currently unsupported.
472: */
473: /* ARGSUSED */
474: int
475: cd9660_mmap(ap)
476: struct vop_mmap_args /* {
477: struct vnode *a_vp;
478: int a_fflags;
479: struct ucred *a_cred;
480: struct proc *a_p;
481: } */ *ap;
482: {
483:
484: return (EINVAL);
485: }
486:
487: /*
488: * Seek on a file
489: *
490: * Nothing to do, so just return.
491: */
492: /* ARGSUSED */
493: int
494: cd9660_seek(ap)
495: struct vop_seek_args /* {
496: struct vnode *a_vp;
497: off_t a_oldoff;
498: off_t a_newoff;
499: struct ucred *a_cred;
500: } */ *ap;
501: {
502:
503: return (0);
504: }
505:
506: /*
507: * Structure for reading directories
508: */
509: struct isoreaddir {
510: struct dirent saveent;
511: struct dirent assocent;
512: struct dirent current;
513: off_t saveoff;
514: off_t assocoff;
515: off_t curroff;
516: struct uio *uio;
517: off_t uio_off;
518: int eofflag;
519: // u_long **cookies;
520: // int *ncookies;
521: };
522:
523: int
524: iso_uiodir(idp,dp,off)
525: struct isoreaddir *idp;
526: struct dirent *dp;
527: off_t off;
528: {
529: int error;
530:
531: dp->d_name[dp->d_namlen] = 0;
532: dp->d_reclen = DIRSIZ(dp);
533:
534: if (idp->uio->uio_resid < dp->d_reclen) {
535: idp->eofflag = 0;
536: return (-1);
537: }
538:
539: #if 0
540: if (idp->cookies) {
541: if (*idp->ncookies <= 0) {
542: idp->eofflag = 0;
543: return (-1);
544: }
545:
546: **idp->cookies++ = off;
547: --*idp->ncookies;
548: }
549: #endif
550:
551: if ( (error = uiomove( (caddr_t)dp, dp->d_reclen, idp->uio )) )
552: return (error);
553: idp->uio_off = off;
554: return (0);
555: }
556:
557: int
558: iso_shipdir(idp)
559: struct isoreaddir *idp;
560: {
561: struct dirent *dp;
562: int cl, sl, assoc;
563: int error;
564: char *cname, *sname;
565:
566: cl = idp->current.d_namlen;
567: cname = idp->current.d_name;
568: assoc = (cl > 1) && (*cname == ASSOCCHAR );
569: if (assoc) {
570: cl--;
571: cname++;
572: }
573:
574: dp = &idp->saveent;
575: sname = dp->d_name;
576: if (!(sl = dp->d_namlen)) {
577: dp = &idp->assocent;
578: sname = dp->d_name + 1;
579: sl = dp->d_namlen - 1;
580: }
581: if (sl > 0) {
582: if (sl != cl
583: || bcmp(sname,cname,sl)) {
584: if (idp->assocent.d_namlen) {
585: if ( (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) )
586: return (error);
587: idp->assocent.d_namlen = 0;
588: }
589: if (idp->saveent.d_namlen) {
590: if ( (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) )
591: return (error);
592: idp->saveent.d_namlen = 0;
593: }
594: }
595: }
596: idp->current.d_reclen = DIRSIZ(&idp->current);
597: if (assoc) {
598: idp->assocoff = idp->curroff;
599: bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);
600: } else {
601: idp->saveoff = idp->curroff;
602: bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
603: }
604: return (0);
605: }
606:
607: /*
608: * Vnode op for readdir
609: */
610: int
611: cd9660_readdir(ap)
612: struct vop_readdir_args /* {
613: struct vnodeop_desc *a_desc;
614: struct vnode *a_vp;
615: struct uio *a_uio;
616: struct ucred *a_cred;
617: int *a_eofflag;
618: int *a_ncookies;
619: u_long **a_cookies;
620: } */ *ap;
621: {
622: register struct uio *uio = ap->a_uio;
623: off_t startingOffset = uio->uio_offset;
624: size_t lost = 0;
625: struct isoreaddir *idp;
626: struct vnode *vdp = ap->a_vp;
627: struct iso_node *dp;
628: struct iso_mnt *imp;
629: struct buf *bp = NULL;
630: struct iso_directory_record *ep;
631: int entryoffsetinblock;
632: doff_t endsearch;
633: u_long bmask;
634: int error = 0;
635: int reclen;
636: u_short namelen;
637:
638: dp = VTOI(vdp);
639: imp = dp->i_mnt;
640: bmask = imp->im_bmask;
641:
642: MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK);
643: idp->saveent.d_namlen = idp->assocent.d_namlen = 0;
644: /*
645: * XXX
646: * Is it worth trying to figure out the type?
647: */
648: idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
649: DT_UNKNOWN;
650: idp->uio = uio;
651: idp->eofflag = 1;
652: idp->curroff = uio->uio_offset;
653:
654: if ((entryoffsetinblock = idp->curroff & bmask) &&
655: (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) {
656: FREE(idp, M_TEMP);
657: return (error);
658: }
659: endsearch = dp->i_size;
660:
661: while (idp->curroff < endsearch) {
662: /*
663: * If offset is on a block boundary,
664: * read the next directory block.
665: * Release previous if it exists.
666: */
667: if ((idp->curroff & bmask) == 0) {
668: if (bp != NULL)
669: brelse(bp);
670: if ( (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp)) )
671: break;
672: entryoffsetinblock = 0;
673: }
674: /*
675: * Get pointer to next entry.
676: */
677: ep = (struct iso_directory_record *)
678: ((char *)bp->b_data + entryoffsetinblock);
679:
680: reclen = isonum_711(ep->length);
681: if (reclen == 0) {
682: /* skip to next block, if any */
683: idp->curroff =
684: (idp->curroff & ~bmask) + imp->logical_block_size;
685: continue;
686: }
687:
688: if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
689: error = EINVAL;
690: /* illegal entry, stop */
691: break;
692: }
693:
694: if (entryoffsetinblock + reclen > imp->logical_block_size) {
695: error = EINVAL;
696: /* illegal directory, so stop looking */
697: break;
698: }
699:
700: idp->current.d_namlen = isonum_711(ep->name_len);
701:
702: if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
703: error = EINVAL;
704: /* illegal entry, stop */
705: break;
706: }
707:
708: #if 1 // radar 1669467 - make it pretty
709: if ( isonum_711(ep->flags) & directoryBit )
710: #else
711: if (isonum_711(ep->flags)&2)
712: #endif // radar 1669467
713: idp->current.d_fileno = isodirino(ep, imp);
714: else
715: {
716:
717: #if 1 // radar 1669467
718: idp->current.d_fileno = (bp->b_blkno << imp->im_bshift) + entryoffsetinblock;
719: #else
720: idp->current.d_fileno = dbtob(bp->b_blkno) + entryoffsetinblock;
721: #endif // radar 1669467
722:
723: }
724:
725: idp->curroff += reclen;
726:
727: switch (imp->iso_ftype) {
728: case ISO_FTYPE_RRIP:
729: cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
730: &idp->current.d_fileno,imp);
731: idp->current.d_namlen = (u_char)namelen;
732: if (idp->current.d_namlen)
733: error = iso_uiodir(idp,&idp->current,idp->curroff);
734: break;
735: default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */
736: strcpy(idp->current.d_name,"..");
737: switch (ep->name[0]) {
738: case 0:
739: idp->current.d_namlen = 1;
740: error = iso_uiodir(idp,&idp->current,idp->curroff);
741: break;
742: case 1:
743: idp->current.d_namlen = 2;
744: error = iso_uiodir(idp,&idp->current,idp->curroff);
745: break;
746: default:
747: isofntrans(ep->name,idp->current.d_namlen,
748: idp->current.d_name, &namelen,
749: imp->iso_ftype == ISO_FTYPE_9660,
750: isonum_711(ep->flags) & associatedBit);
751: idp->current.d_namlen = (u_char)namelen;
752: if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
753: error = iso_shipdir(idp);
754: else
755: error = iso_uiodir(idp,&idp->current,idp->curroff);
756: break;
757: }
758: }
759: if (error)
760: break;
761:
762: entryoffsetinblock += reclen;
763: }
764:
765: if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
766: idp->current.d_namlen = 0;
767: error = iso_shipdir(idp);
768: }
769:
770: if (!error && ap->a_ncookies) {
771: struct dirent *dp, *dpstart;
772: off_t bufferOffset;
773: u_long *cookies;
774: int ncookies;
775:
776: /*
777: * Only the NFS server uses cookies, and it loads the
778: * directory block into system space, so we can just look at
779: * it directly.
780: *
781: * We assume the entire transfer is done to a single contiguous buffer.
782: */
783: if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
784: panic("ufs_readdir: lost in space");
785:
786: /*
787: * Make a first pass over the buffer just generated,
788: * counting the number of entries:
789: */
790: dpstart = (struct dirent *) (uio->uio_iov->iov_base - (uio->uio_offset - startingOffset));
791: for (dp = dpstart, bufferOffset = startingOffset, ncookies = 0;
792: bufferOffset < uio->uio_offset; ) {
793: if (dp->d_reclen == 0)
794: break;
795: bufferOffset += dp->d_reclen;
796: ncookies++;
797: dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
798: }
799: lost += uio->uio_offset - bufferOffset;
800: uio->uio_offset = bufferOffset;
801:
802: /*
803: * Allocate a buffer to hold the cookies requested:
804: */
805: MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP, M_WAITOK);
806: *ap->a_ncookies = ncookies;
807: *ap->a_cookies = cookies;
808:
809: /*
810: * Fill in the offsets for each entry in the buffer just allocated:
811: */
812: for (bufferOffset = startingOffset, dp = dpstart; bufferOffset < uio->uio_offset; ) {
813: *(cookies++) = bufferOffset;
814: bufferOffset += dp->d_reclen;
815: dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
816: }
817: }
818:
819: if (error < 0)
820: error = 0;
821:
822: if (bp)
823: brelse (bp);
824:
825: uio->uio_offset = idp->uio_off;
826: *ap->a_eofflag = idp->eofflag;
827:
828: FREE(idp, M_TEMP);
829:
830: return (error);
831: }
832:
833: /*
834: * Return target name of a symbolic link
835: * Shouldn't we get the parent vnode and read the data from there?
836: * This could eventually result in deadlocks in cd9660_lookup.
837: * But otherwise the block read here is in the block buffer two times.
838: */
839: typedef struct iso_directory_record ISODIR;
840: typedef struct iso_node ISONODE;
841: typedef struct iso_mnt ISOMNT;
842: int
843: cd9660_readlink(ap)
844: struct vop_readlink_args /* {
845: struct vnode *a_vp;
846: struct uio *a_uio;
847: struct ucred *a_cred;
848: } */ *ap;
849: {
850: ISONODE *ip;
851: ISODIR *dirp;
852: ISOMNT *imp;
853: struct buf *bp;
854: struct uio *uio;
855: u_short symlen;
856: int error;
857: char *symname;
858:
859: ip = VTOI(ap->a_vp);
860: imp = ip->i_mnt;
861: uio = ap->a_uio;
862:
863: if (imp->iso_ftype != ISO_FTYPE_RRIP)
864: return (EINVAL);
865:
866: /*
867: * Get parents directory record block that this inode included.
868: */
869: error = bread(imp->im_devvp,
870: #if 1 // radar 1669467
871: (ip->i_number >> imp->im_bshift),
872: #else
873: (ip->i_number >> imp->im_bshift) << (imp->im_bshift - DEV_BSHIFT),
874: #endif // radar 1669467
875: imp->logical_block_size, NOCRED, &bp);
876: if (error) {
877: brelse(bp);
878: return (EINVAL);
879: }
880:
881: /*
882: * Setup the directory pointer for this inode
883: */
884: dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask));
885:
886: /*
887: * Just make sure, we have a right one....
888: * 1: Check not cross boundary on block
889: */
890: if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
891: > imp->logical_block_size) {
892: brelse(bp);
893: return (EINVAL);
894: }
895:
896: /*
897: * Now get a buffer
898: * Abuse a namei buffer for now.
899: */
900: if (uio->uio_segflg == UIO_SYSSPACE)
901: symname = uio->uio_iov->iov_base;
902: else
903: MALLOC_ZONE(symname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
904:
905: /*
906: * Ok, we just gathering a symbolic name in SL record.
907: */
908: if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
909: if (uio->uio_segflg != UIO_SYSSPACE)
910: FREE_ZONE(symname, MAXPATHLEN, M_NAMEI);
911: brelse(bp);
912: return (EINVAL);
913: }
914: /*
915: * Don't forget before you leave from home ;-)
916: */
917: brelse(bp);
918:
919: /*
920: * return with the symbolic name to caller's.
921: */
922: if (uio->uio_segflg != UIO_SYSSPACE) {
923: error = uiomove(symname, symlen, uio);
924: FREE_ZONE(symname, MAXPATHLEN, M_NAMEI);
925: return (error);
926: }
927: uio->uio_resid -= symlen;
928: uio->uio_iov->iov_base += symlen;
929: uio->uio_iov->iov_len -= symlen;
930: return (0);
931: }
932:
933: /*
934: * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
935: * done. If a buffer has been saved in anticipation of a CREATE, delete it.
936: */
937: int
938: cd9660_abortop(ap)
939: struct vop_abortop_args /* {
940: struct vnode *a_dvp;
941: struct componentname *a_cnp;
942: } */ *ap;
943: {
944: if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
945: FREE_ZONE(ap->a_cnp->cn_pnbuf, ap->a_cnp->cn_pnlen, M_NAMEI);
946: return (0);
947: }
948:
949: /*
950: * Lock an inode.
951: */
952:
953: // radar 1669467 - changed ap struct too!!!
954: // radar 1669467 - chw changed implementation to use the lock manager. This is a delta from
955: // what we first did with the radar. This is now basically identical to ufs_lock.
956: int
957: cd9660_lock(ap)
958: struct vop_lock_args /* {
959: struct vnode *a_vp;
960: int a_flags;
961: struct proc *a_p;
962: } */ *ap;
963: {
964: struct vnode *vp = ap->a_vp;
965:
966: if (VTOI(vp) == (struct inode *) NULL)
967: panic ("cd9660 inode in vnode is null\n");
968: return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock,ap->a_p));
969: }
970:
971: /*
972: * Unlock an inode.
973: */
974:
975: // radar 1669467 - chw changed implementation to use the lock manager. As with lock, this is a
976: // delta from what we first did with the radar.
977:
978: int
979: cd9660_unlock(ap)
980: struct vop_unlock_args /* {
981: struct vnode *a_vp;
982: int a_flags;
983: struct proc *a_p;
984: } */ *ap;
985: {
986: struct vnode *vp = ap->a_vp;
987:
988: return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE, &vp->v_interlock,ap->a_p));
989:
990: }
991:
992: /*
993: * Calculate the logical to physical mapping if not done already,
994: * then call the device strategy routine.
995: */
996: int
997: cd9660_strategy(ap)
998: struct vop_strategy_args /* {
999: struct buf *a_bp;
1000: } */ *ap;
1001: {
1002: register struct buf *bp = ap->a_bp;
1003: register struct vnode *vp = bp->b_vp;
1004: register struct iso_node *ip;
1005: int error;
1006:
1007: ip = VTOI(vp);
1008: if (vp->v_type == VBLK || vp->v_type == VCHR)
1009: panic("cd9660_strategy: spec");
1010: if (bp->b_blkno == bp->b_lblkno) {
1011: if ( (error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) ) {
1012: bp->b_error = error;
1013: bp->b_flags |= B_ERROR;
1014: biodone(bp);
1015: return (error);
1016: }
1017: if ((long)bp->b_blkno == -1)
1018: clrbuf(bp);
1019: }
1020: if ((long)bp->b_blkno == -1) {
1021: biodone(bp);
1022: return (0);
1023: }
1024: vp = ip->i_devvp;
1025: bp->b_dev = vp->v_rdev;
1026: VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
1027: return (0);
1028: }
1029:
1030: /*
1031: * Print out the contents of an inode.
1032: */
1033: int
1034: cd9660_print(ap)
1035: struct vop_print_args /* {
1036: struct vnode *a_vp;
1037: } */ *ap;
1038: {
1039:
1040: printf("tag VT_ISOFS, isofs vnode\n");
1041: return (0);
1042: }
1043:
1044: /*
1045: * Check for a locked inode.
1046: */
1047: // radar 1669467 changed this to use the lock manager - chw
1048:
1049: int
1050: cd9660_islocked(ap)
1051: struct vop_islocked_args /* {
1052: struct vnode *a_vp;
1053: } */ *ap;
1054: {
1055:
1056: return (lockstatus(&VTOI(ap->a_vp)->i_lock));
1057: }
1058:
1059: /*
1060: * Return POSIX pathconf information applicable to cd9660 filesystems.
1061: */
1062: int
1063: cd9660_pathconf(ap)
1064: struct vop_pathconf_args /* {
1065: struct vnode *a_vp;
1066: int a_name;
1067: register_t *a_retval;
1068: } */ *ap;
1069: {
1070:
1071: switch (ap->a_name) {
1072: case _PC_LINK_MAX:
1073: *ap->a_retval = 1;
1074: return (0);
1075: case _PC_NAME_MAX:
1076: if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
1077: *ap->a_retval = NAME_MAX;
1078: else
1079: *ap->a_retval = 37;
1080: return (0);
1081: case _PC_PATH_MAX:
1082: *ap->a_retval = PATH_MAX;
1083: return (0);
1084: case _PC_PIPE_BUF:
1085: *ap->a_retval = PIPE_BUF;
1086: return (0);
1087: case _PC_CHOWN_RESTRICTED:
1088: *ap->a_retval = 1;
1089: return (0);
1090: case _PC_NO_TRUNC:
1091: *ap->a_retval = 1;
1092: return (0);
1093: default:
1094: return (EINVAL);
1095: }
1096: /* NOTREACHED */
1097: }
1098:
1099: /*
1100: * Unsupported operation
1101: */
1102: int
1103: cd9660_enotsupp()
1104: {
1105:
1106: return (EOPNOTSUPP);
1107: }
1108: /* Pagein */
1109: int
1110: cd9660_pagein(ap)
1111: struct vop_pagein_args /* {
1112: struct vnode *a_vp;
1113: struct uio *a_uio;
1114: int a_ioflag;
1115: struct ucred *a_cred;
1116: } */ *ap;
1117: {
1118: /* pass thru to read */
1119: return (VOP_READ(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
1120: }
1121:
1122: /* Pageout */
1123: int
1124: cd9660_pageout(ap)
1125: struct vop_pageout_args /* {
1126: struct vnode *a_vp;
1127: struct uio *a_uio;
1128: int a_ioflag;
1129: struct ucred *a_cred;
1130: } */ *ap;
1131: {
1132: /* pass thru to write */
1133: return (VOP_WRITE(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
1134: }
1135:
1136: /*
1137: * cd9660_remove - not possible to remove a file from iso cds
1138: *
1139: * Locking policy: a_dvp and vp locked on entry, unlocked on exit
1140: */
1141: int
1142: cd9660_remove(ap)
1143: struct vop_remove_args /* { struct vnode *a_dvp; struct vnode *a_vp;
1144: struct componentname *a_cnp; } */ *ap;
1145: {
1146: if (ap->a_dvp == ap->a_vp)
1147: vrele(ap->a_vp);
1148: else
1149: vput(ap->a_vp);
1150: vput(ap->a_dvp);
1151:
1152: return (EROFS);
1153: }
1154:
1155:
1156: /*
1157: * cd9660_rmdir - not possible to remove a directory from iso cds
1158: *
1159: * Locking policy: a_dvp and vp locked on entry, unlocked on exit
1160: */
1161: int
1162: cd9660_rmdir(ap)
1163: struct vop_rmdir_args /* { struct vnode *a_dvp; struct vnode *a_vp;
1164: struct componentname *a_cnp; } */ *ap;
1165: {
1166: (void) nop_rmdir(ap);
1167: return (EROFS);
1168: }
1169:
1170: /*
1171:
1172: #
1173: #% getattrlist vp = = =
1174: #
1175: vop_getattrlist {
1176: IN struct vnode *vp;
1177: IN struct attrlist *alist;
1178: INOUT struct uio *uio;
1179: IN struct ucred *cred;
1180: IN struct proc *p;
1181: };
1182:
1183: */
1184: int
1185: cd9660_getattrlist(ap)
1186: struct vop_getattrlist_args /* {
1187: struct vnode *a_vp;
1188: struct attrlist *a_alist
1189: struct uio *a_uio;
1190: struct ucred *a_cred;
1191: struct proc *a_p;
1192: } */ *ap;
1193: {
1194: struct attrlist *alist = ap->a_alist;
1195: int fixedblocksize;
1196: int attrblocksize;
1197: int attrbufsize;
1198: void *attrbufptr;
1199: void *attrptr;
1200: void *varptr;
1201: int error = 0;
1202:
1203: if ((alist->bitmapcount != ATTR_BIT_MAP_COUNT) ||
1204: ((alist->commonattr & ~ATTR_CMN_VALIDMASK) != 0) ||
1205: ((alist->volattr & ~ATTR_VOL_VALIDMASK) != 0) ||
1206: ((alist->dirattr & ~ATTR_DIR_VALIDMASK) != 0) ||
1207: ((alist->fileattr & ~ATTR_FILE_VALIDMASK) != 0) ||
1208: ((alist->forkattr & ~ATTR_FORK_VALIDMASK) != 0)) {
1209: return EINVAL;
1210: };
1211:
1212: /*
1213: * Requesting volume information requires setting the ATTR_VOL_INFO bit and
1214: * volume info requests are mutually exclusive with all other info requests:
1215: */
1216: if ((alist->volattr != 0) &&
1217: (((alist->volattr & ATTR_VOL_INFO) == 0) ||
1218: (alist->dirattr != 0) ||
1219: (alist->fileattr != 0) ||
1220: (alist->forkattr != 0) )) {
1221: return EINVAL;
1222: };
1223:
1224: /*
1225: * Reject requests for unsupported options for now:
1226: */
1227: if (alist->volattr & ATTR_VOL_MOUNTPOINT) return EINVAL;
1228: if (alist->commonattr & (ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)) return EINVAL;
1229: if (alist->fileattr &
1230: (ATTR_FILE_FILETYPE |
1231: ATTR_FILE_FORKCOUNT |
1232: ATTR_FILE_FORKLIST |
1233: ATTR_FILE_DATAEXTENTS |
1234: ATTR_FILE_RSRCEXTENTS)) {
1235: return EINVAL;
1236: };
1237:
1238:
1239: fixedblocksize = attrcalcsize(alist);
1240: attrblocksize = fixedblocksize + (sizeof(u_long)); /* u_long for length longword */
1241: if (alist->commonattr & ATTR_CMN_NAME) attrblocksize += NAME_MAX;
1242: if (alist->commonattr & ATTR_CMN_NAMEDATTRLIST) attrblocksize += 0; /* XXX PPD */
1243: if (alist->volattr & ATTR_VOL_MOUNTPOINT) attrblocksize += PATH_MAX;
1244: if (alist->volattr & ATTR_VOL_NAME) attrblocksize += NAME_MAX;
1245: if (alist->fileattr & ATTR_FILE_FORKLIST) attrblocksize += 0; /* XXX PPD */
1246:
1247: attrbufsize = MIN(ap->a_uio->uio_resid, attrblocksize);
1248: MALLOC(attrbufptr, void *, attrblocksize, M_TEMP, M_WAITOK);
1249: attrptr = attrbufptr;
1250: *((u_long *)attrptr) = 0; /* Set buffer length in case of errors */
1251: ++((u_long *)attrptr); /* Reserve space for length field */
1252: varptr = ((char *)attrptr) + fixedblocksize; /* Point to variable-length storage */
1253:
1254: packattrblk(alist, ap->a_vp, &attrptr, &varptr);
1255:
1256: *((u_long *)attrbufptr) = (varptr - attrbufptr); /* Store length of fixed + var block */
1257: attrbufsize = MIN(attrbufsize, varptr - attrbufptr); /* Don't copy out more data than was generated */
1258:
1259: error = uiomove((caddr_t)attrbufptr, attrbufsize, ap->a_uio);
1260:
1261: FREE(attrbufptr, M_TEMP);
1262:
1263: return error;
1264: }
1265:
1266: /*
1267: * Global vfs data structures for isofs
1268: */
1269: #define cd9660_create \
1270: ((int (*) __P((struct vop_create_args *)))err_create)
1271: #define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))err_mknod)
1272: #define cd9660_setattr \
1273: ((int (*) __P((struct vop_setattr_args *)))cd9660_enotsupp)
1274: #define cd9660_write ((int (*) __P((struct vop_write_args *)))cd9660_enotsupp)
1275: #if NFSSERVER
1276: int lease_check __P((struct vop_lease_args *));
1277: #define cd9660_lease_check lease_check
1278: #else
1279: #define cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop)
1280: #endif
1281: #define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
1282: #define cd9660_rename \
1283: ((int (*) __P((struct vop_rename_args *)))err_rename)
1284: #define cd9660_copyfile \
1285: ((int (*) __P((struct vop_copyfile *)))err_copyfile)
1286: #define cd9660_link ((int (*) __P((struct vop_link_args *)))err_link)
1287: #define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))err_mkdir)
1288: #define cd9660_symlink \
1289: ((int (*) __P((struct vop_symlink_args *)))err_symlink)
1290: #define cd9660_advlock \
1291: ((int (*) __P((struct vop_advlock_args *)))cd9660_enotsupp)
1292: #define cd9660_valloc ((int(*) __P(( \
1293: struct vnode *pvp, \
1294: int mode, \
1295: struct ucred *cred, \
1296: struct vnode **vpp))) cd9660_enotsupp)
1297: #define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))cd9660_enotsupp)
1298: #define cd9660_truncate \
1299: ((int (*) __P((struct vop_truncate_args *)))cd9660_enotsupp)
1300: #define cd9660_update \
1301: ((int (*) __P((struct vop_update_args *)))cd9660_enotsupp)
1302: #define cd9660_bwrite \
1303: ((int (*) __P((struct vop_bwrite_args *)))cd9660_enotsupp)
1304:
1305: /*
1306: * Global vfs data structures for cd9660
1307: */
1308: int (**cd9660_vnodeop_p)();
1309: struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
1310: { &vop_default_desc, vn_default_error },
1311: { &vop_lookup_desc, cd9660_lookup }, /* lookup */
1312: { &vop_create_desc, cd9660_create }, /* create */
1313: { &vop_mknod_desc, cd9660_mknod }, /* mknod */
1314: { &vop_open_desc, cd9660_open }, /* open */
1315: { &vop_close_desc, cd9660_close }, /* close */
1316: { &vop_access_desc, cd9660_access }, /* access */
1317: { &vop_getattr_desc, cd9660_getattr }, /* getattr */
1318: { &vop_setattr_desc, cd9660_setattr }, /* setattr */
1319: { &vop_read_desc, cd9660_read }, /* read */
1320: { &vop_write_desc, cd9660_write }, /* write */
1321: { &vop_lease_desc, cd9660_lease_check },/* lease */
1322: { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */
1323: { &vop_select_desc, cd9660_select }, /* select */
1324: { &vop_mmap_desc, cd9660_mmap }, /* mmap */
1325: { &vop_fsync_desc, cd9660_fsync }, /* fsync */
1326: { &vop_seek_desc, cd9660_seek }, /* seek */
1327: { &vop_remove_desc, cd9660_remove }, /* remove */
1328: { &vop_link_desc, cd9660_link }, /* link */
1329: { &vop_rename_desc, cd9660_rename }, /* rename */
1330: { &vop_copyfile_desc, cd9660_copyfile },/* copyfile */
1331: { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */
1332: { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */
1333: { &vop_symlink_desc, cd9660_symlink }, /* symlink */
1334: { &vop_readdir_desc, cd9660_readdir }, /* readdir */
1335: { &vop_readlink_desc, cd9660_readlink },/* readlink */
1336: { &vop_abortop_desc, cd9660_abortop }, /* abortop */
1337: { &vop_inactive_desc, cd9660_inactive },/* inactive */
1338: { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
1339: { &vop_lock_desc, cd9660_lock }, /* lock */
1340: { &vop_unlock_desc, cd9660_unlock }, /* unlock */
1341: { &vop_bmap_desc, cd9660_bmap }, /* bmap */
1342: { &vop_strategy_desc, cd9660_strategy },/* strategy */
1343: { &vop_print_desc, cd9660_print }, /* print */
1344: { &vop_islocked_desc, cd9660_islocked },/* islocked */
1345: { &vop_pathconf_desc, cd9660_pathconf },/* pathconf */
1346: { &vop_advlock_desc, cd9660_advlock }, /* advlock */
1347: { &vop_blkatoff_desc, cd9660_blkatoff },/* blkatoff */
1348: { &vop_valloc_desc, cd9660_valloc }, /* valloc */
1349: { &vop_vfree_desc, cd9660_vfree }, /* vfree */
1350: { &vop_truncate_desc, cd9660_truncate },/* truncate */
1351: { &vop_update_desc, cd9660_update }, /* update */
1352: { &vop_bwrite_desc, vn_bwrite },
1353: { &vop_pagein_desc, cd9660_pagein }, /* Pagein */
1354: { &vop_pageout_desc, cd9660_pageout }, /* Pageout */
1355: { &vop_getattrlist_desc, cd9660_getattrlist }, /* getattrlist */
1356: { (struct vnodeop_desc*)NULL, (int(*)())NULL }
1357: };
1358: struct vnodeopv_desc cd9660_vnodeop_opv_desc =
1359: { &cd9660_vnodeop_p, cd9660_vnodeop_entries };
1360:
1361: /*
1362: * Special device vnode ops
1363: */
1364: int (**cd9660_specop_p)();
1365: struct vnodeopv_entry_desc cd9660_specop_entries[] = {
1366: { &vop_default_desc, vn_default_error },
1367: { &vop_lookup_desc, spec_lookup }, /* lookup */
1368: { &vop_create_desc, spec_create }, /* create */
1369: { &vop_mknod_desc, spec_mknod }, /* mknod */
1370: { &vop_open_desc, spec_open }, /* open */
1371: { &vop_close_desc, spec_close }, /* close */
1372: { &vop_access_desc, cd9660_access }, /* access */
1373: { &vop_getattr_desc, cd9660_getattr }, /* getattr */
1374: { &vop_setattr_desc, cd9660_setattr }, /* setattr */
1375: { &vop_read_desc, spec_read }, /* read */
1376: { &vop_write_desc, spec_write }, /* write */
1377: { &vop_lease_desc, spec_lease_check }, /* lease */
1378: { &vop_ioctl_desc, spec_ioctl }, /* ioctl */
1379: { &vop_select_desc, spec_select }, /* select */
1380: { &vop_mmap_desc, spec_mmap }, /* mmap */
1381: { &vop_fsync_desc, spec_fsync }, /* fsync */
1382: { &vop_seek_desc, spec_seek }, /* seek */
1383: { &vop_remove_desc, spec_remove }, /* remove */
1384: { &vop_link_desc, spec_link }, /* link */
1385: { &vop_rename_desc, spec_rename }, /* rename */
1386: { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
1387: { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
1388: { &vop_symlink_desc, spec_symlink }, /* symlink */
1389: { &vop_readdir_desc, spec_readdir }, /* readdir */
1390: { &vop_readlink_desc, spec_readlink }, /* readlink */
1391: { &vop_abortop_desc, spec_abortop }, /* abortop */
1392: { &vop_inactive_desc, cd9660_inactive },/* inactive */
1393: { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
1394: { &vop_lock_desc, cd9660_lock }, /* lock */
1395: { &vop_unlock_desc, cd9660_unlock }, /* unlock */
1396: { &vop_bmap_desc, spec_bmap }, /* bmap */
1397: { &vop_strategy_desc, spec_strategy }, /* strategy */
1398: { &vop_print_desc, cd9660_print }, /* print */
1399: { &vop_islocked_desc, cd9660_islocked },/* islocked */
1400: { &vop_pathconf_desc, spec_pathconf }, /* pathconf */
1401: { &vop_advlock_desc, spec_advlock }, /* advlock */
1402: { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */
1403: { &vop_valloc_desc, spec_valloc }, /* valloc */
1404: { &vop_vfree_desc, spec_vfree }, /* vfree */
1405: { &vop_truncate_desc, spec_truncate }, /* truncate */
1406: { &vop_update_desc, cd9660_update }, /* update */
1407: { &vop_bwrite_desc, vn_bwrite },
1408: #ifdef NeXT
1409: { &vop_devblocksize_desc, spec_devblocksize }, /* devblocksize */
1410: #endif /* NeXT */
1411: { &vop_pagein_desc, cd9660_pagein }, /* Pagein */
1412: { &vop_pageout_desc, cd9660_pageout }, /* Pageout */
1413: { (struct vnodeop_desc*)NULL, (int(*)())NULL }
1414: };
1415: struct vnodeopv_desc cd9660_specop_opv_desc =
1416: { &cd9660_specop_p, cd9660_specop_entries };
1417:
1418: #if FIFO
1419: int (**cd9660_fifoop_p)();
1420: struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
1421: { &vop_default_desc, vn_default_error },
1422: { &vop_lookup_desc, fifo_lookup }, /* lookup */
1423: { &vop_create_desc, fifo_create }, /* create */
1424: { &vop_mknod_desc, fifo_mknod }, /* mknod */
1425: { &vop_open_desc, fifo_open }, /* open */
1426: { &vop_close_desc, fifo_close }, /* close */
1427: { &vop_access_desc, cd9660_access }, /* access */
1428: { &vop_getattr_desc, cd9660_getattr }, /* getattr */
1429: { &vop_setattr_desc, cd9660_setattr }, /* setattr */
1430: { &vop_read_desc, fifo_read }, /* read */
1431: { &vop_write_desc, fifo_write }, /* write */
1432: { &vop_lease_desc, fifo_lease_check }, /* lease */
1433: { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
1434: { &vop_select_desc, fifo_select }, /* select */
1435: { &vop_mmap_desc, fifo_mmap }, /* mmap */
1436: { &vop_fsync_desc, fifo_fsync }, /* fsync */
1437: { &vop_seek_desc, fifo_seek }, /* seek */
1438: { &vop_remove_desc, fifo_remove }, /* remove */
1439: { &vop_link_desc, fifo_link } , /* link */
1440: { &vop_rename_desc, fifo_rename }, /* rename */
1441: { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */
1442: { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */
1443: { &vop_symlink_desc, fifo_symlink }, /* symlink */
1444: { &vop_readdir_desc, fifo_readdir }, /* readdir */
1445: { &vop_readlink_desc, fifo_readlink }, /* readlink */
1446: { &vop_abortop_desc, fifo_abortop }, /* abortop */
1447: { &vop_inactive_desc, cd9660_inactive },/* inactive */
1448: { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
1449: { &vop_lock_desc, cd9660_lock }, /* lock */
1450: { &vop_unlock_desc, cd9660_unlock }, /* unlock */
1451: { &vop_bmap_desc, fifo_bmap }, /* bmap */
1452: { &vop_strategy_desc, fifo_strategy }, /* strategy */
1453: { &vop_print_desc, cd9660_print }, /* print */
1454: { &vop_islocked_desc, cd9660_islocked },/* islocked */
1455: { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */
1456: { &vop_advlock_desc, fifo_advlock }, /* advlock */
1457: { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */
1458: { &vop_valloc_desc, fifo_valloc }, /* valloc */
1459: { &vop_vfree_desc, fifo_vfree }, /* vfree */
1460: { &vop_truncate_desc, fifo_truncate }, /* truncate */
1461: { &vop_update_desc, cd9660_update }, /* update */
1462: { &vop_bwrite_desc, vn_bwrite },
1463: { &vop_pagein_desc, cd9660_pagein }, /* Pagein */
1464: { &vop_pageout_desc, cd9660_pageout }, /* Pageout */
1465: { (struct vnodeop_desc*)NULL, (int(*)())NULL }
1466: };
1467: struct vnodeopv_desc cd9660_fifoop_opv_desc =
1468: { &cd9660_fifoop_p, cd9660_fifoop_entries };
1469: #endif /* FIFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.