+ for (; offset < end; offset += filechunk)
+ {
+ if (ref->vp->v_type == VREG)
+ {
+ daddr64_t blkno;
+ filechunk = 1*1024*1024*1024;
+ if (filechunk > (size_t)(end - offset))
+ filechunk = (size_t)(end - offset);
+ error = VNOP_BLOCKMAP(ref->vp, offset, filechunk, &blkno,
+ &filechunk, NULL, VNODE_WRITE | VNODE_BLOCKMAP_NO_TRACK, NULL);
+ if (error) break;
+ if (-1LL == blkno) continue;
+ fileblk = blkno * ref->blksize;
+ }
+ else if ((ref->vp->v_type == VBLK) || (ref->vp->v_type == VCHR))
+ {
+ fileblk = offset;
+ filechunk = ref->filelength;
+ }
+
+ if (DKIOCUNMAP == theIoctl)
+ {
+ extent.offset = fileblk;
+ extent.length = filechunk;
+ unmap.extents = &extent;
+ unmap.extentsCount = 1;
+ error = do_ioctl(p1, p2, theIoctl, (caddr_t)&unmap);
+// printf("DKIOCUNMAP(%d) 0x%qx, 0x%qx\n", error, extent.offset, extent.length);
+ }
+ else if (_DKIOCCSPINEXTENT == theIoctl)
+ {
+ pin.cp_extent.offset = fileblk;
+ pin.cp_extent.length = filechunk;
+ pin.cp_flags = _DKIOCCSPINFORHIBERNATION;
+ error = do_ioctl(p1, p2, theIoctl, (caddr_t)&pin);
+ if (error && (ENOTTY != error))
+ {
+ printf("_DKIOCCSPINEXTENT(%d) 0x%qx, 0x%qx\n", error, pin.cp_extent.offset, pin.cp_extent.length);
+ }
+ }
+ else if (_DKIOCCSUNPINEXTENT == theIoctl)
+ {
+ pin.cp_extent.offset = fileblk;
+ pin.cp_extent.length = filechunk;
+ pin.cp_flags = _DKIOCCSPINFORHIBERNATION;
+ error = do_ioctl(p1, p2, theIoctl, (caddr_t)&pin);
+ if (error && (ENOTTY != error))
+ {
+ printf("_DKIOCCSUNPINEXTENT(%d) 0x%qx, 0x%qx\n", error, pin.cp_extent.offset, pin.cp_extent.length);
+ }
+ }
+ else error = EINVAL;
+
+ if (error) break;
+ }
+ return (error);
+}
+
+extern uint32_t freespace_mb(vnode_t vp);
+
+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 fs_free_size,
+ off_t write_file_offset,
+ void * write_file_addr,
+ 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 fmode, cmode;
+ struct nameidata nd;
+ u_int32_t ndflags;
+ off_t mpFree;
+
+ int (*do_ioctl)(void * p1, void * p2, u_long theIoctl, caddr_t result);
+ void * p1 = NULL;
+ void * p2 = NULL;