kern_open_file_for_direct_io(const char * name,
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,
- off_t offset,
- caddr_t addr,
- vm_size_t len)
+ uint32_t * oflags)
{
struct kern_direct_file_io_ref_t * ref;
int isssd = 0;
uint32_t flags = 0;
uint32_t blksize;
- off_t maxiocount, count;
+ off_t maxiocount, count, segcount;
boolean_t locked = FALSE;
int (*do_ioctl)(void * p1, void * p2, u_long theIoctl, caddr_t result);
if ((error = vnode_open(name, (O_CREAT | FWRITE), (0), 0, &ref->vp, ref->ctx)))
goto out;
- if (addr && len)
+ if (write_file_addr && write_file_len)
{
- if ((error = kern_write_file(ref, offset, addr, len)))
+ if ((error = kern_write_file(ref, write_file_offset, write_file_addr, write_file_len)))
goto out;
}
goto out;
device = va.va_fsid;
+ ref->filelength = va.va_data_size;
+
p1 = &device;
p2 = p;
do_ioctl = &file_ioctl;
+
+ if (set_file_size)
+ {
+ off_t bytesallocated = 0;
+ u_int32_t alloc_flags = PREALLOCATE | ALLOCATEFROMPEOF | ALLOCATEALL;
+ error = VNOP_ALLOCATE(ref->vp, set_file_size, alloc_flags,
+ &bytesallocated, 0 /*fst_offset*/,
+ ref->ctx);
+ // F_SETSIZE:
+ if (!error) error = vnode_setsize(ref->vp, set_file_size, IO_NOZEROFILL, ref->ctx);
+ kprintf("vnode_setsize(%d) %qd\n", error, set_file_size);
+ ref->filelength = bytesallocated;
+ }
}
else if ((ref->vp->v_type == VBLK) || (ref->vp->v_type == VCHR))
{
if (error)
goto out;
- if (ref->vp->v_type == VREG)
- ref->filelength = va.va_data_size;
- else
+ if (ref->vp->v_type != VREG)
{
error = do_ioctl(p1, p2, DKIOCGETBLOCKCOUNT, (caddr_t) &fileblk);
if (error)
maxiocount = count;
error = do_ioctl(p1, p2, DKIOCGETMAXSEGMENTBYTECOUNTREAD, (caddr_t) &count);
+ if (!error)
+ error = do_ioctl(p1, p2, DKIOCGETMAXSEGMENTCOUNTREAD, (caddr_t) &segcount);
if (error)
- count = 0;
+ count = segcount = 0;
+ count *= segcount;
if (count && (count < maxiocount))
maxiocount = count;
error = do_ioctl(p1, p2, DKIOCGETMAXSEGMENTBYTECOUNTWRITE, (caddr_t) &count);
+ if (!error)
+ error = do_ioctl(p1, p2, DKIOCGETMAXSEGMENTCOUNTWRITE, (caddr_t) &segcount);
if (error)
- count = 0;
+ count = segcount = 0;
+ count *= segcount;
if (count && (count < maxiocount))
maxiocount = count;
kfree(ref, sizeof(struct kern_direct_file_io_ref_t));
ref = NULL;
}
+
return(ref);
}