|
|
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) ! 1247: #ifdef NFSSERVER ! 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: ! 1387: #ifdef FIFO ! 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.