X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/378393581903b274cb7a4d18e0d978071a6b592d..a991bd8d3e7fe02dbca0644054bab73c5b75324a:/bsd/dev/vn/vn.c?ds=sidebyside diff --git a/bsd/dev/vn/vn.c b/bsd/dev/vn/vn.c index 265270a3a..b0ef8539f 100644 --- a/bsd/dev/vn/vn.c +++ b/bsd/dev/vn/vn.c @@ -1,23 +1,29 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2019 Apple Inc. All rights reserved. * - * @APPLE_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 Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * @APPLE_OSREFERENCE_LICENSE_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. + * + * 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. - * - * @APPLE_LICENSE_HEADER_END@ + * 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_OSREFERENCE_LICENSE_HEADER_END@ */ /* @@ -114,18 +120,20 @@ #include "shadow.h" +static void +vndevice_do_init(void); -static ioctl_fcn_t vnioctl_chr; -static ioctl_fcn_t vnioctl_blk; -static open_close_fcn_t vnopen; -static open_close_fcn_t vnclose; -static psize_fcn_t vnsize; -static strategy_fcn_t vnstrategy; -static read_write_fcn_t vnread; -static read_write_fcn_t vnwrite; +static ioctl_fcn_t vnioctl_chr; +static ioctl_fcn_t vnioctl_blk; +static open_close_fcn_t vnopen; +static open_close_fcn_t vnclose; +static psize_fcn_t vnsize; +static strategy_fcn_t vnstrategy; +static read_write_fcn_t vnread; +static read_write_fcn_t vnwrite; -static int vndevice_bdev_major; -static int vndevice_cdev_major; +static int vndevice_bdev_major; +static int vndevice_cdev_major; /* * cdevsw @@ -133,194 +141,194 @@ static int vndevice_cdev_major; * D_CANFREE We support B_FREEBUF */ -static struct bdevsw vn_bdevsw = { - /* open */ vnopen, - /* close */ vnclose, - /* strategy */ vnstrategy, - /* ioctl */ vnioctl_blk, - /* dump */ eno_dump, - /* psize */ vnsize, - /* flags */ D_DISK, +static const struct bdevsw vn_bdevsw = { + .d_open = vnopen, + .d_close = vnclose, + .d_strategy = vnstrategy, + .d_ioctl = vnioctl_blk, + .d_dump = eno_dump, + .d_psize = vnsize, + .d_type = D_DISK, }; -static struct cdevsw vn_cdevsw = { - /* open */ vnopen, - /* close */ vnclose, - /* read */ vnread, - /* write */ vnwrite, - /* ioctl */ vnioctl_chr, - /* stop */ eno_stop, - /* reset */ eno_reset, - /* ttys */ 0, - /* select */ eno_select, - /* mmap */ eno_mmap, - /* strategy */ eno_strat, - /* getc */ eno_getc, - /* putc */ eno_putc, - /* flags */ D_DISK, +static const struct cdevsw vn_cdevsw = { + .d_open = vnopen, + .d_close = vnclose, + .d_read = vnread, + .d_write = vnwrite, + .d_ioctl = vnioctl_chr, + .d_stop = eno_stop, + .d_reset = eno_reset, + .d_ttys = NULL, + .d_select = eno_select, + .d_mmap = eno_mmap, + .d_strategy = eno_strat, + .d_reserved_1 = eno_getc, + .d_reserved_2 = eno_putc, + .d_type = D_DISK, }; 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 */ - 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 */ - u_int32_t sc_options; /* options */ - void * sc_bdev; - void * sc_cdev; + 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_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 */ + u_int32_t sc_options; /* options */ + void * sc_bdev; + void * sc_cdev; } vn_table[NVNDEVICE]; -#define ROOT_IMAGE_UNIT 0 +#define ROOT_IMAGE_UNIT 0 /* sc_flags */ -#define VNF_INITED 0x01 -#define VNF_READONLY 0x02 +#define VNF_INITED 0x01 +#define VNF_READONLY 0x02 -static u_int32_t vn_options; +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)) +#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, - dev_t dev, - int in_kernel, - struct proc *p); + struct vn_ioctl_64 *vniop, + dev_t dev, + int in_kernel, + proc_t p); static int vniocattach_shadow(struct vn_softc * vn, - struct user_vn_ioctl *vniop, - dev_t dev, - int in_kernel, - struct proc *p); + struct vn_ioctl_64 *vniop, + dev_t dev, + int in_kernel, + proc_t p); static __inline__ int vnunit(dev_t dev) { - return (minor(dev)); + return minor(dev); } -static int -vnclose(__unused dev_t dev, __unused int flags, - __unused int devtype, __unused struct proc *p) +static int +vnclose(__unused dev_t dev, __unused int flags, + __unused int devtype, __unused proc_t p) { - return (0); + return 0; } -static int -vnopen(dev_t dev, int flags, __unused int devtype, __unused struct proc *p) +static int +vnopen(dev_t dev, int flags, __unused int devtype, __unused proc_t p) { struct vn_softc *vn; int unit; unit = vnunit(dev); if (vnunit(dev) >= NVNDEVICE) { - return (ENXIO); + return ENXIO; } vn = vn_table + unit; - if ((flags & FWRITE) && (vn->sc_flags & VNF_READONLY)) - return (EACCES); + if ((flags & FWRITE) && (vn->sc_flags & VNF_READONLY)) { + return EACCES; + } - return(0); + return 0; } static int -file_io(struct vnode * vp, struct vfs_context * context_p, - enum uio_rw op, char * base, off_t offset, user_ssize_t count, - user_ssize_t * resid) +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) { - uio_t auio; - int error; - char uio_buf[UIO_SIZEOF(1)]; - - auio = uio_createwithbuffer(1, offset, UIO_SYSSPACE, op, - &uio_buf[0], sizeof(uio_buf)); + uio_t auio; + int error; + char uio_buf[UIO_SIZEOF(1)]; + + auio = uio_createwithbuffer(1, offset, UIO_SYSSPACE, op, + &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); - else - error = VNOP_WRITE(vp, auio, IO_SYNC, context_p); + if (op == UIO_READ) { + error = VNOP_READ(vp, auio, IO_SYNC, ctx); + } else { + error = VNOP_WRITE(vp, auio, IO_SYNC, ctx); + } if (resid != NULL) { *resid = uio_resid(auio); } - return (error); + return error; } static __inline__ off_t block_round(off_t o, int blocksize) { - return ((o + blocksize - 1) / blocksize); + return (o + blocksize - 1) / blocksize; } static __inline__ off_t block_truncate(off_t o, int blocksize) { - return (o / blocksize); + return o / blocksize; } static __inline__ int block_remainder(off_t o, int blocksize) { - return (o % blocksize); + return o % blocksize; } static int -vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, - struct vfs_context * context_p) +vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, + vfs_context_t ctx) { - u_long blocksize = vn->sc_secsize; - int error = 0; - off_t offset; - user_ssize_t resid; - off_t orig_offset; - user_ssize_t orig_resid; + u_int32_t blocksize = vn->sc_secsize; + int error = 0; + off_t offset; + user_ssize_t resid; + off_t orig_offset; + user_ssize_t orig_resid; orig_resid = resid = uio_resid(uio); orig_offset = offset = uio_offset(uio); while (resid > 0) { - u_long remainder; - u_long this_block_number; - u_long this_block_count; - off_t this_offset; - user_ssize_t this_resid; - struct vnode * vp; + u_int32_t remainder; + off_t this_block_number; + size_t this_block_count; + off_t this_offset; + user_ssize_t this_resid; + struct vnode * vp; /* figure out which blocks to read */ remainder = block_remainder(offset, blocksize); if (shadow_map_read(vn->sc_shadow_map, - block_truncate(offset, blocksize), - block_round(resid + remainder, blocksize), - &this_block_number, &this_block_count)) { + block_truncate(offset, blocksize), + block_round(resid + remainder, blocksize), + &this_block_number, &this_block_count)) { vp = vn->sc_shadow_vp; - } - else { + } else { vp = vn->sc_vp; } /* read the blocks (or parts thereof) */ - this_offset = (off_t)this_block_number * blocksize + remainder; + this_offset = this_block_number * blocksize + remainder; uio_setoffset(uio, this_offset); this_resid = this_block_count * blocksize - remainder; if (this_resid > resid) { 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; } @@ -336,34 +344,34 @@ vnread_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, } uio_setresid(uio, resid); uio_setoffset(uio, offset); - return (error); + return error; } 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, + off_t file_block, off_t shadow_block) { - int error; - char * tmpbuf; + int error; + char * tmpbuf; tmpbuf = _MALLOC(vn->sc_secsize, M_TEMP, M_WAITOK); if (tmpbuf == NULL) { - return (ENOMEM); + return ENOMEM; } /* read one block from file at file_block offset */ - error = file_io(vn->sc_vp, context_p, UIO_READ, - tmpbuf, (off_t)file_block * vn->sc_secsize, - vn->sc_secsize, NULL); + error = file_io(vn->sc_vp, ctx, UIO_READ, + tmpbuf, 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, - tmpbuf, (off_t)shadow_block * vn->sc_secsize, - vn->sc_secsize, NULL); - done: + error = file_io(vn->sc_shadow_vp, ctx, UIO_WRITE, + tmpbuf, shadow_block * vn->sc_secsize, + vn->sc_secsize, NULL); +done: FREE(tmpbuf, M_TEMP); - return (error); + return error; } enum { @@ -372,25 +380,25 @@ enum { }; static int -vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, - struct vfs_context * context_p) +vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, + vfs_context_t ctx) { - u_long blocksize = vn->sc_secsize; - int error = 0; - user_ssize_t resid; - off_t offset; + u_int32_t blocksize = vn->sc_secsize; + int error = 0; + user_ssize_t resid; + off_t offset; resid = uio_resid(uio); offset = uio_offset(uio); 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; - user_ssize_t this_resid; + int flags = 0; + off_t offset_block_number; + u_int32_t remainder; + size_t resid_block_count; + size_t shadow_block_count; + off_t shadow_block_number; + user_ssize_t this_resid; /* figure out which blocks to write */ offset_block_number = block_truncate(offset, blocksize); @@ -399,53 +407,50 @@ vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, /* figure out if the first or last blocks are partial writes */ if (remainder > 0 && !shadow_map_is_written(vn->sc_shadow_map, - offset_block_number)) { + offset_block_number)) { /* the first block is a partial write */ flags |= FLAGS_FIRST_BLOCK_PARTIAL; } if (resid_block_count > 1 && !shadow_map_is_written(vn->sc_shadow_map, - offset_block_number - + resid_block_count - 1) + offset_block_number + + resid_block_count - 1) && block_remainder(offset + resid, blocksize) > 0) { /* the last block is a partial write */ flags |= FLAGS_LAST_BLOCK_PARTIAL; } if (shadow_map_write(vn->sc_shadow_map, - offset_block_number, resid_block_count, - &shadow_block_number, - &shadow_block_count)) { + offset_block_number, resid_block_count, + &shadow_block_number, + &shadow_block_count)) { /* shadow file is growing */ #if 0 /* truncate the file to its new length before write */ - 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 + 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, ctx); +#endif } /* write the blocks (or parts thereof) */ - uio_setoffset(uio, (off_t) - shadow_block_number * blocksize + remainder); - this_resid = (off_t)shadow_block_count * blocksize - remainder; + uio_setoffset(uio, shadow_block_number * blocksize + remainder); + this_resid = shadow_block_count * blocksize - remainder; if (this_resid >= resid) { this_resid = resid; if ((flags & FLAGS_LAST_BLOCK_PARTIAL) != 0) { /* copy the last block to the shadow */ - u_long d; - u_long 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); + off_t d; + off_t s; + + s = offset_block_number + + resid_block_count - 1; + d = shadow_block_number + + shadow_block_count - 1; + error = vncopy_block_to_shadow(vn, ctx, s, d); if (error) { printf("vnwrite_shadow: failed to copy" - " block %d to shadow block %d\n", - s, d); + " block %lld to shadow block %lld\n", + s, d); break; } } @@ -453,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, - offset_block_number, - shadow_block_number); + 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", - offset_block_number, - shadow_block_number); + " copy block %lld to shadow block %lld\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; } @@ -479,37 +484,39 @@ vnwrite_shadow(struct vn_softc * vn, struct uio *uio, int ioflag, } uio_setresid(uio, resid); uio_setoffset(uio, offset); - return (error); + return error; } -static int +static int vnread(dev_t dev, struct uio *uio, int ioflag) { - struct vfs_context context; - int error = 0; - boolean_t funnel_state; - off_t offset; - struct proc * p; - user_ssize_t resid; - struct vn_softc * vn; - int unit; + struct vfs_context context; + int error = 0; + off_t offset; + proc_t p; + user_ssize_t resid; + struct vn_softc * vn; + int unit; unit = vnunit(dev); if (vnunit(dev) >= NVNDEVICE) { - return (ENXIO); + return ENXIO; } p = current_proc(); - funnel_state = thread_funnel_set(kernel_flock, TRUE); vn = vn_table + unit; if ((vn->sc_flags & VNF_INITED) == 0) { 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; } @@ -534,16 +541,14 @@ 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); + vn->sc_shadow_vid); if (error != 0) { /* 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); @@ -552,29 +557,26 @@ vnread(dev_t dev, struct uio *uio, int ioflag) error = VNOP_READ(vn->sc_vp, uio, ioflag, &context); } vnode_put(vn->sc_vp); - done: - (void) thread_funnel_set(kernel_flock, funnel_state); - return (error); +done: + return error; } -static int +static int vnwrite(dev_t dev, struct uio *uio, int ioflag) { - struct vfs_context context; - int error; - boolean_t funnel_state; - off_t offset; - struct proc * p; - user_ssize_t resid; - struct vn_softc * vn; - int unit; + struct vfs_context context; + int error; + off_t offset; + proc_t p; + user_ssize_t resid; + struct vn_softc * vn; + int unit; unit = vnunit(dev); if (vnunit(dev) >= NVNDEVICE) { - return (ENXIO); + return ENXIO; } p = current_proc(); - funnel_state = thread_funnel_set(kernel_flock, TRUE); vn = vn_table + unit; if ((vn->sc_flags & VNF_INITED) == 0) { error = ENXIO; @@ -584,11 +586,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); @@ -612,17 +618,14 @@ 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); + vn->sc_shadow_vid); if (error != 0) { /* 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); @@ -631,45 +634,41 @@ vnwrite(dev_t dev, struct uio *uio, int ioflag) error = VNOP_WRITE(vn->sc_vp, uio, ioflag, &context); } vnode_put(vn->sc_vp); - done: - (void) thread_funnel_set(kernel_flock, funnel_state); - return (error); +done: + return error; } 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; - int error = 0; - u_long offset; - boolean_t read_shadow; - u_long resid; - u_long start = 0; - - context.vc_proc = p; - context.vc_ucred = vn->sc_cred; + u_int32_t blocksize = vn->sc_secsize; + int error = 0; + off_t offset; + boolean_t read_shadow; + size_t resid; + u_int32_t start = 0; + 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; - struct vnode * vp; + user_ssize_t temp_resid; + off_t this_offset; + size_t this_resid; + struct vnode * vp; read_shadow = shadow_map_read(vn->sc_shadow_map, - offset, resid, - &this_offset, &this_resid); + offset, resid, + &this_offset, &this_resid); if (read_shadow) { vp = vn->sc_shadow_vp; - } - else { + } else { vp = vn->sc_vp; } - error = file_io(vp, &context, UIO_READ, base + start, - (off_t)this_offset * blocksize, - (user_ssize_t)this_resid * blocksize, - &temp_resid); + error = file_io(vp, ctx, UIO_READ, base + start, + this_offset * blocksize, + (user_ssize_t)this_resid * blocksize, + &temp_resid); if (error) { break; } @@ -682,49 +681,45 @@ shadow_read(struct vn_softc * vn, struct buf * bp, char * base, struct proc * p) offset += this_resid; start += this_resid * blocksize; } - buf_setresid(bp, resid * blocksize); - return (error); + buf_setresid(bp, (uint32_t)(resid * blocksize)); + return error; } static int -shadow_write(struct vn_softc * vn, struct buf * bp, char * base, - struct proc * p) +shadow_write(struct vn_softc * vn, struct buf * bp, char * base, + vfs_context_t ctx) { - u_long blocksize = vn->sc_secsize; - struct vfs_context context; - int error = 0; - u_long offset; - boolean_t shadow_grew; - u_long resid; - u_long start = 0; - - context.vc_proc = p; - context.vc_ucred = vn->sc_cred; + u_int32_t blocksize = vn->sc_secsize; + int error = 0; + off_t offset; + boolean_t shadow_grew; + size_t resid; + u_int32_t start = 0; + 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; + user_ssize_t temp_resid; + off_t this_offset; + size_t this_resid; - shadow_grew = shadow_map_write(vn->sc_shadow_map, - offset, resid, - &this_offset, &this_resid); + shadow_grew = shadow_map_write(vn->sc_shadow_map, + offset, resid, + &this_offset, &this_resid); if (shadow_grew) { #if 0 - off_t size; + off_t size; /* 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); + size = (off_t)shadow_map_shadow_size(vn->sc_shadow_map) + * blocksize; + vnode_setsize(vn->sc_shadow_vp, size, IO_SYNC, ctx); #endif } - error = file_io(vn->sc_shadow_vp, &context, UIO_WRITE, - base + start, - (off_t)this_offset * blocksize, - (user_ssize_t)this_resid * blocksize, - &temp_resid); + error = file_io(vn->sc_shadow_vp, ctx, UIO_WRITE, + base + start, + this_offset * blocksize, + (user_ssize_t)this_resid * blocksize, + &temp_resid); if (error) { break; } @@ -737,45 +732,41 @@ shadow_write(struct vn_softc * vn, struct buf * bp, char * base, offset += this_resid; start += this_resid * blocksize; } - buf_setresid(bp, resid * blocksize); - return (error); + buf_setresid(bp, (uint32_t)(resid * blocksize)); + return error; } 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; - + int error = 0; + char * iov_base; + caddr_t vaddr; - if (buf_map(bp, &vaddr)) - panic("vn device: buf_map failed"); + 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, - buf_flags(bp) & B_READ ? UIO_READ : UIO_WRITE, - iov_base, - (off_t)buf_blkno(bp) * vn->sc_secsize, - buf_resid(bp), &temp_resid); - buf_setresid(bp, temp_resid); - } - else { - if (buf_flags(bp) & B_READ) - error = shadow_read(vn, bp, iov_base, p); - else - error = shadow_write(vn, bp, iov_base, p); + user_ssize_t temp_resid; + + 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, + buf_resid(bp), &temp_resid); + buf_setresid(bp, (uint32_t)temp_resid); + } else { + if (buf_flags(bp) & B_READ) { + error = shadow_read(vn, bp, iov_base, ctx); + } else { + error = shadow_write(vn, bp, iov_base, ctx); + } } buf_unmap(bp); - return (error); + return error; } static void @@ -783,20 +774,21 @@ vnstrategy(struct buf *bp) { struct vn_softc *vn; int error = 0; - long sz; /* in sc_secsize chunks */ + 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 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)); if ((vn->sc_flags & VNF_INITED) == 0) { error = ENXIO; 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 @@ -823,7 +815,7 @@ vnstrategy(struct buf *bp) * If the request crosses EOF, truncate the request. */ if ((blk_num + sz) > 0 && ((u_int64_t)(blk_num + sz)) > vn->sc_size) { - buf_setcount(bp, (vn->sc_size - blk_num) * vn->sc_secsize); + buf_setcount(bp, (uint32_t)((vn->sc_size - blk_num) * vn->sc_secsize)); buf_setresid(bp, buf_count(bp)); } vp = vn->sc_vp; @@ -831,74 +823,82 @@ 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; if (shadow_vp != NULL) { error = vnode_getwithvid(shadow_vp, - vn->sc_shadow_vid); + vn->sc_shadow_vid); if (error != 0) { /* 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); } - done: - (void) thread_funnel_set(kernel_flock, funnel_state); +done: if (error) { - buf_seterror(bp, error); + buf_seterror(bp, error); } buf_biodone(bp); return; } /* ARGSUSED */ -static int +static int vnioctl(dev_t dev, u_long cmd, caddr_t data, - __unused int flag, struct proc *p, - int is_char) + __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; - boolean_t funnel_state; + struct vn_ioctl_64 user_vnio; + struct vfs_context context; unit = vnunit(dev); if (vnunit(dev) >= NVNDEVICE) { - return (ENXIO); + return ENXIO; } - funnel_state = thread_funnel_set(kernel_flock, TRUE); vn = vn_table + unit; error = proc_suser(p); if (error) { 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: @@ -908,7 +908,6 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, case DKIOCGETMAXSEGMENTBYTECOUNTREAD: case DKIOCGETMAXSEGMENTBYTECOUNTWRITE: case DKIOCGETBLOCKCOUNT: - case DKIOCGETBLOCKCOUNT32: if ((vn->sc_flags & VNF_INITED) == 0) { error = ENXIO; goto done; @@ -918,10 +917,11 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, break; } - if (vn->sc_vp != NULL) + if (vn->sc_vp != NULL) { vfs_ioattr(vnode_mount(vn->sc_vp), &ioattr); - else + } else { bzero(&ioattr, sizeof(ioattr)); + } switch (cmd) { case DKIOCISVIRTUAL: @@ -952,7 +952,7 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, *o = ioattr.io_maxsegwritesize; break; case DKIOCGETBLOCKSIZE: - *f = vn->sc_secsize; + *f = vn->sc_secsize; break; case DKIOCSETBLOCKSIZE: if (is_char) { @@ -979,14 +979,16 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, case DKIOCISWRITABLE: *f = 1; break; - case DKIOCGETBLOCKCOUNT32: - *f = vn->sc_size; - break; 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; @@ -998,7 +1000,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) { @@ -1008,8 +1010,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; @@ -1021,7 +1028,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) { @@ -1031,8 +1038,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; @@ -1048,7 +1060,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: @@ -1075,21 +1087,20 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, error = ENOTTY; break; } - done: - (void) thread_funnel_set(kernel_flock, funnel_state); - return(error); +done: + return error; } -static int -vnioctl_chr(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +static int +vnioctl_chr(dev_t dev, u_long cmd, caddr_t data, int flag, proc_t p) { - return (vnioctl(dev, cmd, data, flag, p, TRUE)); + 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) +static int +vnioctl_blk(dev_t dev, u_long cmd, caddr_t data, int flag, proc_t p) { - return (vnioctl(dev, cmd, data, flag, p, FALSE)); + return vnioctl(dev, cmd, data, flag, p, FALSE); } /* @@ -1101,68 +1112,64 @@ 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, - dev_t dev, - int in_kernel, - struct proc *p) + struct vn_ioctl_64 *vniop, + dev_t dev, + int in_kernel, + proc_t p) { - dev_t cdev; - struct vfs_context context; + dev_t cdev; + 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; + flags = FREAD | FWRITE; if (in_kernel) { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE32, vniop->vn_file, &context); - } - else { - NDINIT(&nd, LOOKUP, FOLLOW, - (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), - vniop->vn_file, &context); + NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, UIO_SYSSPACE, vniop->vn_file, ctx); + } else { + NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, + (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), + 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) - return (error); + if (error != EACCES && error != EPERM && error != EROFS) { + return error; + } flags &= ~FWRITE; if (in_kernel) { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE32, - vniop->vn_file, &context); - } - else { - NDINIT(&nd, LOOKUP, FOLLOW, - (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), - vniop->vn_file, &context); + NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, UIO_SYSSPACE, + vniop->vn_file, ctx); + } else { + NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, + (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), + vniop->vn_file, ctx); } error = vn_open(&nd, flags, 0); - if (error) - return (error); + if (error) { + return error; + } } if (nd.ni_vp->v_type != VREG) { error = EINVAL; - } - else { - error = vnode_size(nd.ni_vp, &file_size, &context); + } else { + 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); + 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); - return(error); + kauth_cred_unref(&cred); + return error; } vn->sc_secsize = DEV_BSIZE; vn->sc_fsize = file_size; @@ -1173,58 +1180,55 @@ vniocattach_file(struct vn_softc *vn, vn->sc_cred = cred; cdev = makedev(vndevice_cdev_major, minor(dev)); vn->sc_cdev = devfs_make_node(cdev, DEVFS_CHAR, - UID_ROOT, GID_OPERATOR, - 0600, "rvn%d", - minor(dev)); + UID_ROOT, GID_OPERATOR, + 0600, "rvn%d", + minor(dev)); vn->sc_flags |= VNF_INITED; - if (flags == FREAD) + if (flags == FREAD) { vn->sc_flags |= VNF_READONLY; + } /* lose the short-term reference */ vnode_put(nd.ni_vp); - return(0); + return 0; } 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; + shadow_map_t * map; off_t file_size; - context.vc_proc = p; - context.vc_ucred = proc_ucred(p); - - flags = FREAD|FWRITE; + flags = FREAD | FWRITE; if (in_kernel) { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE32, vniop->vn_file, &context); - } - else { - NDINIT(&nd, LOOKUP, FOLLOW, - (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), - vniop->vn_file, &context); + NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, UIO_SYSSPACE, vniop->vn_file, ctx); + } else { + NDINIT(&nd, LOOKUP, OP_OPEN, FOLLOW, + (IS_64BIT_PROCESS(p) ? UIO_USERSPACE64 : UIO_USERSPACE32), + vniop->vn_file, ctx); } /* vn_open gives both long- and short-term references */ error = vn_open(&nd, flags, 0); if (error) { /* shadow MUST be writable! */ - return (error); + 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); + if (nd.ni_vp->v_type != VREG + || (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); + return error ? error : EINVAL; } map = shadow_map_create(vn->sc_fsize, file_size, - 0, vn->sc_secsize); + 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); + return ENOMEM; } vn->sc_shadow_vp = nd.ni_vp; vn->sc_shadow_vid = vnode_vid(nd.ni_vp); @@ -1234,25 +1238,25 @@ vniocattach_shadow(struct vn_softc *vn, struct user_vn_ioctl *vniop, /* lose the short-term reference */ vnode_put(nd.ni_vp); - return(0); + return 0; } int vndevice_root_image(char * path, char devname[], dev_t * dev_p) { - int error = 0; - struct vn_softc * vn; - struct user_vn_ioctl vnio; + int error = 0; + struct vn_softc * vn; + struct vn_ioctl_64 vnio; vnio.vn_file = CAST_USER_ADDR_T(path); vnio.vn_size = 0; vn = vn_table + ROOT_IMAGE_UNIT; - *dev_p = makedev(vndevice_bdev_major, - ROOT_IMAGE_UNIT); - sprintf(devname, "vn%d", ROOT_IMAGE_UNIT); + *dev_p = makedev(vndevice_bdev_major, + ROOT_IMAGE_UNIT); + snprintf(devname, 16, "vn%d", ROOT_IMAGE_UNIT); error = vniocattach_file(vn, &vnio, *dev_p, 1, current_proc()); - return (error); + return error; } /* @@ -1262,35 +1266,34 @@ 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; - struct vfs_context context; + struct vfs_context context; /* * 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); FREE(tmpbuf, M_TEMP); - return (error); + return error; } 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) { @@ -1299,8 +1302,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; @@ -1310,67 +1312,75 @@ vnclear(struct vn_softc *vn, struct proc * p) } } -static int +static int vnsize(dev_t dev) { - int secsize; + int secsize; struct vn_softc *vn; int unit; - boolean_t funnel_state; unit = vnunit(dev); if (vnunit(dev) >= NVNDEVICE) { - return (-1); + return -1; } - funnel_state = thread_funnel_set(kernel_flock, TRUE); vn = vn_table + unit; - if ((vn->sc_flags & VNF_INITED) == 0) + if ((vn->sc_flags & VNF_INITED) == 0) { secsize = -1; - else + } else { secsize = vn->sc_secsize; - (void) thread_funnel_set(kernel_flock, funnel_state); - return (secsize); + } + + return secsize; } -#define CDEV_MAJOR -1 -#define BDEV_MAJOR -1 +#define CDEV_MAJOR -1 +#define BDEV_MAJOR -1 static int vndevice_inited = 0; -void +void vndevice_init(void) { - int i; - - if (vndevice_inited) + 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) { printf("vndevice_init: bdevsw_add() returned %d\n", - vndevice_bdev_major); + vndevice_bdev_major); return; } vndevice_cdev_major = cdevsw_add_with_bdev(CDEV_MAJOR, &vn_cdevsw, - vndevice_bdev_major); + vndevice_bdev_major); if (vndevice_cdev_major < 0) { printf("vndevice_init: cdevsw_add() returned %d\n", - vndevice_cdev_major); + vndevice_cdev_major); return; } for (i = 0; i < NVNDEVICE; i++) { - dev_t dev = makedev(vndevice_bdev_major, i); + dev_t dev = makedev(vndevice_bdev_major, i); vn_table[i].sc_bdev = devfs_make_node(dev, DEVFS_BLOCK, - UID_ROOT, GID_OPERATOR, - 0600, "vn%d", - i); - if (vn_table[i].sc_bdev == NULL) + UID_ROOT, GID_OPERATOR, + 0600, "vn%d", + i); + if (vn_table[i].sc_bdev == NULL) { printf("vninit: devfs_make_node failed!\n"); + } } } -static void -vn_ioctl_to_64(struct vn_ioctl *from, struct user_vn_ioctl *to) +static void +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;