]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/vm/vm_compressor_backing_file.c
xnu-3789.70.16.tar.gz
[apple/xnu.git] / bsd / vm / vm_compressor_backing_file.c
index 9a663e9e848e7e5f821f778cff6dec569a1afba1..9a83330fb5be6328095e4153f298a0b2f27b9b67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
 
 void vm_swapfile_open(const char *path, vnode_t *vp);
 void vm_swapfile_close(uint64_t path, vnode_t vp);
-int vm_swapfile_preallocate(vnode_t vp, uint64_t *size);
+int vm_swapfile_preallocate(vnode_t vp, uint64_t *size, boolean_t *pin);
 uint64_t vm_swapfile_get_blksize(vnode_t vp);
 uint64_t vm_swapfile_get_transfer_size(vnode_t vp);
 int vm_swapfile_io(vnode_t vp, uint64_t offset, uint64_t start, int npages, int flags);
+int vm_record_file_write(struct vnode *vp, uint64_t offset, char *buf, int size);
+
 
 void
 vm_swapfile_open(const char *path, vnode_t *vp)
 {
        int error = 0;
-       vfs_context_t   ctx = vfs_context_current();
+       vfs_context_t   ctx = vfs_context_kernel();
 
        if ((error = vnode_open(path, (O_CREAT | O_TRUNC | FREAD | FWRITE), S_IRUSR | S_IWUSR, 0, vp, ctx))) {
                printf("Failed to open swap file %d\n", error);
@@ -59,6 +61,18 @@ vm_swapfile_open(const char *path, vnode_t *vp)
                return;
        }       
 
+       /*
+        * If MNT_IOFLAGS_NOSWAP is set, opening the swap file should fail.
+        * To avoid a race on the mount we only make this check after creating the
+        * vnode.
+        */
+       if ((*vp)->v_mount->mnt_kern_flag & MNTK_NOSWAP) {
+               vnode_put(*vp);
+               vm_swapfile_close((uint64_t)path, *vp);
+               *vp = NULL;
+               return;
+       }
+
        vnode_put(*vp);
 }
 
@@ -79,7 +93,7 @@ int unlink1(vfs_context_t, vnode_t, user_addr_t, enum uio_seg, int);
 void
 vm_swapfile_close(uint64_t path_addr, vnode_t vp)
 {
-       vfs_context_t context = vfs_context_current();
+       vfs_context_t context = vfs_context_kernel();
        int error;
 
        vnode_getwithref(vp);
@@ -96,36 +110,14 @@ vm_swapfile_close(uint64_t path_addr, vnode_t vp)
 }
 
 int
-vm_swapfile_preallocate(vnode_t vp, uint64_t *size)
+vm_swapfile_preallocate(vnode_t vp, uint64_t *size, boolean_t *pin)
 {
        int             error = 0;
        uint64_t        file_size = 0;
        vfs_context_t   ctx = NULL;
 
 
-       ctx = vfs_context_current();
-
-#if CONFIG_PROTECT
-       {
-#if 0  // <rdar://11771612>
-
-               if ((error = cp_vnode_setclass(vp, PROTECTION_CLASS_F))) {
-                       if(config_protect_bug) {
-                               printf("swap protection class set failed with %d\n", error);
-                       } else {
-                               panic("swap protection class set failed with %d\n", error);
-                       }
-               }
-#endif
-               /* initialize content protection keys manually */
-               if ((error = cp_handle_vnop(vp, CP_WRITE_ACCESS, 0)) != 0) {
-                       printf("Content Protection key failure on swap: %d\n", error);
-                       vnode_put(vp);
-                       vp = NULL;
-                       goto done;
-               }
-       }
-#endif
+       ctx = vfs_context_kernel();
 
        error = vnode_setsize(vp, *size, IO_NOZEROFILL, ctx);
 
@@ -138,10 +130,21 @@ vm_swapfile_preallocate(vnode_t vp, uint64_t *size)
 
        if (error) {
                printf("vnode_size (new file) for swap file failed: %d\n", error);
+               goto done;
        }       
-
        assert(file_size == *size);
        
+       if (pin != NULL && *pin != FALSE) {
+               error = VNOP_IOCTL(vp, FIOPINSWAP, NULL, 0, ctx);
+
+               if (error) {
+                       printf("pin for swap files failed: %d,  file_size = %lld\n", error, file_size);
+                       /* this is not fatal, carry on with files wherever they landed */
+                       *pin = FALSE;
+                       error = 0;
+               }
+       }
+
        vnode_lock_spin(vp);
        SET(vp->v_flag, VSWAP);
        vnode_unlock(vp);
@@ -149,6 +152,23 @@ done:
        return error;
 }
 
+
+int
+vm_record_file_write(vnode_t vp, uint64_t offset, char *buf, int size)
+{
+       int error = 0;
+       vfs_context_t ctx;
+
+       ctx = vfs_context_kernel();
+               
+       error = vn_rdwr(UIO_WRITE, vp, (caddr_t)buf, size, offset,
+               UIO_SYSSPACE, IO_NODELOCKED, vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));
+
+       return (error);
+}
+
+
+
 int
 vm_swapfile_io(vnode_t vp, uint64_t offset, uint64_t start, int npages, int flags)
 {
@@ -158,10 +178,12 @@ vm_swapfile_io(vnode_t vp, uint64_t offset, uint64_t start, int npages, int flag
        kern_return_t   kr = KERN_SUCCESS;
        upl_t           upl = NULL;
        unsigned int    count = 0;
-       int             upl_create_flags = 0, upl_control_flags = 0;
+       upl_control_flags_t upl_create_flags = 0;
+       int             upl_control_flags = 0;
        upl_size_t      upl_size = 0;
 
-       upl_create_flags = UPL_SET_INTERNAL | UPL_SET_LITE;
+       upl_create_flags = UPL_SET_INTERNAL | UPL_SET_LITE
+                       | UPL_MEMORY_TAG_MAKE(VM_KERN_MEMORY_OSFMK);
 
 #if ENCRYPTED_SWAP
        upl_control_flags = UPL_IOSYNC | UPL_PAGING_ENCRYPTED;