]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_symfile.c
xnu-2050.48.11.tar.gz
[apple/xnu.git] / bsd / kern / kern_symfile.c
index d0d4674948cea99910aef1f1d3cd6413e26b59f4..2e1965dfd0685a2da4a5d60b55394a27f8f0ef10 100644 (file)
@@ -179,14 +179,15 @@ struct kern_direct_file_io_ref_t *
 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;
 
@@ -202,7 +203,7 @@ kern_open_file_for_direct_io(const char * name,
     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);
@@ -225,9 +226,9 @@ kern_open_file_for_direct_io(const char * name,
     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;
     }
 
@@ -251,9 +252,24 @@ kern_open_file_for_direct_io(const char * name,
            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))
     {
@@ -278,9 +294,7 @@ kern_open_file_for_direct_io(const char * name,
     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)
@@ -392,14 +406,20 @@ kern_open_file_for_direct_io(const char * name,
         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;
 
@@ -438,6 +458,7 @@ out:
        kfree(ref, sizeof(struct kern_direct_file_io_ref_t));
        ref = NULL;
     }
+
     return(ref);
 }