+ if (_DKIOCCSPINEXTENT == theIoctl) {
+ /* Tell CS the image size, so it knows whether to place the subsequent pins SSD/HDD */
+ pin.cp_extent.length = end;
+ pin.cp_flags = _DKIOCCSHIBERNATEIMGSIZE;
+ (void) do_ioctl(p1, p2, _DKIOCCSPINEXTENT, (caddr_t)&pin);
+ } else if (_DKIOCCSUNPINEXTENT == theIoctl) {
+ /* Tell CS hibernation is done, so it can stop blocking overlapping writes */
+ pin.cp_flags = _DKIOCCSPINDISCARDBLACKLIST;
+ (void) do_ioctl(p1, p2, _DKIOCCSUNPINEXTENT, (caddr_t)&pin);
+ }
+
+ while (offset < end)
+ {
+ 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, NULL);
+ if (error) break;
+ 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;
+ offset += filechunk;
+ }
+ return (error);