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