+struct kern_direct_file_io_ref_t *
+kern_open_file_for_direct_io(const char * name,
+ boolean_t create_file,
+ kern_get_file_extents_callback_t callback,
+ void * callback_ref,
+ off_t set_file_size,
+ off_t write_file_offset,
+ caddr_t write_file_addr,
+ vm_size_t write_file_len,
+ dev_t * partition_device_result,
+ dev_t * image_device_result,
+ uint64_t * partitionbase_result,
+ uint64_t * maxiocount_result,
+ uint32_t * oflags)
+{
+ struct kern_direct_file_io_ref_t * ref;
+
+ proc_t p;
+ struct vnode_attr va;
+ int error;
+ off_t f_offset;
+ uint64_t fileblk;
+ size_t filechunk;
+ uint64_t physoffset;
+ dev_t device;
+ dev_t target = 0;
+ int isssd = 0;
+ uint32_t flags = 0;
+ uint32_t blksize;
+ off_t maxiocount, count, segcount;
+ boolean_t locked = FALSE;
+
+ int (*do_ioctl)(void * p1, void * p2, u_long theIoctl, caddr_t result);
+ void * p1 = NULL;
+ void * p2 = NULL;
+
+ error = EFAULT;
+
+ ref = (struct kern_direct_file_io_ref_t *) kalloc(sizeof(struct kern_direct_file_io_ref_t));
+ if (!ref)
+ {
+ error = EFAULT;
+ goto out;
+ }
+
+ bzero(ref, sizeof(*ref));
+ p = kernproc;
+ ref->ctx = vfs_context_create(vfs_context_current());
+
+ if ((error = vnode_open(name, (create_file) ? (O_CREAT | FWRITE) : FWRITE,
+ (0), 0, &ref->vp, ref->ctx)))
+ goto out;
+
+ if (ref->vp->v_type == VREG)
+ {
+ vnode_lock_spin(ref->vp);
+ SET(ref->vp->v_flag, VSWAP);
+ vnode_unlock(ref->vp);
+ }
+
+ if (write_file_addr && write_file_len)
+ {
+ if ((error = kern_write_file(ref, write_file_offset, write_file_addr, write_file_len, 0)))
+ goto out;
+ }
+
+ VATTR_INIT(&va);
+ VATTR_WANTED(&va, va_rdev);
+ VATTR_WANTED(&va, va_fsid);
+ VATTR_WANTED(&va, va_data_size);
+ VATTR_WANTED(&va, va_data_alloc);
+ VATTR_WANTED(&va, va_nlink);
+ error = EFAULT;
+ if (vnode_getattr(ref->vp, &va, ref->ctx))
+ goto out;
+
+ kprintf("vp va_rdev major %d minor %d\n", major(va.va_rdev), minor(va.va_rdev));
+ kprintf("vp va_fsid major %d minor %d\n", major(va.va_fsid), minor(va.va_fsid));
+ kprintf("vp size %qd alloc %qd\n", va.va_data_size, va.va_data_alloc);
+
+ if (ref->vp->v_type == VREG)
+ {
+ /* Don't dump files with links. */
+ if (va.va_nlink != 1)
+ goto out;
+
+ device = va.va_fsid;
+ ref->filelength = va.va_data_size;
+
+ p1 = &device;
+ p2 = p;
+ do_ioctl = &file_ioctl;
+
+ if (set_file_size)
+ {
+ error = vnode_setsize(ref->vp, set_file_size,
+ IO_NOZEROFILL | IO_NOAUTH, ref->ctx);
+ if (error)
+ goto out;
+ ref->filelength = set_file_size;
+ }
+ }
+ else if ((ref->vp->v_type == VBLK) || (ref->vp->v_type == VCHR))
+ {
+ /* Partition. */
+ device = va.va_rdev;
+
+ p1 = ref->vp;
+ p2 = ref->ctx;
+ do_ioctl = &device_ioctl;