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