|
|
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_vfsops.c,v 1.18 1995/03/09 12:05:36 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_vfsops.c 8.9 (Berkeley) 12/5/94 ! 65: */ ! 66: ! 67: #include <sys/param.h> ! 68: #include <sys/systm.h> ! 69: #include <sys/namei.h> ! 70: #include <sys/proc.h> ! 71: #include <sys/kernel.h> ! 72: #include <sys/vnode.h> ! 73: #include <miscfs/specfs/specdev.h> ! 74: #include <sys/mount.h> ! 75: #include <sys/buf.h> ! 76: #include <sys/file.h> ! 77: #include <sys/disklabel.h> ! 78: #include <sys/ioctl.h> ! 79: #include <sys/errno.h> ! 80: #include <sys/malloc.h> ! 81: #include <sys/stat.h> ! 82: ! 83: #include <isofs/cd9660/iso.h> ! 84: #include <isofs/cd9660/iso_rrip.h> ! 85: #include <isofs/cd9660/cd9660_node.h> ! 86: #include <isofs/cd9660/cd9660_mount.h> ! 87: ! 88: extern int enodev (); ! 89: ! 90: struct vfsops cd9660_vfsops = { ! 91: cd9660_mount, ! 92: cd9660_start, ! 93: cd9660_unmount, ! 94: cd9660_root, ! 95: cd9660_quotactl, ! 96: cd9660_statfs, ! 97: cd9660_sync, ! 98: cd9660_vget, ! 99: cd9660_fhtovp, ! 100: cd9660_vptofh, ! 101: cd9660_init, ! 102: cd9660_sysctl ! 103: }; ! 104: ! 105: /* ! 106: * Called by vfs_mountroot when iso is going to be mounted as root. ! 107: * ! 108: * Name is updated by mount(8) after booting. ! 109: */ ! 110: #define ROOTNAME "root_device" ! 111: ! 112: static int iso_mountfs __P((struct vnode *devvp, struct mount *mp, ! 113: struct proc *p, struct iso_args *argp)); ! 114: static void DRGetTypeCreatorAndFlags( struct iso_mnt * theMountPointPtr, ! 115: struct iso_directory_record * theDirRecPtr, ! 116: u_int32_t * theTypePtr, ! 117: u_int32_t * theCreatorPtr, ! 118: u_int16_t * theFlagsPtr ); ! 119: ! 120: int cd9660_vget_internal( struct mount *mp, ! 121: ino_t ino, ! 122: struct vnode **vpp, ! 123: int relocated, ! 124: struct iso_directory_record *isodir, ! 125: struct proc *p ); ! 126: ! 127: ! 128: int ! 129: cd9660_mountroot() ! 130: { ! 131: register struct mount *mp; ! 132: extern struct vnode *rootvp; ! 133: struct proc *p = current_proc(); /* XXX */ ! 134: struct iso_mnt *imp; ! 135: size_t size; ! 136: int error; ! 137: struct iso_args args; ! 138: ! 139: ! 140: /* ! 141: * Get vnodes for swapdev and rootdev. ! 142: */ ! 143: #if 0 ! 144: if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) ! 145: panic("cd9660_mountroot: can't setup bdevvp's"); ! 146: #else ! 147: if ( bdevvp(rootdev, &rootvp)) ! 148: panic("cd9660_mountroot: can't setup bdevvp's"); ! 149: ! 150: #endif ! 151: ! 152: MALLOC_ZONE(mp, struct mount *, ! 153: sizeof(struct mount), M_MOUNT, M_WAITOK); ! 154: bzero((char *)mp, (u_long)sizeof(struct mount)); ! 155: mp->mnt_op = &cd9660_vfsops; ! 156: mp->mnt_flag = MNT_RDONLY; ! 157: LIST_INIT(&mp->mnt_vnodelist); ! 158: args.flags = ISOFSMNT_ROOT; ! 159: if ((error = iso_mountfs(rootvp, mp, p, &args))) { ! 160: FREE_ZONE(mp, sizeof (struct mount), M_MOUNT); ! 161: return (error); ! 162: } ! 163: simple_lock(&mountlist_slock); ! 164: #if 0 ! 165: if (error = VFS_LOCK(mp)) { ! 166: (void)cd9660_unmount(mp, 0, p); ! 167: FREE_ZONE(mp, sizeof (struct mount), M_MOUNT); ! 168: return (error); ! 169: } ! 170: #endif ! 171: CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); ! 172: simple_unlock(&mountlist_slock); ! 173: mp->mnt_vnodecovered = NULLVP; ! 174: imp = VFSTOISOFS(mp); ! 175: (void) copystr("/", mp->mnt_stat.f_mntonname, MNAMELEN - 1, ! 176: &size); ! 177: bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); ! 178: (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, ! 179: &size); ! 180: bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); ! 181: (void)cd9660_statfs(mp, &mp->mnt_stat, p); ! 182: // VFS_UNLOCK(mp); ! 183: return (0); ! 184: } ! 185: ! 186: /* ! 187: * VFS Operations. ! 188: * ! 189: * mount system call ! 190: */ ! 191: int ! 192: cd9660_mount(mp, path, data, ndp, p) ! 193: register struct mount *mp; ! 194: char *path; ! 195: caddr_t data; ! 196: struct nameidata *ndp; ! 197: struct proc *p; ! 198: { ! 199: struct vnode *devvp; ! 200: struct iso_args args; ! 201: size_t size; ! 202: int error; ! 203: struct iso_mnt *imp; ! 204: ! 205: if ( (error = copyin(data, (caddr_t)&args, sizeof (struct iso_args))) ) ! 206: return (error); ! 207: ! 208: if ((mp->mnt_flag & MNT_RDONLY) == 0) ! 209: return (EROFS); ! 210: ! 211: imp = VFSTOISOFS(mp); /* set up imp before use. */ ! 212: ! 213: /* ! 214: * If updating, check whether changing from read-only to ! 215: * read/write; if there is no device name, that's all we do. ! 216: */ ! 217: if (mp->mnt_flag & MNT_UPDATE) { ! 218: if (args.fspec == 0) ! 219: return (vfs_export(mp, &imp->im_export, &args.export)); ! 220: } ! 221: /* ! 222: * Not an update, or updating the name: look up the name ! 223: * and verify that it refers to a sensible block device. ! 224: */ ! 225: NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); ! 226: if ( (error = namei(ndp)) ) ! 227: return (error); ! 228: devvp = ndp->ni_vp; ! 229: ! 230: if (devvp->v_type != VBLK) { ! 231: vrele(devvp); ! 232: return ENOTBLK; ! 233: } ! 234: if (major(devvp->v_rdev) >= nblkdev) { ! 235: vrele(devvp); ! 236: return ENXIO; ! 237: } ! 238: if ((mp->mnt_flag & MNT_UPDATE) == 0) ! 239: error = iso_mountfs(devvp, mp, p, &args); ! 240: else { ! 241: if (devvp != imp->im_devvp) ! 242: error = EINVAL; /* needs translation */ ! 243: else ! 244: vrele(devvp); ! 245: } ! 246: if (error) { ! 247: vrele(devvp); ! 248: return error; ! 249: } ! 250: ! 251: /* Set the mount flag to indicate that we support volfs */ ! 252: mp->mnt_flag |= MNT_DOVOLFS; ! 253: ! 254: (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); ! 255: bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); ! 256: (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, ! 257: &size); ! 258: bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); ! 259: return 0; ! 260: } ! 261: ! 262: /* ! 263: * Common code for mount and mountroot ! 264: */ ! 265: static int ! 266: iso_mountfs(devvp, mp, p, argp) ! 267: register struct vnode *devvp; ! 268: struct mount *mp; ! 269: struct proc *p; ! 270: struct iso_args *argp; ! 271: { ! 272: register struct iso_mnt *isomp = (struct iso_mnt *)0; ! 273: struct buf *bp = NULL; ! 274: dev_t dev = devvp->v_rdev; ! 275: int error = EINVAL; ! 276: int needclose = 0; ! 277: int ronly = (mp->mnt_flag & MNT_RDONLY) != 0; ! 278: extern struct vnode *rootvp; ! 279: int iso_bsize; ! 280: int iso_blknum; ! 281: struct iso_volume_descriptor *vdp; ! 282: struct iso_primary_descriptor *pri; ! 283: struct iso_directory_record *rootp; ! 284: int logical_block_size; ! 285: ! 286: if (!ronly) ! 287: return EROFS; ! 288: ! 289: /* ! 290: * Disallow multiple mounts of the same device. ! 291: * Disallow mounting of a device that is currently in use ! 292: * (except for root, which might share swap device for miniroot). ! 293: * Flush out any old buffers remaining from a previous use. ! 294: */ ! 295: if ( (error = vfs_mountedon(devvp)) ) ! 296: return error; ! 297: if (vcount(devvp) > 1 && devvp != rootvp) ! 298: return EBUSY; ! 299: if ( (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) ) ! 300: return (error); ! 301: ! 302: if ( (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) ) ! 303: return error; ! 304: needclose = 1; ! 305: ! 306: /* This is the "logical sector size". The standard says this ! 307: * should be 2048 or the physical sector size on the device, ! 308: * whichever is greater. For now, we'll just use a constant. ! 309: */ ! 310: iso_bsize = ISO_DEFAULT_BLOCK_SIZE; ! 311: ! 312: for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) { ! 313: ! 314: if ( (error = bread(devvp, iso_blknum, iso_bsize, NOCRED, &bp)) ) ! 315: { ! 316: goto out; ! 317: }; ! 318: ! 319: vdp = (struct iso_volume_descriptor *)bp->b_data; ! 320: if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) { ! 321: #ifdef DEBUG ! 322: printf("cd9660_vfsops.c: iso_mountfs: Invalid ID in volume desciptor.\n"); ! 323: #endif ! 324: error = EINVAL; ! 325: goto out; ! 326: } ! 327: ! 328: if (isonum_711 (vdp->type) == ISO_VD_END) { ! 329: #ifdef DEBUG ! 330: printf("cd9660_vfsops.c: iso_mountfs: isonum_711() != ISO_VD_END.\n"); ! 331: #endif ! 332: error = EINVAL; ! 333: goto out; ! 334: } ! 335: ! 336: if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) ! 337: break; ! 338: brelse(bp); ! 339: } ! 340: ! 341: if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) { ! 342: #ifdef DEBUG ! 343: printf("cd9660_vfsops.c: iso_mountfs: isnum_711() != ISO_VD_PRIMARY.\n"); ! 344: #endif ! 345: error = EINVAL; ! 346: goto out; ! 347: } ! 348: ! 349: pri = (struct iso_primary_descriptor *)vdp; ! 350: ! 351: logical_block_size = isonum_723 (pri->logical_block_size); ! 352: ! 353: if (logical_block_size < DEV_BSIZE || logical_block_size > MAXBSIZE ! 354: || (logical_block_size & (logical_block_size - 1)) != 0) { ! 355: error = EINVAL; ! 356: goto out; ! 357: } ! 358: ! 359: rootp = (struct iso_directory_record *)pri->root_directory_record; ! 360: ! 361: MALLOC(isomp, struct iso_mnt *, sizeof *isomp, M_ISOFSMNT, M_WAITOK); ! 362: bzero((caddr_t)isomp, sizeof *isomp); ! 363: isomp->logical_block_size = logical_block_size; ! 364: isomp->volume_space_size = isonum_733 (pri->volume_space_size); ! 365: bcopy (rootp, isomp->root, sizeof isomp->root); ! 366: isomp->root_extent = isonum_733 (rootp->extent); ! 367: isomp->root_size = isonum_733 (rootp->size); ! 368: ! 369: /* ! 370: * getattrlist wants the volume name, create date and modify date ! 371: */ ! 372: ! 373: /* Remove any trailing white space */ ! 374: if ( strlen(pri->volume_id) ) { ! 375: char *myPtr; ! 376: ! 377: myPtr = pri->volume_id + strlen( pri->volume_id ) - 1; ! 378: while ( *myPtr == ' ' && myPtr >= pri->volume_id ) { ! 379: *myPtr = 0x00; ! 380: myPtr--; ! 381: } ! 382: } ! 383: /* YYY need to use secondary volume descriptor name for kanji disks */ ! 384: bcopy(pri->volume_id, isomp->volume_id, sizeof(isomp->volume_id)); ! 385: cd9660_tstamp_conv17(pri->creation_date, &isomp->creation_date); ! 386: cd9660_tstamp_conv17(pri->modification_date, &isomp->modification_date); ! 387: ! 388: #if 0 ! 389: kprintf("\n************************************************************************* \n"); ! 390: kprintf( "iso_mountfs - pri->id is \"%c%c%c%c%c\" \n", ! 391: pri->id[0], pri->id[1], pri->id[2], pri->id[3], pri->id[4] ); ! 392: kprintf( "iso_mountfs - pri->CDXASignature is \"%c%c%c%c%c%c%c%c\" \n", ! 393: pri->CDXASignature[0], pri->CDXASignature[1], pri->CDXASignature[2], ! 394: pri->CDXASignature[3], pri->CDXASignature[4], pri->CDXASignature[5], ! 395: pri->CDXASignature[6], pri->CDXASignature[7] ); ! 396: #endif ! 397: ! 398: /* See if this is a CD-XA volume */ ! 399: if ( bcmp( pri->CDXASignature, ISO_XA_ID, sizeof(pri->CDXASignature) ) == 0 ) ! 400: isomp->im_flags2 |= IMF2_IS_CDXA; ! 401: ! 402: isomp->im_bmask = logical_block_size - 1; ! 403: isomp->im_bshift = 0; ! 404: while ((1 << isomp->im_bshift) < isomp->logical_block_size) ! 405: isomp->im_bshift++; ! 406: ! 407: bp->b_flags |= B_AGE; ! 408: brelse(bp); ! 409: bp = NULL; ! 410: ! 411: mp->mnt_data = (qaddr_t)isomp; ! 412: mp->mnt_stat.f_fsid.val[0] = (long)dev; ! 413: mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; ! 414: mp->mnt_maxsymlinklen = 0; ! 415: mp->mnt_flag |= MNT_LOCAL; ! 416: isomp->im_mountp = mp; ! 417: isomp->im_dev = dev; ! 418: isomp->im_devvp = devvp; ! 419: ! 420: devvp->v_specflags |= SI_MOUNTEDON; ! 421: ! 422: /* Check the Rock Ridge Extention support */ ! 423: if (!(argp->flags & ISOFSMNT_NORRIP)) { ! 424: if ( (error = bread(isomp->im_devvp, ! 425: (isomp->root_extent + isonum_711(rootp->ext_attr_length)), ! 426: isomp->logical_block_size, NOCRED, &bp)) ) ! 427: goto out; ! 428: ! 429: rootp = (struct iso_directory_record *)bp->b_data; ! 430: ! 431: if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) { ! 432: argp->flags |= ISOFSMNT_NORRIP; ! 433: } else { ! 434: argp->flags &= ~ISOFSMNT_GENS; ! 435: } ! 436: ! 437: /* ! 438: * The contents are valid, ! 439: * but they will get reread as part of another vnode, so... ! 440: */ ! 441: bp->b_flags |= B_AGE; ! 442: brelse(bp); ! 443: bp = NULL; ! 444: } ! 445: isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT); ! 446: switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) { ! 447: default: ! 448: isomp->iso_ftype = ISO_FTYPE_DEFAULT; ! 449: break; ! 450: case ISOFSMNT_GENS|ISOFSMNT_NORRIP: ! 451: isomp->iso_ftype = ISO_FTYPE_9660; ! 452: break; ! 453: case 0: ! 454: isomp->iso_ftype = ISO_FTYPE_RRIP; ! 455: break; ! 456: } ! 457: ! 458: return 0; ! 459: out: ! 460: if (bp) ! 461: brelse(bp); ! 462: if (needclose) ! 463: (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); ! 464: if (isomp) { ! 465: FREE((caddr_t)isomp, M_ISOFSMNT); ! 466: mp->mnt_data = (qaddr_t)0; ! 467: } ! 468: ! 469: /* Clear the mounted on bit in the devvp If it */ ! 470: /* not set, this is a nop and there is no way to */ ! 471: /* get here with it set unless we did it. If you*/ ! 472: /* are making code changes which makes the above */ ! 473: /* assumption not true, change this code. */ ! 474: ! 475: devvp->v_specflags &= ~SI_MOUNTEDON; ! 476: ! 477: return error; ! 478: } ! 479: ! 480: /* ! 481: * Make a filesystem operational. ! 482: * Nothing to do at the moment. ! 483: */ ! 484: /* ARGSUSED */ ! 485: int ! 486: cd9660_start(mp, flags, p) ! 487: struct mount *mp; ! 488: int flags; ! 489: struct proc *p; ! 490: { ! 491: return 0; ! 492: } ! 493: ! 494: /* ! 495: * unmount system call ! 496: */ ! 497: int ! 498: cd9660_unmount(mp, mntflags, p) ! 499: struct mount *mp; ! 500: int mntflags; ! 501: struct proc *p; ! 502: { ! 503: register struct iso_mnt *isomp; ! 504: int error, flags = 0; ! 505: ! 506: if ( (mntflags & MNT_FORCE) ) ! 507: flags |= FORCECLOSE; ! 508: #if 0 ! 509: mntflushbuf(mp, 0); ! 510: if (mntinvalbuf(mp)) ! 511: return EBUSY; ! 512: #endif ! 513: if ( (error = vflush(mp, NULLVP, flags)) ) ! 514: return (error); ! 515: ! 516: isomp = VFSTOISOFS(mp); ! 517: ! 518: #ifdef ISODEVMAP ! 519: if (isomp->iso_ftype == ISO_FTYPE_RRIP) ! 520: iso_dunmap(isomp->im_dev); ! 521: #endif ! 522: ! 523: isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON; ! 524: error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, p); ! 525: vrele(isomp->im_devvp); ! 526: FREE((caddr_t)isomp, M_ISOFSMNT); ! 527: mp->mnt_data = (qaddr_t)0; ! 528: mp->mnt_flag &= ~MNT_LOCAL; ! 529: return (error); ! 530: } ! 531: ! 532: /* ! 533: * Return root of a filesystem ! 534: */ ! 535: int ! 536: cd9660_root(mp, vpp) ! 537: struct mount *mp; ! 538: struct vnode **vpp; ! 539: { ! 540: struct iso_mnt *imp = VFSTOISOFS(mp); ! 541: struct iso_directory_record *dp = ! 542: (struct iso_directory_record *)imp->root; ! 543: ino_t ino = isodirino(dp, imp); ! 544: ! 545: /* ! 546: * With RRIP we must use the `.' entry of the root directory. ! 547: * Simply tell vget, that it's a relocated directory. ! 548: */ ! 549: return (cd9660_vget_internal(mp, ino, vpp, ! 550: imp->iso_ftype == ISO_FTYPE_RRIP, dp, current_proc())); ! 551: } ! 552: ! 553: /* ! 554: * Do operations associated with quotas, not supported ! 555: */ ! 556: /* ARGSUSED */ ! 557: int ! 558: cd9660_quotactl(mp, cmd, uid, arg, p) ! 559: struct mount *mp; ! 560: int cmd; ! 561: uid_t uid; ! 562: caddr_t arg; ! 563: struct proc *p; ! 564: { ! 565: ! 566: return (EOPNOTSUPP); ! 567: } ! 568: ! 569: /* ! 570: * Get file system statistics. ! 571: */ ! 572: int ! 573: cd9660_statfs(mp, sbp, p) ! 574: struct mount *mp; ! 575: register struct statfs *sbp; ! 576: struct proc *p; ! 577: { ! 578: register struct iso_mnt *isomp; ! 579: ! 580: isomp = VFSTOISOFS(mp); ! 581: ! 582: #ifdef COMPAT_09 ! 583: sbp->f_type = 5; ! 584: #else ! 585: sbp->f_type = 0; ! 586: #endif ! 587: sbp->f_bsize = isomp->logical_block_size; ! 588: sbp->f_iosize = sbp->f_bsize; /* XXX */ ! 589: sbp->f_blocks = isomp->volume_space_size; ! 590: sbp->f_bfree = 0; /* total free blocks */ ! 591: sbp->f_bavail = 0; /* blocks free for non superuser */ ! 592: sbp->f_files = 0; /* total files */ ! 593: sbp->f_ffree = 0; /* free file nodes */ ! 594: if (sbp != &mp->mnt_stat) { ! 595: bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); ! 596: bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); ! 597: } ! 598: ! 599: strncpy( sbp->f_fstypename, mp->mnt_vfc->vfc_name, (MFSNAMELEN - 1) ); ! 600: sbp->f_fstypename[(MFSNAMELEN - 1)] = '\0'; ! 601: ! 602: /* Use the first spare for flags: */ ! 603: sbp->f_spare[0] = isomp->im_flags; ! 604: return 0; ! 605: } ! 606: ! 607: /* ARGSUSED */ ! 608: int ! 609: cd9660_sync(mp, waitfor, cred, p) ! 610: struct mount *mp; ! 611: int waitfor; ! 612: struct ucred *cred; ! 613: struct proc *p; ! 614: { ! 615: return (0); ! 616: } ! 617: ! 618: /* ! 619: * File handle to vnode ! 620: * ! 621: * Have to be really careful about stale file handles: ! 622: * - check that the inode number is in range ! 623: * - call iget() to get the locked inode ! 624: * - check for an unallocated inode (i_mode == 0) ! 625: * - check that the generation number matches ! 626: */ ! 627: ! 628: struct ifid { ! 629: ushort ifid_len; ! 630: ushort ifid_pad; ! 631: int ifid_ino; ! 632: long ifid_start; ! 633: }; ! 634: ! 635: /* ARGSUSED */ ! 636: int ! 637: cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) ! 638: register struct mount *mp; ! 639: struct fid *fhp; ! 640: struct mbuf *nam; ! 641: struct vnode **vpp; ! 642: int *exflagsp; ! 643: struct ucred **credanonp; ! 644: { ! 645: struct ifid *ifhp = (struct ifid *)fhp; ! 646: register struct iso_node *ip; ! 647: register struct netcred *np; ! 648: register struct iso_mnt *imp = VFSTOISOFS(mp); ! 649: struct vnode *nvp; ! 650: int error; ! 651: ! 652: #ifdef ISOFS_DBG ! 653: printf("fhtovp: ino %d, start %ld\n", ! 654: ifhp->ifid_ino, ifhp->ifid_start); ! 655: #endif ! 656: ! 657: /* ! 658: * Get the export permission structure for this <mp, client> tuple. ! 659: */ ! 660: np = vfs_export_lookup(mp, &imp->im_export, nam); ! 661: if (np == NULL) ! 662: return (EACCES); ! 663: ! 664: if ( (error = VFS_VGET(mp, &ifhp->ifid_ino, &nvp)) ) { ! 665: *vpp = NULLVP; ! 666: return (error); ! 667: } ! 668: ip = VTOI(nvp); ! 669: if (ip->inode.iso_mode == 0) { ! 670: vput(nvp); ! 671: *vpp = NULLVP; ! 672: return (ESTALE); ! 673: } ! 674: *vpp = nvp; ! 675: *exflagsp = np->netc_exflags; ! 676: *credanonp = &np->netc_anon; ! 677: return (0); ! 678: } ! 679: ! 680: int ! 681: cd9660_vget(mp, ino, vpp) ! 682: struct mount *mp; ! 683: void *ino; ! 684: struct vnode **vpp; ! 685: { ! 686: ! 687: /* ! 688: * XXXX ! 689: * It would be nice if we didn't always set the `relocated' flag ! 690: * and force the extra read, but I don't want to think about fixing ! 691: * that right now. ! 692: */ ! 693: ! 694: return ( cd9660_vget_internal( mp, *(ino_t*)ino, vpp, 0, ! 695: (struct iso_directory_record *) 0, ! 696: current_proc()) ); ! 697: } ! 698: ! 699: int ! 700: cd9660_vget_internal(mp, ino, vpp, relocated, isodir, p) ! 701: struct mount *mp; ! 702: ino_t ino; ! 703: struct vnode **vpp; ! 704: int relocated; ! 705: struct iso_directory_record *isodir; ! 706: struct proc *p; ! 707: { ! 708: register struct iso_mnt *imp; ! 709: struct iso_node *ip; ! 710: struct buf *bp; ! 711: struct vnode *vp, *nvp; ! 712: dev_t dev; ! 713: int error; ! 714: ! 715: imp = VFSTOISOFS(mp); ! 716: dev = imp->im_dev; ! 717: if ((*vpp = cd9660_ihashget(dev, ino, p)) != NULLVP) ! 718: return (0); ! 719: ! 720: /* Allocate a new vnode/iso_node. */ ! 721: if ( (error = getnewvnode(VT_ISOFS, mp, cd9660_vnodeop_p, &vp)) ) { ! 722: *vpp = NULLVP; ! 723: return (error); ! 724: } ! 725: MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, ! 726: M_WAITOK); ! 727: bzero((caddr_t)ip, sizeof(struct iso_node)); ! 728: lockinit(&ip->i_lock, PINOD,"isonode",0,0); ! 729: vp->v_data = ip; ! 730: ip->i_vnode = vp; ! 731: ip->i_dev = dev; ! 732: ip->i_number = ino; ! 733: ! 734: /* ! 735: * Put it onto its hash chain and lock it so that other requests for ! 736: * this inode will block if they arrive while we are sleeping waiting ! 737: * for old data structures to be purged or for the contents of the ! 738: * disk portion of this inode to be read. ! 739: */ ! 740: cd9660_ihashins(ip); ! 741: ! 742: if (isodir == 0) { ! 743: int lbn, off; ! 744: ! 745: lbn = lblkno(imp, ino); ! 746: if (lbn >= imp->volume_space_size) { ! 747: vput(vp); ! 748: printf("fhtovp: lbn exceed volume space %d\n", lbn); ! 749: return (ESTALE); ! 750: } ! 751: ! 752: off = blkoff(imp, ino); ! 753: if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) { ! 754: vput(vp); ! 755: printf("fhtovp: crosses block boundary %d\n", ! 756: off + ISO_DIRECTORY_RECORD_SIZE); ! 757: return (ESTALE); ! 758: } ! 759: ! 760: error = bread(imp->im_devvp, ! 761: lbn, ! 762: imp->logical_block_size, NOCRED, &bp); ! 763: if (error) { ! 764: vput(vp); ! 765: brelse(bp); ! 766: printf("fhtovp: bread error %d\n",error); ! 767: return (error); ! 768: } ! 769: isodir = (struct iso_directory_record *)(bp->b_data + off); ! 770: ! 771: if (off + isonum_711(isodir->length) > ! 772: imp->logical_block_size) { ! 773: vput(vp); ! 774: if (bp != 0) ! 775: brelse(bp); ! 776: printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n", ! 777: off +isonum_711(isodir->length), off, ! 778: isonum_711(isodir->length)); ! 779: return (ESTALE); ! 780: } ! 781: ! 782: /* ! 783: * for directories we can get parentID from adjacent parent directory record ! 784: */ ! 785: if ((isonum_711(isodir->flags) & directoryBit) && (isodir->name[0] == 0)) { ! 786: struct iso_directory_record *pdp; ! 787: ! 788: pdp = (struct iso_directory_record *) ((char *)bp->b_data + isonum_711(isodir->length)); ! 789: if ((isonum_711(pdp->flags) & directoryBit) && (pdp->name[0] == 1)) ! 790: ip->i_parent = isodirino(pdp, imp); ! 791: ! 792: } ! 793: #if 0 ! 794: if (isonum_733(isodir->extent) + ! 795: isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) { ! 796: if (bp != 0) ! 797: brelse(bp); ! 798: printf("fhtovp: file start miss %d vs %d\n", ! 799: isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length), ! 800: ifhp->ifid_start); ! 801: return (ESTALE); ! 802: } ! 803: #endif ! 804: } else ! 805: bp = 0; ! 806: ! 807: ip->i_mnt = imp; ! 808: ip->i_devvp = imp->im_devvp; ! 809: VREF(ip->i_devvp); ! 810: ! 811: if (relocated) { ! 812: /* ! 813: * On relocated directories we must ! 814: * read the `.' entry out of a dir. ! 815: */ ! 816: ip->iso_start = ino >> imp->im_bshift; ! 817: if (bp != 0) ! 818: brelse(bp); ! 819: if ( (error = VOP_BLKATOFF(vp, (off_t)0, NULL, &bp)) ) { ! 820: vput(vp); ! 821: return (error); ! 822: } ! 823: isodir = (struct iso_directory_record *)bp->b_data; ! 824: } ! 825: ! 826: /* ! 827: * get apple extensions to ISO directory record or use defaults ! 828: * when there are no apple extensions. ! 829: */ ! 830: if ( (isonum_711( isodir->flags ) & directoryBit) == 0 ) ! 831: { ! 832: /* This is an ISO directory record for a file */ ! 833: DRGetTypeCreatorAndFlags( imp, isodir, &ip->i_FileType, ! 834: &ip->i_Creator, &ip->i_FinderFlags ); ! 835: } ! 836: ! 837: ip->iso_extent = isonum_733(isodir->extent); ! 838: ip->i_size = isonum_733(isodir->size); ! 839: ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent; ! 840: ! 841: /* ! 842: * if we have a valid name, fill in i_name ! 843: */ ! 844: if (((u_char)isodir->name[0]) > 1) { ! 845: u_short namelen; ! 846: ! 847: if (imp->iso_ftype == ISO_FTYPE_RRIP) { ! 848: ino_t inump = 0; ! 849: ! 850: cd9660_rrip_getname(isodir, ip->i_name, &namelen, &inump, imp); ! 851: } else { ! 852: isofntrans (isodir->name, isonum_711(isodir->name_len), ! 853: ip->i_name, &namelen, ! 854: imp->iso_ftype == ISO_FTYPE_9660, ! 855: isonum_711(isodir->flags) & associatedBit); ! 856: } ! 857: ! 858: if (namelen > (sizeof(ip->i_name) - 1)) ! 859: namelen = sizeof(ip->i_name) - 1; ! 860: ip->i_name[namelen] = '\0'; ! 861: } ! 862: ! 863: /* ! 864: * Setup time stamp, attribute ! 865: */ ! 866: vp->v_type = VNON; ! 867: switch (imp->iso_ftype) { ! 868: default: /* ISO_FTYPE_9660 */ ! 869: { ! 870: struct buf *bp2; ! 871: int off; ! 872: if ((imp->im_flags & ISOFSMNT_EXTATT) ! 873: && (off = isonum_711(isodir->ext_attr_length))) ! 874: VOP_BLKATOFF(vp, (off_t)-(off << imp->im_bshift), NULL, ! 875: &bp2); ! 876: else ! 877: bp2 = NULL; ! 878: cd9660_defattr(isodir, ip, bp2); ! 879: cd9660_deftstamp(isodir, ip, bp2); ! 880: if (bp2) ! 881: brelse(bp2); ! 882: break; ! 883: } ! 884: case ISO_FTYPE_RRIP: ! 885: cd9660_rrip_analyze(isodir, ip, imp); ! 886: break; ! 887: } ! 888: ! 889: if (bp != 0) ! 890: brelse(bp); ! 891: ! 892: /* ! 893: * Initialize the associated vnode ! 894: */ ! 895: switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) { ! 896: case VFIFO: ! 897: #ifdef FIFO ! 898: vp->v_op = cd9660_fifoop_p; ! 899: break; ! 900: #else ! 901: vput(vp); ! 902: return (EOPNOTSUPP); ! 903: #endif /* FIFO */ ! 904: case VCHR: ! 905: case VBLK: ! 906: /* ! 907: * if device, look at device number table for translation ! 908: */ ! 909: #ifdef ISODEVMAP ! 910: if (dp = iso_dmap(dev, ino, 0)) ! 911: ip->inode.iso_rdev = dp->d_dev; ! 912: #endif ! 913: vp->v_op = cd9660_specop_p; ! 914: if ( (nvp = checkalias(vp, ip->inode.iso_rdev, mp)) ) { ! 915: /* ! 916: * Discard unneeded vnode, but save its iso_node. ! 917: */ ! 918: cd9660_ihashrem(ip); ! 919: VOP_UNLOCK(vp, 0, p); ! 920: nvp->v_data = vp->v_data; ! 921: vp->v_data = NULL; ! 922: vp->v_op = spec_vnodeop_p; ! 923: vrele(vp); ! 924: vgone(vp); ! 925: /* ! 926: * Reinitialize aliased inode. ! 927: */ ! 928: vp = nvp; ! 929: ip->i_vnode = vp; ! 930: cd9660_ihashins(ip); ! 931: } ! 932: break; ! 933: default: ! 934: break; ! 935: } ! 936: ! 937: if (ip->iso_extent == imp->root_extent) { ! 938: vp->v_flag |= VROOT; ! 939: ip->i_parent = 1; /* root's parent is always 1 by convention */ ! 940: } ! 941: /* ! 942: * XXX need generation number? ! 943: */ ! 944: ! 945: *vpp = vp; ! 946: return (0); ! 947: } ! 948: ! 949: ! 950: /************************************************************************ ! 951: * ! 952: * Function: DRGetTypeCreatorAndFlags ! 953: * ! 954: * Purpose: Set up the fileType, fileCreator and fileFlags ! 955: * ! 956: * Returns: none ! 957: * ! 958: * Side Effects: sets *theTypePtr, *theCreatorPtr, and *theFlagsPtr ! 959: * ! 960: * Description: ! 961: * ! 962: * Revision History: ! 963: * 28 Jul 88 BL�B Added a new extension type of 6, which allows ! 964: * the specification of four of the finder flags. ! 965: * We let the creator of the disk just copy over ! 966: * the finder flags, but we only look at always ! 967: * switch launch, system, bundle, and locked bits. ! 968: * 15 Aug 88 BL�B The Apple extensions to ISO 9660 implemented the ! 969: * padding field at the end of a directory record ! 970: * incorrectly. ! 971: * 19 Jul 89 BG Rewrote routine to handle the "new" Apple ! 972: * Extensions definition, as well as take into ! 973: * account the possibility of "other" definitions. ! 974: * 02 Nov 89 BG Corrected the 'AA' SystemUseID processing to ! 975: * check for SystemUseID == 2 (HFS). Was incorrectly ! 976: * checking for SystemUseID == 1 (ProDOS) before. ! 977: * 18 Mar 92 CMP Fixed the check for whether len_fi was odd or even. ! 978: * Before it would always assume even for an XA record. ! 979: * 26 Dec 97 jwc Swiped from MacOS implementation of ISO 9660 CD-ROM support ! 980: * and modified to work in Rhapsody file system. ! 981: * ! 982: *********************************************************************** */ ! 983: ! 984: static void DRGetTypeCreatorAndFlags( struct iso_mnt * theMountPointPtr, ! 985: struct iso_directory_record * theDirRecPtr, ! 986: u_int32_t * theTypePtr, ! 987: u_int32_t * theCreatorPtr, ! 988: u_int16_t * theFlagsPtr ) ! 989: { ! 990: int foundStuff; ! 991: u_int32_t myType; ! 992: u_int32_t myCreator; ! 993: AppleExtension *myAppleExtPtr; ! 994: NewAppleExtension *myNewAppleExtPtr; ! 995: u_int16_t myFinderFlags; ! 996: char *myPtr; ! 997: ! 998: foundStuff = 1; ! 999: myType = 0L; ! 1000: myCreator = 0L; ! 1001: myFinderFlags = 0; ! 1002: *theFlagsPtr = 0x0000; ! 1003: ! 1004: /* handle the fact that our original apple extensions didn't take ! 1005: into account the padding byte on a file name */ ! 1006: ! 1007: myPtr = &theDirRecPtr->name[ (isonum_711(theDirRecPtr->name_len)) ]; ! 1008: ! 1009: /* if string length is even, bump myPtr for padding byte */ ! 1010: if ( ((isonum_711(theDirRecPtr->name_len)) & 0x01) == 0 ) ! 1011: myPtr++; ! 1012: myAppleExtPtr = (AppleExtension *) myPtr; ! 1013: ! 1014: /* checking for whether or not the new 'AA' code is being called (and if so, correctly) */ ! 1015: if ( (isonum_711(theDirRecPtr->length)) <= ! 1016: ISO_DIRECTORY_RECORD_SIZE + (isonum_711(theDirRecPtr->name_len)) ) ! 1017: { ! 1018: foundStuff = 0; ! 1019: goto DoneLooking; ! 1020: } ! 1021: ! 1022: if ( myAppleExtPtr->signature[0] == 'B' && myAppleExtPtr->signature[1] == 'A' ) ! 1023: { ! 1024: int i; ! 1025: ! 1026: switch ( isonum_711(myAppleExtPtr->systemUseID) ) ! 1027: { ! 1028: case 0x00: /* nothing there. use default */ ! 1029: foundStuff = 0; ! 1030: break; ! 1031: case 0x02: /* no icon */ ! 1032: case 0x04: /* icon, no bundle bit */ ! 1033: for ( i = 0; i < 4; i++ ) ! 1034: myType = (myType << 8) | myAppleExtPtr->fileType[i]; ! 1035: ! 1036: for ( i = 0; i < 4; i++ ) ! 1037: myCreator = (myCreator << 8) | myAppleExtPtr->fileCreator[i]; ! 1038: ! 1039: *theFlagsPtr |= fInitedBit; ! 1040: break; ! 1041: case 0x03: /* no icon, bundle bit */ ! 1042: case 0x05: /* icon and bundle bit */ ! 1043: for ( i = 0; i < 4; i++ ) ! 1044: myType = (myType << 8) | myAppleExtPtr->fileType[i]; ! 1045: ! 1046: for ( i = 0; i < 4; i++ ) ! 1047: myCreator = (myCreator << 8) | myAppleExtPtr->fileCreator[i]; ! 1048: ! 1049: *theFlagsPtr |= fInitedBit | fHasBundleBit; ! 1050: break; ! 1051: case 0x06: /* finder flags in word at end */ ! 1052: for ( i = 0; i < 4; i++ ) ! 1053: myType = (myType << 8) | myAppleExtPtr->fileType[i]; ! 1054: ! 1055: for ( i = 0; i < 4; i++ ) ! 1056: myCreator = (myCreator << 8) | myAppleExtPtr->fileCreator[i]; ! 1057: ! 1058: myFinderFlags = ! 1059: (myAppleExtPtr->finderFlags[0] << 8) | myAppleExtPtr->finderFlags[1]; ! 1060: ! 1061: /* just check the following four bits--all others always set to 0 */ ! 1062: myFinderFlags &= (fAlwaysBit | fSystemBit | fHasBundleBit | fLockedBit); ! 1063: *theFlagsPtr |= (fInitedBit | myFinderFlags); ! 1064: break; ! 1065: default: ! 1066: foundStuff = 0; ! 1067: } ! 1068: goto DoneLooking; ! 1069: } ! 1070: ! 1071: /* ! 1072: * If signature[]s != 'BA', then (1) this is not an old-style disc and we ! 1073: * need to look at ALL available SystemUse possibilities; (2) this could ! 1074: * possibly be a CD-XA style disc and our offset calculations need to ! 1075: * take this into account. ! 1076: */ ! 1077: ! 1078: foundStuff = 0; /* now we default to *false* until we find a good one */ ! 1079: myPtr = (char *) myAppleExtPtr; ! 1080: ! 1081: if ( (theMountPointPtr->im_flags2 & IMF2_IS_CDXA) != 0 ) ! 1082: myPtr += 14;/* add in CD-XA fixed record offset (tnx, Phillips) */ ! 1083: myNewAppleExtPtr = (NewAppleExtension *) myPtr; ! 1084: ! 1085: /* calculate the "real" end of the directory record information */ ! 1086: myPtr = ((char *) theDirRecPtr) + (isonum_711(theDirRecPtr->length)); ! 1087: while( (char *) myNewAppleExtPtr < myPtr ) /* end of directory buffer */ ! 1088: { ! 1089: /* ! 1090: * If we get here, we can assume that ALL further entries in this ! 1091: * directory record are of the form: ! 1092: * ! 1093: * struct OptionalSystemUse ! 1094: * { ! 1095: * byte Signature[2]; ! 1096: * byte systemUseID; ! 1097: * byte OSULength; ! 1098: * byte fileType[4]; # only if HFS ! 1099: * byte fileCreator[4]; # only if HFS ! 1100: * byte finderFlags[2]; # only if HFS ! 1101: * }; ! 1102: * ! 1103: * This means that we can examine the Signature bytes to see if they are 'AA' ! 1104: * (the NEW Apple extension signature). If they are, deal with them. If they ! 1105: * aren't, the OSULength field will tell us how long this extension info is ! 1106: * (including the signature and length bytes) and that will allow us to walk ! 1107: * the OptionalSystemUse records until we hit the end of them or run off the ! 1108: * end of the directory record. ! 1109: */ ! 1110: u_char *myFromPtr, *myToPtr; ! 1111: union ! 1112: { ! 1113: u_int32_t fourchars; ! 1114: u_char chars[4]; ! 1115: } myChars; ! 1116: ! 1117: if ( myNewAppleExtPtr->signature[0] == 'A' && myNewAppleExtPtr->signature[1] == 'A' ) ! 1118: { ! 1119: if ( isonum_711(myNewAppleExtPtr->systemUseID) == 2 ) /* HFS */ ! 1120: { ! 1121: foundStuff = 1; /* we got one! */ ! 1122: ! 1123: myFromPtr = &myNewAppleExtPtr->fileType[0]; ! 1124: myToPtr = &myChars.chars[0]; ! 1125: *myToPtr++ = *myFromPtr++; ! 1126: *myToPtr++ = *myFromPtr++; ! 1127: *myToPtr++ = *myFromPtr++; ! 1128: *myToPtr = *myFromPtr; ! 1129: myType = myChars.fourchars; /* copy file type to user var */ ! 1130: ! 1131: myFromPtr = &myNewAppleExtPtr->fileCreator[0]; ! 1132: myToPtr = &myChars.chars[0]; ! 1133: *myToPtr++ = *myFromPtr++; ! 1134: *myToPtr++ = *myFromPtr++; ! 1135: *myToPtr++ = *myFromPtr++; ! 1136: *myToPtr = *myFromPtr; ! 1137: myCreator = myChars.fourchars; /* copy creator to user var */ ! 1138: ! 1139: myFromPtr = &myNewAppleExtPtr->finderFlags[0]; ! 1140: myToPtr = &myChars.chars[2]; /* *flags* is a short */ ! 1141: myChars.fourchars = 0; ! 1142: *myToPtr++ = *myFromPtr++; ! 1143: *myToPtr = *myFromPtr; ! 1144: myFinderFlags = myChars.fourchars; ! 1145: myFinderFlags &= ( fAlwaysBit | fSystemBit | fHasBundleBit | fLockedBit ); ! 1146: *theFlagsPtr = (myFinderFlags | fInitedBit); /* return Finder flags to user var */ ! 1147: ! 1148: break; /* exit the loop */ ! 1149: } ! 1150: } ! 1151: ! 1152: /* ! 1153: * Check to see if we have a reasonable OSULength value. ! 1154: * ZERO is not an acceptable value. Nor is any value less than 4. ! 1155: */ ! 1156: ! 1157: if ( (isonum_711(myNewAppleExtPtr->OSULength)) < 4 ) ! 1158: break; /* not acceptable - get out! */ ! 1159: ! 1160: /* otherwise, step past this SystemUse record */ ! 1161: (char *)myNewAppleExtPtr += (isonum_711(myNewAppleExtPtr->OSULength)); ! 1162: ! 1163: } // end of while loop ! 1164: ! 1165: DoneLooking: ! 1166: if ( foundStuff != 0 ) ! 1167: { ! 1168: *theTypePtr = myType; ! 1169: *theCreatorPtr = myCreator; ! 1170: } ! 1171: else ! 1172: { ! 1173: *theTypePtr = DEFAULTTYPE; ! 1174: *theCreatorPtr = DEFAULTCREATOR; ! 1175: *theFlagsPtr |= fInitedBit; ! 1176: } ! 1177: ! 1178: return; ! 1179: ! 1180: } /* DRGetTypeCreatorAndFlags */ ! 1181: ! 1182: ! 1183: /* ! 1184: * Vnode pointer to File handle ! 1185: */ ! 1186: /* ARGSUSED */ ! 1187: int ! 1188: cd9660_vptofh(vp, fhp) ! 1189: struct vnode *vp; ! 1190: struct fid *fhp; ! 1191: { ! 1192: register struct iso_node *ip = VTOI(vp); ! 1193: register struct ifid *ifhp; ! 1194: ! 1195: ifhp = (struct ifid *)fhp; ! 1196: ifhp->ifid_len = sizeof(struct ifid); ! 1197: ! 1198: ifhp->ifid_ino = ip->i_number; ! 1199: ifhp->ifid_start = ip->iso_start; ! 1200: ! 1201: #ifdef ISOFS_DBG ! 1202: printf("vptofh: ino %d, start %ld\n", ! 1203: ifhp->ifid_ino,ifhp->ifid_start); ! 1204: #endif ! 1205: return 0; ! 1206: } ! 1207: ! 1208: /* ! 1209: * Fast-FileSystem only? ! 1210: */ ! 1211: int ! 1212: cd9660_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) ! 1213: int * name; ! 1214: u_int namelen; ! 1215: void* oldp; ! 1216: size_t * oldlenp; ! 1217: void * newp; ! 1218: size_t newlen; ! 1219: struct proc * p; ! 1220: { ! 1221: return EOPNOTSUPP; ! 1222: } ! 1223:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.