]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/isofs/cd9660/cd9660_vfsops.c
xnu-1228.tar.gz
[apple/xnu.git] / bsd / isofs / cd9660 / cd9660_vfsops.c
index f026c811f0b10ffd1d5f5dd67a62c37d59a90573..acdb699a2f2a090c534419c5a77f78d32eb43931 100644 (file)
@@ -1,23 +1,29 @@
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*     $NetBSD: cd9660_vfsops.c,v 1.18 1995/03/09 12:05:36 mycroft Exp $       */
 
@@ -79,7 +85,6 @@
 #include <sys/stat.h>
 #include <sys/ubc.h>
 #include <sys/utfconv.h>
-#include <architecture/byte_order.h>
 
 #include <isofs/cd9660/iso.h>
 #include <isofs/cd9660/iso_rrip.h>
@@ -132,7 +137,9 @@ struct vfsops cd9660_vfsops = {
        cd9660_fhtovp,
        cd9660_vptofh,
        cd9660_init,
-       cd9660_sysctl
+       cd9660_sysctl,
+       NULL,
+       {NULL}
 };
 
 /*
@@ -184,11 +191,11 @@ cd9660_mount(mount_t mp, vnode_t devvp, user_addr_t data, vfs_context_t context)
        struct iso_mnt *imp = NULL;
 
        if (vfs_context_is64bit(context)) {
-               error = copyin(data, (caddr_t)&args, sizeof (args));
+               error = copyin(data, (caddr_t)&args, sizeof(args));
        }
        else {
                struct iso_args temp;
-               error = copyin(data, (caddr_t)&temp, sizeof (temp));
+               error = copyin(data, (caddr_t)&temp, sizeof(temp));
                args.flags = temp.flags;
                args.ssector = temp.ssector;
                args.toc_length = temp.toc_length;
@@ -254,7 +261,7 @@ cd9660_phys_device(mount_t mp, vfs_context_t context)
                return (NULL);
 
        /* Make a copy of the mount from name, then remove trailing "s...". */
-       strncpy(whole_path, sfs->f_mntfromname, sizeof(whole_path)-1); 
+       strlcpy(whole_path, sfs->f_mntfromname, sizeof(whole_path)); 
        
        /*
         * I would use strrchr or rindex here, but those are declared __private_extern__,
@@ -300,7 +307,6 @@ cd9660_find_video_dir(struct iso_mnt *isomp)
        struct vnode *rvp = NULL;
        struct vnode *videovp = NULL;
        struct componentname cn;
-       struct vfs_context context;
        char dirname[] = "MPEGAV";
        
        result = 0;             /* Assume not a video CD */
@@ -311,18 +317,15 @@ cd9660_find_video_dir(struct iso_mnt *isomp)
                return 0;       /* couldn't find video dir */
        }
        
-       context.vc_proc = current_proc();
-       context.vc_ucred = kauth_cred_get();
-
        cn.cn_nameiop = LOOKUP;
        cn.cn_flags = ISLASTCN;
-       cn.cn_context = &context;
+       cn.cn_context = vfs_context_current();
        cn.cn_pnbuf = dirname;
        cn.cn_pnlen = sizeof(dirname)-1;
        cn.cn_nameptr = cn.cn_pnbuf;
        cn.cn_namelen = cn.cn_pnlen;
        
-       err = VNOP_LOOKUP(rvp, &videovp, &cn, &context);
+       err = VNOP_LOOKUP(rvp, &videovp, &cn, cn.cn_context);
        if (err == 0) {
                struct iso_node *ip = VTOI(videovp);
                result = 1;             /* Looks like video CD */
@@ -341,20 +344,16 @@ cd9660_find_video_dir(struct iso_mnt *isomp)
  * Common code for mount and mountroot
  */
 static int
-iso_mountfs(devvp, mp, argp, context)
-       register struct vnode *devvp;
-       struct mount *mp;
-       struct user_iso_args *argp;
-       vfs_context_t context;
+iso_mountfs(struct vnode *devvp, struct mount *mp, struct user_iso_args *argp,
+           vfs_context_t context)
 {
-       struct proc *p;
-       register struct iso_mnt *isomp = (struct iso_mnt *)0;
+       struct iso_mnt *isomp = (struct iso_mnt *)0;
        struct buf *bp = NULL;
        struct buf *pribp = NULL, *supbp = NULL;
        dev_t dev = vnode_specrdev(devvp);
        int error = EINVAL;
        int breaderr = 0;
-       u_long iso_bsize;
+       u_long iso_bsize, orig_bsize;
        int iso_blknum;
        int joliet_level;
        struct iso_volume_descriptor *vdp = NULL;
@@ -368,6 +367,16 @@ iso_mountfs(devvp, mp, argp, context)
        if (vfs_isrdwr(mp))
                return (EROFS);
 
+       /* Advisory locking should be handled at the VFS layer */
+       vfs_setlocklocal(mp);
+
+       /* Finish initializing hash tables */
+       cd9660_hashinit();
+
+       if ((error = VNOP_IOCTL(devvp, DKIOCGETBLOCKSIZE,
+            (caddr_t)&orig_bsize, 0, context)))
+               return (error);
+       
        /* This is the "logical sector size".  The standard says this
         * should be 2048 or the physical sector size on the device,
         * whichever is greater.  For now, we'll just use a constant.
@@ -392,7 +401,7 @@ iso_mountfs(devvp, mp, argp, context)
                        continue;
                }
 
-               vdp = (struct iso_volume_descriptor *)buf_dataptr(bp);
+               vdp = (struct iso_volume_descriptor *)((char *)0 + buf_dataptr(bp));
                if (bcmp (vdp->volume_desc_id, ISO_STANDARD_ID, sizeof(vdp->volume_desc_id)) != 0) {
 #ifdef DEBUG
                        printf("cd9660_vfsops.c: iso_mountfs: "
@@ -475,8 +484,8 @@ iso_mountfs(devvp, mp, argp, context)
        
        rootp = (struct iso_directory_record *)pri->root_directory_record;
        
-       MALLOC(isomp, struct iso_mnt *, sizeof *isomp, M_ISOFSMNT, M_WAITOK);
-       bzero((caddr_t)isomp, sizeof *isomp);
+       MALLOC(isomp, struct iso_mnt *, sizeof(*isomp), M_ISOFSMNT, M_WAITOK);
+       bzero((caddr_t)isomp, sizeof(*isomp));
        isomp->im_sector_size = ISO_DEFAULT_BLOCK_SIZE;
        isomp->logical_block_size = logical_block_size;
        isomp->volume_space_size = isonum_733 (pri->volume_space_size);
@@ -489,7 +498,7 @@ iso_mountfs(devvp, mp, argp, context)
         * filehandle validation.
         */
        isomp->volume_space_size += blkoff;
-       bcopy (rootp, isomp->root, sizeof isomp->root);
+       bcopy (rootp, isomp->root, sizeof(isomp->root));
        isomp->root_extent = isonum_733 (rootp->extent);
        isomp->root_size = isonum_733 (rootp->size);
 
@@ -509,7 +518,7 @@ iso_mountfs(devvp, mp, argp, context)
        }
 
        if (pri->volume_id[0] == 0)
-               strcpy(isomp->volume_id, ISO_DFLT_VOLUME_ID);
+               strlcpy(isomp->volume_id, ISO_DFLT_VOLUME_ID, sizeof(isomp->volume_id));
        else
                bcopy(pri->volume_id, isomp->volume_id, sizeof(isomp->volume_id));
        cd9660_tstamp_conv17(pri->creation_date, &isomp->creation_date);
@@ -564,7 +573,7 @@ iso_mountfs(devvp, mp, argp, context)
                        argp->flags |= ISOFSMNT_NORRIP;
                        goto skipRRIP;
                }
-               rootp = (struct iso_directory_record *)buf_dataptr(bp);
+               rootp = (struct iso_directory_record *)((char *)0 + buf_dataptr(bp));
                
                if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
                        argp->flags  |= ISOFSMNT_NORRIP;
@@ -610,9 +619,7 @@ skipRRIP:
                 *
                 * This name can have up to 16 UCS-2 chars.
                 */
-               convflags = UTF_DECOMPOSED;
-               if (BYTE_ORDER != BIG_ENDIAN)
-                       convflags |= UTF_REVERSE_ENDIAN;
+               convflags = UTF_DECOMPOSED | UTF_BIG_ENDIAN;
                uchp = (u_int16_t *)sup->volume_id;
                for (i = 0; i < 16 && uchp[i]; ++i);
                if ((utf8_encodestr((u_int16_t *)sup->volume_id, (i * 2), vol_id,
@@ -629,7 +636,7 @@ skipRRIP:
 
                rootp = (struct iso_directory_record *)
                        sup->root_directory_record;
-               bcopy (rootp, isomp->root, sizeof isomp->root);
+               bcopy (rootp, isomp->root, sizeof(isomp->root));
                isomp->root_extent = isonum_733 (rootp->extent);
                isomp->root_size = isonum_733 (rootp->size);
                buf_markaged(supbp);
@@ -659,6 +666,11 @@ skipRRIP:
 
        return (0);
 out:
+       if (orig_bsize != iso_bsize) {
+               (void)VNOP_IOCTL(devvp, DKIOCSETBLOCKSIZE,
+                       (caddr_t)&orig_bsize, FWRITE, context);
+       }
+
        if (bp)
                buf_brelse(bp);
        if (pribp)
@@ -694,7 +706,7 @@ cd9660_start(__unused struct mount *mp, __unused int flags,
 int
 cd9660_unmount(struct mount *mp, int mntflags, vfs_context_t context)
 {
-       register struct iso_mnt *isomp;
+       struct iso_mnt *isomp;
        int error, flags = 0;
        int force = 0;
        
@@ -750,10 +762,10 @@ cd9660_root(struct mount *mp, struct vnode **vpp, __unused vfs_context_t context
  */
 /* ARGSUSED */
 int
-cd9660_statfs(struct mount *mp, register struct vfsstatfs *sbp,
+cd9660_statfs(struct mount *mp, struct vfsstatfs *sbp,
              __unused vfs_context_t context)
 {
-       register struct iso_mnt *isomp;
+       struct iso_mnt *isomp;
        
        isomp = VFSTOISOFS(mp);
 
@@ -792,7 +804,7 @@ cd9660_statfs(struct mount *mp, register struct vfsstatfs *sbp,
        return (0);
 }
 
-int cd9660_vfs_getattr(struct mount *mp, struct vfs_attr *fsap, vfs_context_t context)
+int cd9660_vfs_getattr(struct mount *mp, struct vfs_attr *fsap, __unused vfs_context_t context)
 {
        struct iso_mnt *imp;
        struct vfsstatfs *stats = vfs_statfs(mp);
@@ -848,11 +860,7 @@ int cd9660_vfs_getattr(struct mount *mp, struct vfs_attr *fsap, vfs_context_t co
                        VOL_CAP_INT_SEARCHFS |
                        VOL_CAP_INT_ATTRLIST |
                        VOL_CAP_INT_NFSEXPORT |
-                       VOL_CAP_INT_READDIRATTR |
-                       VOL_CAP_INT_EXCHANGEDATA |
-                       VOL_CAP_INT_COPYFILE |
                        VOL_CAP_INT_ALLOCATE |
-                       VOL_CAP_INT_VOL_RENAME |
                        VOL_CAP_INT_ADVLOCK |
                        VOL_CAP_INT_FLOCK;
                fsap->f_capabilities.valid[VOL_CAPABILITIES_RESERVED1] = 0;
@@ -868,15 +876,19 @@ int cd9660_vfs_getattr(struct mount *mp, struct vfs_attr *fsap, vfs_context_t co
                 * VFS has implemented.
                 */
 
-               fsap->f_attributes.validattr.commonattr = ATTR_CMN_VALIDMASK;
-        fsap->f_attributes.validattr.volattr = ATTR_VOL_VALIDMASK;
-        fsap->f_attributes.validattr.dirattr = ATTR_DIR_VALIDMASK;
+#define ISOFS_ATTR_CMN_VALIDMASK       (ATTR_CMN_VALIDMASK & ~(ATTR_CMN_PAROBJID | ATTR_CMN_CRTIME | ATTR_CMN_BKUPTIME | ATTR_CMN_PARENTID))
+#define ISOFS_ATTR_VOL_VALIDMASK       (ATTR_VOL_VALIDMASK & ~(ATTR_VOL_OBJCOUNT | ATTR_VOL_FILECOUNT | ATTR_VOL_DIRCOUNT | ATTR_VOL_MAXOBJCOUNT | ATTR_VOL_NAME))
+#define ISOFS_ATTR_DIR_VALIDMASK       (ATTR_DIR_VALIDMASK & ~(ATTR_DIR_ENTRYCOUNT))
+
+               fsap->f_attributes.validattr.commonattr = ISOFS_ATTR_CMN_VALIDMASK;
+        fsap->f_attributes.validattr.volattr = ISOFS_ATTR_VOL_VALIDMASK;
+        fsap->f_attributes.validattr.dirattr = ISOFS_ATTR_DIR_VALIDMASK;
         fsap->f_attributes.validattr.fileattr = ATTR_FILE_VALIDMASK;
         fsap->f_attributes.validattr.forkattr = ATTR_FORK_VALIDMASK;
 
-               fsap->f_attributes.nativeattr.commonattr = ATTR_CMN_VALIDMASK;
-        fsap->f_attributes.nativeattr.volattr = ATTR_VOL_VALIDMASK;
-        fsap->f_attributes.nativeattr.dirattr = ATTR_DIR_VALIDMASK;
+               fsap->f_attributes.nativeattr.commonattr = ISOFS_ATTR_CMN_VALIDMASK;
+        fsap->f_attributes.nativeattr.volattr = ISOFS_ATTR_VOL_VALIDMASK;
+        fsap->f_attributes.nativeattr.dirattr = ISOFS_ATTR_DIR_VALIDMASK;
         fsap->f_attributes.nativeattr.fileattr = ATTR_FILE_VALIDMASK;
         fsap->f_attributes.nativeattr.forkattr = ATTR_FORK_VALIDMASK;
 
@@ -920,7 +932,7 @@ int
 cd9660_fhtovp(mount_t mp, int fhlen, unsigned char *fhp, vnode_t *vpp, vfs_context_t context)
 {
        struct ifid *ifhp = (struct ifid *)fhp;
-       register struct iso_node *ip;
+       struct iso_node *ip;
        struct vnode *nvp;
        int error;
        
@@ -932,7 +944,7 @@ cd9660_fhtovp(mount_t mp, int fhlen, unsigned char *fhp, vnode_t *vpp, vfs_conte
               ifhp->ifid_ino, ifhp->ifid_start);
 #endif
        
-       if ( (error = VFS_VGET(mp, (ino64_t)ifhp->ifid_ino, &nvp, context)) ) {
+       if ( (error = VFS_VGET(mp, (ino64_t)ntohl(ifhp->ifid_ino), &nvp, context)) ) {
                *vpp = NULLVP;
                return (error);
        }
@@ -1051,7 +1063,7 @@ cd9660_vget_internal(mount_t mp, ino_t ino, vnode_t *vpp, vnode_t dvp,
                     struct componentname *cnp, int relocated,
                     struct iso_directory_record *isodir, proc_t p)
 {
-       register struct iso_mnt *imp;
+       struct iso_mnt *imp;
        struct iso_node *ip;
        buf_t   bp = NULL;
        vnode_t vp;
@@ -1145,7 +1157,7 @@ cd9660_vget_internal(mount_t mp, ino_t ino, vnode_t *vpp, vnode_t dvp,
                        struct iso_directory_record *pdp;
 
                        pdp = (struct iso_directory_record *)
-                                       ((char *)buf_dataptr(bp) + isonum_711(isodir->length));
+                                       ((char *)0 + buf_dataptr(bp) + isonum_711(isodir->length));
                        if ((isonum_711(pdp->flags) & directoryBit)
                                        && (pdp->name[0] == 1))
                                ip->i_parent = isodirino(pdp, imp);
@@ -1178,7 +1190,7 @@ cd9660_vget_internal(mount_t mp, ino_t ino, vnode_t *vpp, vnode_t dvp,
                if ((error = (int)buf_bread(imp->im_devvp, lbn, imp->im_sector_size, NOCRED, &bp)))
                        goto errout;
 
-               isodir = (struct iso_directory_record *)buf_dataptr(bp);
+               isodir = (struct iso_directory_record *)((char *)0 + buf_dataptr(bp));
        }
 
        /*
@@ -1584,16 +1596,16 @@ DoneLooking:
 int
 cd9660_vptofh(struct vnode *vp, int *fhlenp, unsigned char *fhp, __unused vfs_context_t context)
 {
-       register struct iso_node *ip = VTOI(vp);
-       register struct ifid *ifhp;
+       struct iso_node *ip = VTOI(vp);
+       struct ifid *ifhp;
 
        if (*fhlenp < (int)sizeof(struct ifid))
                return (EOVERFLOW);
        
        ifhp = (struct ifid *)fhp;
        
-       ifhp->ifid_ino = ip->i_number;
-       ifhp->ifid_start = ip->iso_start;
+       ifhp->ifid_ino = htonl(ip->i_number);
+       ifhp->ifid_start = htonl(ip->iso_start);
        *fhlenp = sizeof(struct ifid);
        
 #ifdef ISOFS_DBG