]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/vn/vn.c
xnu-1504.15.3.tar.gz
[apple/xnu.git] / bsd / dev / vn / vn.c
index 9c8004db16a476925209aed881581d2c0326c196..bac9133319961485c683c18cb8b03f7637401a6c 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * 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 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.
- *
- * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 /*
 
 
 #include "shadow.h"
+static void 
+vndevice_do_init(void) __attribute__((section("__TEXT, initcode")));
 
 static ioctl_fcn_t             vnioctl_chr;
 static ioctl_fcn_t             vnioctl_blk;
@@ -159,7 +159,7 @@ static struct cdevsw vn_cdevsw = {
        /* ioctl */     vnioctl_chr,
        /* stop */      eno_stop,
        /* reset */     eno_reset,
-       /* ttys */      0,
+       /* ttys */      NULL,
        /* select */    eno_select,
        /* mmap */      eno_mmap,
        /* strategy */  eno_strat,
@@ -172,14 +172,14 @@ struct vn_softc {
        u_int64_t       sc_fsize;       /* file size in bytes           */
        u_int64_t       sc_size;        /* size of vn, sc_secsize scale */
        int             sc_flags;       /* flags                        */
-       u_long          sc_secsize;     /* sector size                  */
+       u_int32_t               sc_secsize;     /* sector size                  */
        struct vnode    *sc_vp;         /* vnode if not NULL            */
        uint32_t        sc_vid;
        int             sc_open_flags;
        struct vnode    *sc_shadow_vp;  /* shadow vnode if not NULL     */
        uint32_t        sc_shadow_vid;
        shadow_map_t *  sc_shadow_map;  /* shadow map if not NULL       */
-       kauth_cred_t sc_cred;   /* credentials                  */
+       kauth_cred_t    sc_cred;        /* credentials                  */
        u_int32_t       sc_options;     /* options                      */
        void *          sc_bdev;
        void *          sc_cdev;
@@ -196,25 +196,24 @@ static u_int32_t  vn_options;
 #define IFOPT(vn,opt) if (((vn)->sc_options|vn_options) & (opt))
 #define TESTOPT(vn,opt) (((vn)->sc_options|vn_options) & (opt))
 
-static int     setcred(struct vnode * vp, struct proc * p, 
-                       kauth_cred_t cred);
-static void    vnclear (struct vn_softc *vn, struct proc * p);
-static void vn_ioctl_to_64(struct vn_ioctl *from, struct user_vn_ioctl *to);
+static int     setcred(struct vnode * vp, kauth_cred_t cred);
+static void    vnclear (struct vn_softc *vn, vfs_context_t  ctx);
+static void vn_ioctl_to_64(struct vn_ioctl_32 *from, struct vn_ioctl_64 *to);
 void vndevice_init(void);
 int vndevice_root_image(char * path, char devname[], dev_t * dev_p);
 
 static int
 vniocattach_file(struct vn_softc *vn,
-                struct user_vn_ioctl *vniop,
+                struct vn_ioctl_64 *vniop,
                 dev_t dev,
                 int in_kernel,
-                struct proc *p);
+                proc_t p);
 static int
 vniocattach_shadow(struct vn_softc * vn,
-                  struct user_vn_ioctl *vniop,
+                  struct vn_ioctl_64 *vniop,
                   dev_t dev,
                   int in_kernel,
-                  struct proc *p);
+                  proc_t p);
 static __inline__ int
 vnunit(dev_t dev)
 {
@@ -223,13 +222,13 @@ vnunit(dev_t dev)
 
 static int
 vnclose(__unused dev_t dev, __unused int flags, 
-               __unused int devtype, __unused struct proc *p)
+               __unused int devtype, __unused proc_t p)
 {
        return (0);
 }
 
 static int
-vnopen(dev_t dev, int flags, __unused int devtype, __unused struct proc *p)
+vnopen(dev_t dev, int flags, __unused int devtype, __unused proc_t p)
 {
        struct vn_softc *vn;
        int unit;
@@ -246,7 +245,7 @@ vnopen(dev_t dev, int flags, __unused int devtype, __unused struct proc *p)
 }
 
 static int
-file_io(struct vnode * vp, struct vfs_context * context_p
+file_io(struct vnode * vp, vfs_context_t ctx
        enum uio_rw op, char * base, off_t offset, user_ssize_t count,
        user_ssize_t * resid)
 {
@@ -258,9 +257,9 @@ file_io(struct vnode * vp, struct vfs_context * context_p,
                                    &uio_buf[0], sizeof(uio_buf));
        uio_addiov(auio, CAST_USER_ADDR_T(base), count);
        if (op == UIO_READ)
-               error = VNOP_READ(vp, auio, IO_SYNC, context_p);
+               error = VNOP_READ(vp, auio, IO_SYNC, ctx);
        else
-               error = VNOP_WRITE(vp, auio, IO_SYNC, context_p);
+               error = VNOP_WRITE(vp, auio, IO_SYNC, ctx);
 
        if (resid != NULL) {
                *resid = uio_resid(auio);
@@ -288,9 +287,9 @@ block_remainder(off_t o, int blocksize)
 
 static int
 vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, 
-             struct vfs_context * context_p)
+             vfs_context_t ctx)
 {
-       u_long          blocksize = vn->sc_secsize;
+       u_int32_t               blocksize = vn->sc_secsize;
        int             error = 0;
        off_t           offset;
        user_ssize_t    resid;
@@ -301,9 +300,9 @@ vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
        orig_offset = offset = uio_offset(uio);
 
        while (resid > 0) {
-               u_long          remainder;
-               u_long          this_block_number;
-               u_long          this_block_count;
+               u_int32_t               remainder;
+               u_int32_t               this_block_number;
+               u_int32_t               this_block_count;
                off_t           this_offset;
                user_ssize_t    this_resid;
                struct vnode *  vp;
@@ -328,7 +327,7 @@ vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
                        this_resid = resid;
                }
                uio_setresid(uio, this_resid);
-               error = VNOP_READ(vp, uio, ioflag, context_p);
+               error = VNOP_READ(vp, uio, ioflag, ctx);
                if (error) {
                        break;
                }
@@ -348,8 +347,8 @@ vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
 }
 
 static int
-vncopy_block_to_shadow(struct vn_softc * vn, struct vfs_context * context_p,
-                      u_long file_block, u_long shadow_block)
+vncopy_block_to_shadow(struct vn_softc * vn, vfs_context_t ctx,
+                      u_int32_t file_block, u_int32_t shadow_block)
 {
        int     error;
        char *  tmpbuf;
@@ -359,14 +358,14 @@ vncopy_block_to_shadow(struct vn_softc * vn, struct vfs_context * context_p,
            return (ENOMEM);
        }
        /* read one block from file at file_block offset */
-       error = file_io(vn->sc_vp, context_p, UIO_READ,
+       error = file_io(vn->sc_vp, ctx, UIO_READ,
                        tmpbuf, (off_t)file_block * vn->sc_secsize, 
                        vn->sc_secsize, NULL);
        if (error) {
                goto done;
        }
        /* write one block to shadow file at shadow_block offset */
-       error = file_io(vn->sc_shadow_vp, context_p, UIO_WRITE,
+       error = file_io(vn->sc_shadow_vp, ctx, UIO_WRITE,
                        tmpbuf, (off_t)shadow_block * vn->sc_secsize, 
                        vn->sc_secsize, NULL);
  done:
@@ -381,9 +380,9 @@ enum {
 
 static int
 vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, 
-              struct vfs_context * context_p)
+              vfs_context_t ctx)
 {
-       u_long          blocksize = vn->sc_secsize;
+       u_int32_t               blocksize = vn->sc_secsize;
        int             error = 0;
        user_ssize_t    resid;
        off_t           offset;
@@ -393,11 +392,11 @@ vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
 
        while (resid > 0) {
                int             flags = 0;
-               u_long          offset_block_number;
-               u_long          remainder;
-               u_long          resid_block_count;
-               u_long          shadow_block_count;
-               u_long          shadow_block_number;
+               u_int32_t               offset_block_number;
+               u_int32_t               remainder;
+               u_int32_t               resid_block_count;
+               u_int32_t               shadow_block_count;
+               u_int32_t               shadow_block_number;
                user_ssize_t    this_resid;
 
                /* figure out which blocks to write */
@@ -429,9 +428,8 @@ vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
                        off_t   size;
                        size = (off_t)shadow_map_shadow_size(vn->sc_shadow_map) 
                                * vn->sc_secsize;
-                       vnode_setsize(vn->sc_shadow_vp, size, IO_SYNC, 
-                                     context_p);
-#endif 0
+                       vnode_setsize(vn->sc_shadow_vp, size, IO_SYNC, ctx);
+#endif
                }
                /* write the blocks (or parts thereof) */
                uio_setoffset(uio, (off_t)
@@ -441,18 +439,17 @@ vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
                        this_resid = resid;
                        if ((flags & FLAGS_LAST_BLOCK_PARTIAL) != 0) {
                                /* copy the last block to the shadow */
-                               u_long  d;
-                               u_long  s;
+                               u_int32_t       d;
+                               u_int32_t       s;
 
                                s = offset_block_number 
                                        + resid_block_count - 1;
                                d = shadow_block_number 
                                        + shadow_block_count - 1;
-                               error = vncopy_block_to_shadow(vn, context_p,
-                                                              s, d);
+                               error = vncopy_block_to_shadow(vn, ctx, s, d);
                                if (error) {
                                        printf("vnwrite_shadow: failed to copy"
-                                              " block %d to shadow block %d\n",
+                                              " block %u to shadow block %u\n",
                                               s, d);
                                        break;
                                }
@@ -461,18 +458,18 @@ vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag,
                uio_setresid(uio, this_resid);
                if ((flags & FLAGS_FIRST_BLOCK_PARTIAL) != 0) {
                        /* copy the first block to the shadow */
-                       error = vncopy_block_to_shadow(vn, context_p,
+                       error = vncopy_block_to_shadow(vn, ctx,
                                                       offset_block_number,
                                                       shadow_block_number);
                        if (error) {
                                printf("vnwrite_shadow: failed to"
-                                      " copy block %d to shadow block %d\n", 
+                                      " copy block %u to shadow block %u\n", 
                                       offset_block_number, 
                                       shadow_block_number);
                                break;
                        }
                }
-               error = VNOP_WRITE(vn->sc_shadow_vp, uio, ioflag, context_p);
+               error = VNOP_WRITE(vn->sc_shadow_vp, uio, ioflag, ctx);
                if (error) {
                        break;
                }
@@ -497,7 +494,7 @@ vnread(dev_t dev, struct uio *uio, int ioflag)
        int                     error = 0;
        boolean_t               funnel_state;
        off_t                   offset;
-       struct proc *           p;
+       proc_t                  p;
        user_ssize_t            resid;
        struct vn_softc *       vn;
        int                     unit;
@@ -513,11 +510,15 @@ vnread(dev_t dev, struct uio *uio, int ioflag)
                error = ENXIO;
                goto done;
        }
+
+       context.vc_thread = current_thread();
+       context.vc_ucred = vn->sc_cred;
+
        error = vnode_getwithvid(vn->sc_vp, vn->sc_vid);
        if (error != 0) {
                /* the vnode is no longer available, abort */
                error = ENXIO;
-               vnclear(vn, p);
+               vnclear(vn, &context);
                goto done;
        }
 
@@ -542,8 +543,6 @@ vnread(dev_t dev, struct uio *uio, int ioflag)
                uio_setresid(uio, resid);
        }
 
-       context.vc_proc = p;
-       context.vc_ucred = vn->sc_cred;
        if (vn->sc_shadow_vp != NULL) {
                error = vnode_getwithvid(vn->sc_shadow_vp,
                                         vn->sc_shadow_vid);
@@ -551,7 +550,7 @@ vnread(dev_t dev, struct uio *uio, int ioflag)
                        /* the vnode is no longer available, abort */
                        error = ENXIO;
                        vnode_put(vn->sc_vp);
-                       vnclear(vn, p);
+                       vnclear(vn, &context);
                        goto done;
                }
                error = vnread_shadow(vn, uio, ioflag, &context);
@@ -572,7 +571,7 @@ vnwrite(dev_t dev, struct uio *uio, int ioflag)
        int                     error;
        boolean_t               funnel_state;
        off_t                   offset;
-       struct proc *           p;
+       proc_t                  p;
        user_ssize_t            resid;
        struct vn_softc *       vn;
        int                     unit;
@@ -592,11 +591,15 @@ vnwrite(dev_t dev, struct uio *uio, int ioflag)
                error = EROFS;
                goto done;
        }
+
+       context.vc_thread = current_thread();
+       context.vc_ucred = vn->sc_cred;
+
        error = vnode_getwithvid(vn->sc_vp, vn->sc_vid);
        if (error != 0) {
                /* the vnode is no longer available, abort */
                error = ENXIO;
-               vnclear(vn, p);
+               vnclear(vn, &context);
                goto done;
        }
        resid = uio_resid(uio);
@@ -620,9 +623,6 @@ vnwrite(dev_t dev, struct uio *uio, int ioflag)
                uio_setresid(uio, resid);
        }
 
-       context.vc_proc = p;
-       context.vc_ucred = vn->sc_cred;
-
        if (vn->sc_shadow_vp != NULL) {
                error = vnode_getwithvid(vn->sc_shadow_vp,
                                         vn->sc_shadow_vid);
@@ -630,7 +630,7 @@ vnwrite(dev_t dev, struct uio *uio, int ioflag)
                        /* the vnode is no longer available, abort */
                        error = ENXIO;
                        vnode_put(vn->sc_vp);
-                       vnclear(vn, p);
+                       vnclear(vn, &context);
                        goto done;
                }
                error = vnwrite_shadow(vn, uio, ioflag, &context);
@@ -645,24 +645,22 @@ vnwrite(dev_t dev, struct uio *uio, int ioflag)
 }
 
 static int
-shadow_read(struct vn_softc * vn, struct buf * bp, char * base, struct proc * p)
+shadow_read(struct vn_softc * vn, struct buf * bp, char * base,
+       vfs_context_t ctx)
 {
-       u_long          blocksize = vn->sc_secsize;
-       struct vfs_context  context; 
+       u_int32_t               blocksize = vn->sc_secsize;
        int             error = 0;
-       u_long          offset;
+       u_int32_t               offset;
        boolean_t       read_shadow;
-       u_long          resid;
-       u_long          start = 0;
+       u_int32_t               resid;
+       u_int32_t               start = 0;
 
-       context.vc_proc = p;
-       context.vc_ucred = vn->sc_cred;
        offset = buf_blkno(bp);
        resid =  buf_resid(bp) / blocksize;
        while (resid > 0) {
                user_ssize_t    temp_resid;
-               u_long          this_offset;
-               u_long          this_resid;
+               u_int32_t               this_offset;
+               u_int32_t               this_resid;
                struct vnode *  vp;
 
                read_shadow = shadow_map_read(vn->sc_shadow_map,
@@ -674,7 +672,7 @@ shadow_read(struct vn_softc * vn, struct buf * bp, char * base, struct proc * p)
                else {
                        vp = vn->sc_vp;
                }
-               error = file_io(vp, &context, UIO_READ, base + start,
+               error = file_io(vp, ctx, UIO_READ, base + start,
                                (off_t)this_offset * blocksize,
                                (user_ssize_t)this_resid * blocksize, 
                                &temp_resid);
@@ -696,24 +694,21 @@ shadow_read(struct vn_softc * vn, struct buf * bp, char * base, struct proc * p)
 
 static int
 shadow_write(struct vn_softc * vn, struct buf * bp, char * base, 
-            struct proc * p)
+            vfs_context_t ctx)
 {
-       u_long          blocksize = vn->sc_secsize;
-       struct vfs_context  context; 
+       u_int32_t               blocksize = vn->sc_secsize;
        int             error = 0;
-       u_long          offset;
+       u_int32_t               offset;
        boolean_t       shadow_grew;
-       u_long          resid;
-       u_long          start = 0;
+       u_int32_t               resid;
+       u_int32_t               start = 0;
 
-       context.vc_proc = p;
-       context.vc_ucred = vn->sc_cred;
        offset = buf_blkno(bp);
        resid =  buf_resid(bp) / blocksize;
        while (resid > 0) {
                user_ssize_t    temp_resid;
-               u_long          this_offset;
-               u_long          this_resid;
+               u_int32_t               this_offset;
+               u_int32_t               this_resid;
 
                shadow_grew = shadow_map_write(vn->sc_shadow_map, 
                                               offset, resid, 
@@ -724,11 +719,10 @@ shadow_write(struct vn_softc * vn, struct buf * bp, char * base,
                        /* truncate the file to its new length before write */
                        size = (off_t)shadow_map_shadow_size(vn->sc_shadow_map) 
                                * blocksize;
-                       vnode_setsize(vn->sc_shadow_vp, size, IO_SYNC,
-                                     &context);
+                       vnode_setsize(vn->sc_shadow_vp, size, IO_SYNC, ctx);
 #endif
                }
-               error = file_io(vn->sc_shadow_vp, &context, UIO_WRITE, 
+               error = file_io(vn->sc_shadow_vp, ctx, UIO_WRITE, 
                                base + start,
                                (off_t)this_offset * blocksize,
                                (user_ssize_t)this_resid * blocksize, 
@@ -750,25 +744,20 @@ shadow_write(struct vn_softc * vn, struct buf * bp, char * base,
 }
 
 static int
-vn_readwrite_io(struct vn_softc * vn, struct buf * bp, struct proc * p)
+vn_readwrite_io(struct vn_softc * vn, struct buf * bp, vfs_context_t ctx)
 {
        int                     error = 0;
        char *                  iov_base;
        caddr_t                 vaddr;
-       
 
        if (buf_map(bp, &vaddr)) 
                panic("vn device: buf_map failed");
        iov_base = (char *)vaddr;
 
        if (vn->sc_shadow_vp == NULL) {
-               struct vfs_context      context; 
                user_ssize_t            temp_resid;
 
-               context.vc_proc = p;
-               context.vc_ucred = vn->sc_cred;
-
-               error = file_io(vn->sc_vp, &context,
+               error = file_io(vn->sc_vp, ctx,
                                buf_flags(bp) & B_READ ? UIO_READ : UIO_WRITE,
                                iov_base,
                                (off_t)buf_blkno(bp) * vn->sc_secsize,
@@ -777,9 +766,9 @@ vn_readwrite_io(struct vn_softc * vn, struct buf * bp, struct proc * p)
        }
        else {
                if (buf_flags(bp) & B_READ)
-                       error = shadow_read(vn, bp, iov_base, p);
+                       error = shadow_read(vn, bp, iov_base, ctx);
                else
-                       error = shadow_write(vn, bp, iov_base, p);
+                       error = shadow_write(vn, bp, iov_base, ctx);
        }
        buf_unmap(bp);
 
@@ -794,9 +783,9 @@ vnstrategy(struct buf *bp)
        long sz;        /* in sc_secsize chunks */
        daddr64_t blk_num;
        boolean_t               funnel_state;
-       struct proc *           p = current_proc();
        struct vnode *          shadow_vp = NULL;
        struct vnode *          vp = NULL;
+       struct vfs_context      context; 
 
        funnel_state = thread_funnel_set(kernel_flock, TRUE);
        vn = vn_table + vnunit(buf_device(bp));
@@ -805,6 +794,9 @@ vnstrategy(struct buf *bp)
                goto done;
        }
 
+       context.vc_thread = current_thread();
+       context.vc_ucred = vn->sc_cred;
+
        buf_setresid(bp, buf_count(bp));
        /*
         * Check for required alignment.  Transfers must be a valid
@@ -839,11 +831,12 @@ vnstrategy(struct buf *bp)
                error = ENXIO;
                goto done;
        }
+
        error = vnode_getwithvid(vp, vn->sc_vid);
        if (error != 0) {
                /* the vnode is no longer available, abort */
                error = ENXIO;
-               vnclear(vn, p);
+               vnclear(vn, &context);
                goto done;
        }
        shadow_vp = vn->sc_shadow_vp;
@@ -854,11 +847,12 @@ vnstrategy(struct buf *bp)
                        /* the vnode is no longer available, abort */
                        error = ENXIO;
                        vnode_put(vn->sc_vp);
-                       vnclear(vn, p);
+                       vnclear(vn, &context);
                        goto done;
                }
        }
-       error = vn_readwrite_io(vn, bp, p);
+
+       error = vn_readwrite_io(vn, bp, &context);
        vnode_put(vp);
        if (shadow_vp != NULL) {
                vnode_put(shadow_vp);
@@ -876,18 +870,19 @@ vnstrategy(struct buf *bp)
 /* ARGSUSED */
 static int
 vnioctl(dev_t dev, u_long cmd, caddr_t data,
-       __unused int flag, struct proc *p,
+       __unused int flag, proc_t p,
        int is_char)
 {
        struct vn_softc *vn;
-       struct user_vn_ioctl *viop;
+       struct vn_ioctl_64 *viop;
        int error;
        u_int32_t *f;
        u_int64_t * o;
        int unit;
        struct vfsioattr ioattr;
-       struct user_vn_ioctl user_vnio;
+       struct vn_ioctl_64 user_vnio;
        boolean_t               funnel_state;
+       struct vfs_context      context; 
 
        unit = vnunit(dev);
        if (vnunit(dev) >= NVNDEVICE) {
@@ -901,12 +896,20 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
                goto done;
        }
 
-       viop = (struct user_vn_ioctl *)data;
+       context.vc_thread = current_thread();
+       context.vc_ucred = vn->sc_cred;
+
+       viop = (struct vn_ioctl_64 *)data;
        f = (u_int32_t *)data;
        o = (u_int64_t *)data;
        switch (cmd) {
+#ifdef __LP64__
+       case VNIOCDETACH32:
+       case VNIOCDETACH:
+#else
        case VNIOCDETACH:
        case VNIOCDETACH64:
+#endif
        case DKIOCGETBLOCKSIZE:
        case DKIOCSETBLOCKSIZE:
        case DKIOCGETMAXBLOCKCOUNTREAD:
@@ -993,8 +996,13 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
        case DKIOCGETBLOCKCOUNT:
                *o = vn->sc_size;
                break;
+#ifdef __LP64__
+       case VNIOCSHADOW32:
+       case VNIOCSHADOW:
+#else
        case VNIOCSHADOW:
        case VNIOCSHADOW64:
+#endif
                if (vn->sc_shadow_vp != NULL) {
                        error = EBUSY;
                        break;
@@ -1006,7 +1014,7 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
                }
                if (!proc_is64bit(p)) {
                        /* downstream code expects LP64 version of vn_ioctl structure */
-                       vn_ioctl_to_64((struct vn_ioctl *)viop, &user_vnio);
+                       vn_ioctl_to_64((struct vn_ioctl_32 *)viop, &user_vnio);
                        viop = &user_vnio;
                }
                if (viop->vn_file == USER_ADDR_NULL) {
@@ -1016,8 +1024,13 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
                error = vniocattach_shadow(vn, viop, dev, 0, p);
                break;
 
+#ifdef __LP64__
+       case VNIOCATTACH32:
+       case VNIOCATTACH:
+#else
        case VNIOCATTACH:
        case VNIOCATTACH64:
+#endif
                if (is_char) {
                        /* attach only on block device */
                        error = ENODEV;
@@ -1029,7 +1042,7 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
                }
                if (!proc_is64bit(p)) {
                        /* downstream code expects LP64 version of vn_ioctl structure */
-                       vn_ioctl_to_64((struct vn_ioctl *)viop, &user_vnio);
+                       vn_ioctl_to_64((struct vn_ioctl_32 *)viop, &user_vnio);
                        viop = &user_vnio;
                }
                if (viop->vn_file == USER_ADDR_NULL) {
@@ -1039,8 +1052,13 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
                error = vniocattach_file(vn, viop, dev, 0, p);
                break;
 
+#ifdef __LP64__
+       case VNIOCDETACH32:
+       case VNIOCDETACH:
+#else
        case VNIOCDETACH:
        case VNIOCDETACH64:
+#endif
                if (is_char) {
                        /* detach only on block device */
                        error = ENODEV;
@@ -1056,7 +1074,7 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
                 * How are these problems handled for removable and failing
                 * hardware devices? (Hint: They are not)
                 */
-               vnclear(vn, p);
+               vnclear(vn, &context);
                break;
 
        case VNIOCGSET:
@@ -1089,13 +1107,13 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data,
 }
 
 static int
-vnioctl_chr(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+vnioctl_chr(dev_t dev, u_long cmd, caddr_t data, int flag, proc_t p)
 {
        return (vnioctl(dev, cmd, data, flag, p, TRUE));
 }
 
 static int
-vnioctl_blk(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+vnioctl_blk(dev_t dev, u_long cmd, caddr_t data, int flag, proc_t p)
 {
        return (vnioctl(dev, cmd, data, flag, p, FALSE));
 }
@@ -1109,67 +1127,66 @@ vnioctl_blk(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 
 static int
 vniocattach_file(struct vn_softc *vn,
-                struct user_vn_ioctl *vniop,
+                struct vn_ioctl_64 *vniop,
                 dev_t dev,
                 int in_kernel,
-                struct proc *p)
+                proc_t p)
 {
        dev_t   cdev;
-       struct vfs_context context;
+       vfs_context_t ctx = vfs_context_current();
        kauth_cred_t cred;
        struct nameidata nd;
        off_t file_size;
        int error, flags;
 
-       context.vc_proc = p;
-       context.vc_ucred = proc_ucred(p);
-       
        flags = FREAD|FWRITE;
        if (in_kernel) {
-               NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE32, vniop->vn_file, &context);
+               NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, vniop->vn_file, ctx);
        }
        else {
                NDINIT(&nd, LOOKUP, FOLLOW, 
                           (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), 
-                          vniop->vn_file, &context);
+                          vniop->vn_file, ctx);
        }
        /* vn_open gives both long- and short-term references */
        error = vn_open(&nd, flags, 0);
        if (error) {
-               if (error != EACCES && error != EPERM && error != EROFS)
+               if (error != EACCES && error != EPERM && error != EROFS) {
                        return (error);
+               }
                flags &= ~FWRITE;
                if (in_kernel) {
-                       NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE32
-                              vniop->vn_file, &context);
+                       NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, 
+                              vniop->vn_file, ctx);
                }
                else {
                        NDINIT(&nd, LOOKUP, FOLLOW, 
                                   (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), 
-                              vniop->vn_file, &context);
+                              vniop->vn_file, ctx);
                }
                error = vn_open(&nd, flags, 0);
-               if (error)
+               if (error) {
                        return (error);
+               }
        }
        if (nd.ni_vp->v_type != VREG) {
                error = EINVAL;
        }
        else {
-               error = vnode_size(nd.ni_vp, &file_size, &context);
+               error = vnode_size(nd.ni_vp, &file_size, ctx);
        }
        if (error != 0) {
-               (void) vn_close(nd.ni_vp, flags, proc_ucred(p), p);
+               (void) vn_close(nd.ni_vp, flags, ctx);
                vnode_put(nd.ni_vp);
                return (error);
        }
        cred = kauth_cred_proc_ref(p);
        nd.ni_vp->v_flag |= VNOCACHE_DATA;
-       error = setcred(nd.ni_vp, p, cred);
+       error = setcred(nd.ni_vp, cred);
        if (error) {
-               (void)vn_close(nd.ni_vp, flags, proc_ucred(p), p);
+               (void)vn_close(nd.ni_vp, flags, ctx);
                vnode_put(nd.ni_vp);
-               kauth_cred_rele(cred);
+               kauth_cred_unref(&cred);
                return(error);
        }
        vn->sc_secsize = DEV_BSIZE;
@@ -1193,26 +1210,23 @@ vniocattach_file(struct vn_softc *vn,
 }
 
 static int
-vniocattach_shadow(struct vn_softc *vn, struct user_vn_ioctl *vniop, 
-                                  __unused int dev, int in_kernel, struct proc *p)
+vniocattach_shadow(struct vn_softc *vn, struct vn_ioctl_64 *vniop, 
+                                  __unused dev_t dev, int in_kernel, proc_t p)
 {
-       struct vfs_context context;
+       vfs_context_t ctx = vfs_context_current();
        struct nameidata nd;
        int error, flags;
        shadow_map_t *  map;
        off_t file_size;
 
-       context.vc_proc = p;
-       context.vc_ucred = proc_ucred(p);
-       
        flags = FREAD|FWRITE;
        if (in_kernel) {
-               NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE32, vniop->vn_file, &context);
+               NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, vniop->vn_file, ctx);
        }
        else {
                NDINIT(&nd, LOOKUP, FOLLOW, 
                           (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), 
-                          vniop->vn_file, &context);
+                          vniop->vn_file, ctx);
        }
        /* vn_open gives both long- and short-term references */
        error = vn_open(&nd, flags, 0);
@@ -1221,15 +1235,15 @@ vniocattach_shadow(struct vn_softc *vn, struct user_vn_ioctl *vniop,
                return (error);
        }
        if (nd.ni_vp->v_type != VREG 
-           || (error = vnode_size(nd.ni_vp, &file_size, &context))) {
-               (void)vn_close(nd.ni_vp, flags, proc_ucred(p), p);
+           || (error = vnode_size(nd.ni_vp, &file_size, ctx))) {
+               (void)vn_close(nd.ni_vp, flags, ctx);
                vnode_put(nd.ni_vp);
                return (error ? error : EINVAL);
        }
        map = shadow_map_create(vn->sc_fsize, file_size,
                                0, vn->sc_secsize);
        if (map == NULL) {
-               (void)vn_close(nd.ni_vp, flags, proc_ucred(p), p);
+               (void)vn_close(nd.ni_vp, flags, ctx);
                vnode_put(nd.ni_vp);
                vn->sc_shadow_vp = NULL;
                return (ENOMEM);
@@ -1250,7 +1264,7 @@ vndevice_root_image(char * path, char devname[], dev_t * dev_p)
 {
        int                     error = 0;
        struct vn_softc *               vn;
-       struct user_vn_ioctl    vnio;
+       struct vn_ioctl_64      vnio;
 
        vnio.vn_file = CAST_USER_ADDR_T(path);
        vnio.vn_size = 0;
@@ -1258,7 +1272,7 @@ vndevice_root_image(char * path, char devname[], dev_t * dev_p)
        vn = vn_table + ROOT_IMAGE_UNIT;
        *dev_p = makedev(vndevice_bdev_major, 
                         ROOT_IMAGE_UNIT);
-       sprintf(devname, "vn%d", ROOT_IMAGE_UNIT);
+       snprintf(devname, 16, "vn%d", ROOT_IMAGE_UNIT);
        error = vniocattach_file(vn, &vnio, *dev_p, 1, current_proc());
        return (error);
 }
@@ -1270,7 +1284,7 @@ vndevice_root_image(char * path, char devname[], dev_t * dev_p)
  * if some other uid can write directly to the mapped file (NFS).
  */
 static int
-setcred(struct vnode * vp, struct proc * p, kauth_cred_t cred)
+setcred(struct vnode * vp, kauth_cred_t cred)
 {
        char *tmpbuf;
        int error = 0;
@@ -1279,7 +1293,7 @@ setcred(struct vnode * vp, struct proc * p, kauth_cred_t cred)
        /*
         * Horrible kludge to establish credentials for NFS  XXX.
         */
-       context.vc_proc = p;
+       context.vc_thread = current_thread();
        context.vc_ucred = cred;
        tmpbuf = _MALLOC(DEV_BSIZE, M_TEMP, M_WAITOK);
        error = file_io(vp, &context, UIO_READ, tmpbuf, 0, DEV_BSIZE, NULL);
@@ -1288,17 +1302,16 @@ setcred(struct vnode * vp, struct proc * p, kauth_cred_t cred)
 }
 
 void
-vnclear(struct vn_softc *vn, struct proc * p)
+vnclear(struct vn_softc *vn, vfs_context_t ctx)
 {
        if (vn->sc_vp != NULL) {
                /* release long-term reference */
-               (void)vn_close(vn->sc_vp, vn->sc_open_flags, vn->sc_cred, p);
+               (void)vn_close(vn->sc_vp, vn->sc_open_flags, ctx);
                vn->sc_vp = NULL;
        }
        if (vn->sc_shadow_vp != NULL) {
                /* release long-term reference */
-               (void)vn_close(vn->sc_shadow_vp, FREAD | FWRITE, 
-                              vn->sc_cred, p);
+               (void)vn_close(vn->sc_shadow_vp, FREAD | FWRITE, ctx);
                vn->sc_shadow_vp = NULL;
        }
        if (vn->sc_shadow_map != NULL) {
@@ -1307,8 +1320,7 @@ vnclear(struct vn_softc *vn, struct proc * p)
        }
        vn->sc_flags &= ~(VNF_INITED | VNF_READONLY);
        if (vn->sc_cred) {
-               kauth_cred_rele(vn->sc_cred);
-               vn->sc_cred = NULL;
+               kauth_cred_unref(&vn->sc_cred);
        }
        vn->sc_size = 0;
        vn->sc_fsize = 0;
@@ -1348,10 +1360,17 @@ static int vndevice_inited = 0;
 void 
 vndevice_init(void)
 {
-       int     i;
-
        if (vndevice_inited)
                return;
+               
+       vndevice_do_init();
+}
+               
+static void 
+vndevice_do_init( void )
+{
+       int     i;
+
        vndevice_bdev_major = bdevsw_add(BDEV_MAJOR, &vn_bdevsw);
 
        if (vndevice_bdev_major < 0) {
@@ -1378,7 +1397,7 @@ vndevice_init(void)
 }
 
 static void 
-vn_ioctl_to_64(struct vn_ioctl *from, struct user_vn_ioctl *to) 
+vn_ioctl_to_64(struct vn_ioctl_32 *from, struct vn_ioctl_64 *to) 
 {
        to->vn_file = CAST_USER_ADDR_T(from->vn_file);
        to->vn_size = from->vn_size;