]> git.saurik.com Git - apple/xnu.git/blame - bsd/vm/dp_backing_file.c
xnu-2782.1.97.tar.gz
[apple/xnu.git] / bsd / vm / dp_backing_file.c
CommitLineData
1c79356b 1/*
6d2010ae 2 * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
5d5c5d0d 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
30 * support for mandatory and extensible security protections. This notice
31 * is included in support of clause 2.2 (b) of the Apple Public License,
32 * Version 2.0.
1c79356b
A
33 */
34
1c79356b
A
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/lock.h>
91447636
A
38#include <sys/proc_internal.h>
39#include <sys/kauth.h>
1c79356b
A
40#include <sys/buf.h>
41#include <sys/uio.h>
91447636 42#include <sys/vnode_internal.h>
1c79356b 43#include <sys/namei.h>
91447636
A
44#include <sys/ubc_internal.h>
45#include <sys/malloc.h>
6d2010ae
A
46#include <sys/user.h>
47#if CONFIG_PROTECT
48#include <sys/cprotect.h>
49#endif
91447636
A
50
51#include <default_pager/default_pager_types.h>
52#include <default_pager/default_pager_object.h>
1c79356b 53
b0d623f7 54#include <security/audit/audit.h>
e5568f75
A
55#include <bsm/audit_kevents.h>
56
1c79356b 57#include <mach/mach_types.h>
91447636
A
58#include <mach/host_priv.h>
59#include <mach/mach_traps.h>
60#include <mach/boolean.h>
61
62#include <kern/kern_types.h>
fe8ab488 63#include <kern/locks.h>
1c79356b 64#include <kern/host.h>
91447636 65#include <kern/task.h>
1c79356b
A
66#include <kern/zalloc.h>
67#include <kern/kalloc.h>
91447636
A
68#include <kern/assert.h>
69
1c79356b 70#include <libkern/libkern.h>
1c79356b 71
91447636
A
72#include <vm/vm_pageout.h>
73#include <vm/vm_map.h>
74#include <vm/vm_kern.h>
1c79356b 75#include <vm/vnode_pager.h>
91447636 76#include <vm/vm_protos.h>
2d21ac55
A
77#if CONFIG_MACF
78#include <security/mac_framework.h>
79#endif
1c79356b 80
fe8ab488
A
81#include <pexpert/pexpert.h>
82
83void macx_init(void);
84
85static lck_grp_t *macx_lock_group;
86static lck_mtx_t *macx_lock;
39236c6e 87
1c79356b
A
88/*
89 * temporary support for delayed instantiation
90 * of default_pager
91 */
92int default_pager_init_flag = 0;
93
94struct bs_map bs_port_table[MAX_BACKING_STORE] = {
95 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
96 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
97 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
98 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
99 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
100 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
101 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
102 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
103 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
104 {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
105
106/* ###################################################### */
107
fe8ab488
A
108/*
109 * Routine: macx_init
110 * Function:
111 * Initialize locks so that only one caller can change
112 * state at a time.
113 */
114void
115macx_init(void)
116{
117 macx_lock_group = lck_grp_alloc_init("macx", NULL);
118 macx_lock = lck_mtx_alloc_init(macx_lock_group, NULL);
119}
1c79356b 120
55e303ae
A
121/*
122 * Routine: macx_backing_store_recovery
123 * Function:
124 * Syscall interface to set a tasks privilege
125 * level so that it is not subject to
126 * macx_backing_store_suspend
127 */
128int
129macx_backing_store_recovery(
91447636 130 struct macx_backing_store_recovery_args *args)
55e303ae 131{
91447636 132 int pid = args->pid;
55e303ae
A
133 int error;
134 struct proc *p = current_proc();
55e303ae 135
91447636 136 if ((error = suser(kauth_cred_get(), 0)))
55e303ae
A
137 goto backing_store_recovery_return;
138
139 /* for now restrict backing_store_recovery */
140 /* usage to only present task */
91447636 141 if(pid != proc_selfpid()) {
55e303ae
A
142 error = EINVAL;
143 goto backing_store_recovery_return;
144 }
145
146 task_backing_store_privileged(p->task);
147
148backing_store_recovery_return:
55e303ae
A
149 return(error);
150}
151
152/*
153 * Routine: macx_backing_store_suspend
154 * Function:
155 * Syscall interface to stop new demand for
156 * backing store when backing store is low
157 */
158
159int
160macx_backing_store_suspend(
91447636 161 struct macx_backing_store_suspend_args *args)
55e303ae 162{
91447636 163 boolean_t suspend = args->suspend;
55e303ae 164 int error;
55e303ae 165
fe8ab488 166 lck_mtx_lock(macx_lock);
91447636 167 if ((error = suser(kauth_cred_get(), 0)))
55e303ae
A
168 goto backing_store_suspend_return;
169
fe8ab488 170 /* Multiple writers protected by macx_lock */
55e303ae
A
171 vm_backing_store_disable(suspend);
172
173backing_store_suspend_return:
fe8ab488 174 lck_mtx_unlock(macx_lock);
55e303ae
A
175 return(error);
176}
177
b0d623f7 178extern boolean_t backing_store_stop_compaction;
39236c6e 179extern boolean_t compressor_store_stop_compaction;
b0d623f7
A
180
181/*
182 * Routine: macx_backing_store_compaction
183 * Function:
184 * Turn compaction of swap space on or off. This is
185 * used during shutdown/restart so that the kernel
186 * doesn't waste time compacting swap files that are
187 * about to be deleted anyway. Compaction is always
188 * on by default when the system comes up and is turned
189 * off when a shutdown/restart is requested. It is
190 * re-enabled if the shutdown/restart is aborted for any reason.
fe8ab488
A
191 *
192 * This routine assumes macx_lock has been locked by macx_triggers ->
193 * mach_macx_triggers -> macx_backing_store_compaction
b0d623f7
A
194 */
195
196int
197macx_backing_store_compaction(int flags)
198{
199 int error;
200
fe8ab488 201 lck_mtx_assert(macx_lock, LCK_MTX_ASSERT_OWNED);
b0d623f7
A
202 if ((error = suser(kauth_cred_get(), 0)))
203 return error;
204
205 if (flags & SWAP_COMPACT_DISABLE) {
206 backing_store_stop_compaction = TRUE;
39236c6e
A
207 compressor_store_stop_compaction = TRUE;
208
209 kprintf("backing_store_stop_compaction = TRUE\n");
b0d623f7
A
210
211 } else if (flags & SWAP_COMPACT_ENABLE) {
212 backing_store_stop_compaction = FALSE;
39236c6e
A
213 compressor_store_stop_compaction = FALSE;
214
215 kprintf("backing_store_stop_compaction = FALSE\n");
b0d623f7
A
216 }
217
218 return 0;
219}
220
221/*
222 * Routine: macx_triggers
223 * Function:
224 * Syscall interface to set the call backs for low and
225 * high water marks.
226 */
227int
228macx_triggers(
229 struct macx_triggers_args *args)
230{
231 int error;
232
fe8ab488 233 lck_mtx_lock(macx_lock);
b0d623f7
A
234 error = suser(kauth_cred_get(), 0);
235 if (error)
236 return error;
237
fe8ab488
A
238 error = mach_macx_triggers(args);
239
240 lck_mtx_unlock(macx_lock);
241 return error;
b0d623f7
A
242}
243
0b4c1975
A
244
245extern boolean_t dp_isssd;
39236c6e
A
246
247/*
248 * In the compressed pager world, the swapfiles are created by the kernel.
249 * Well, all except the first one. That swapfile is absorbed by the kernel at
250 * the end of the macx_swapon function (if swap is enabled). That's why
251 * we allow the first invocation of macx_swapon to succeed.
252 *
253 * If the compressor pool is running low, the kernel messages the dynamic pager
254 * on the port it has registered with the kernel. That port can transport 1 of 2
255 * pieces of information to dynamic pager: create a swapfile or delete a swapfile.
256 *
257 * We choose to transmit the former. So, that message tells dynamic pager
258 * to create a swapfile and activate it by calling macx_swapon.
259 *
260 * We deny this new macx_swapon request. That leads dynamic pager to interpret the
261 * failure as a serious error and notify all it's clients that swap is running low.
262 * That's how we get the loginwindow "Resume / Force Quit Applications" dialog to appear.
263 *
264 * NOTE:
265 * If the kernel has already created multiple swapfiles by the time the compressor
266 * pool is running low (and it has to play this trick), dynamic pager won't be able to
267 * create a file in user-space and, that too will lead to a similar notification blast
268 * to all of it's clients. So, that behaves as desired too.
269 */
270boolean_t macx_swapon_allowed = TRUE;
0b4c1975 271
1c79356b
A
272/*
273 * Routine: macx_swapon
274 * Function:
275 * Syscall interface to add a file to backing store
276 */
277int
278macx_swapon(
91447636 279 struct macx_swapon_args *args)
1c79356b 280{
91447636
A
281 int size = args->size;
282 vnode_t vp = (vnode_t)NULL;
1c79356b 283 struct nameidata nd, *ndp;
1c79356b
A
284 register int error;
285 kern_return_t kr;
286 mach_port_t backing_store;
0b4e3aa0 287 memory_object_default_t default_pager;
1c79356b 288 int i;
91447636 289 off_t file_size;
2d21ac55
A
290 vfs_context_t ctx = vfs_context_current();
291 struct proc *p = current_proc();
0b4c1975
A
292 int dp_cluster_size;
293
fe8ab488
A
294 AUDIT_MACH_SYSCALL_ENTER(AUE_SWAPON);
295 AUDIT_ARG(value32, args->priority);
296
297 lck_mtx_lock(macx_lock);
298
39236c6e
A
299 if (COMPRESSED_PAGER_IS_ACTIVE) {
300 if (macx_swapon_allowed == FALSE) {
fe8ab488
A
301 error = EINVAL;
302 goto swapon_bailout;
39236c6e 303 } else {
39236c6e 304 macx_swapon_allowed = FALSE;
fe8ab488
A
305 error = 0;
306 goto swapon_bailout;
39236c6e
A
307 }
308 }
1c79356b 309
1c79356b
A
310 ndp = &nd;
311
91447636 312 if ((error = suser(kauth_cred_get(), 0)))
1c79356b
A
313 goto swapon_bailout;
314
1c79356b
A
315 /*
316 * Get a vnode for the paging area.
317 */
6d2010ae 318 NDINIT(ndp, LOOKUP, OP_LOOKUP, FOLLOW | LOCKLEAF | AUDITVNPATH1,
91447636 319 ((IS_64BIT_PROCESS(p)) ? UIO_USERSPACE64 : UIO_USERSPACE32),
b0d623f7 320 (user_addr_t) args->filename, ctx);
1c79356b
A
321
322 if ((error = namei(ndp)))
323 goto swapon_bailout;
91447636 324 nameidone(ndp);
1c79356b
A
325 vp = ndp->ni_vp;
326
327 if (vp->v_type != VREG) {
328 error = EINVAL;
1c79356b
A
329 goto swapon_bailout;
330 }
1c79356b 331
91447636 332 /* get file size */
2d21ac55
A
333 if ((error = vnode_size(vp, &file_size, ctx)) != 0)
334 goto swapon_bailout;
335#if CONFIG_MACF
336 vnode_lock(vp);
337 error = mac_system_check_swapon(vfs_context_ucred(ctx), vp);
338 vnode_unlock(vp);
339 if (error)
1c79356b 340 goto swapon_bailout;
2d21ac55 341#endif
1c79356b 342
91447636 343 /* resize to desired size if it's too small */
2d21ac55 344 if ((file_size < (off_t)size) && ((error = vnode_setsize(vp, (off_t)size, 0, ctx)) != 0))
91447636 345 goto swapon_bailout;
1c79356b 346
6d2010ae
A
347#if CONFIG_PROTECT
348 {
6d2010ae 349 /* initialize content protection keys manually */
316670eb
A
350 if ((error = cp_handle_vnop(vp, CP_WRITE_ACCESS, 0)) != 0) {
351 goto swapon_bailout;
352 }
6d2010ae
A
353 }
354#endif
355
356
0b4c1975
A
357 if (default_pager_init_flag == 0) {
358 start_def_pager(NULL);
359 default_pager_init_flag = 1;
360 }
361
1c79356b
A
362 /* add new backing store to list */
363 i = 0;
364 while(bs_port_table[i].vp != 0) {
365 if(i == MAX_BACKING_STORE)
366 break;
367 i++;
368 }
369 if(i == MAX_BACKING_STORE) {
370 error = ENOMEM;
1c79356b
A
371 goto swapon_bailout;
372 }
373
374 /* remember the vnode. This vnode has namei() reference */
375 bs_port_table[i].vp = vp;
376
377 /*
378 * Look to see if we are already paging to this file.
379 */
380 /* make certain the copy send of kernel call will work */
0b4e3aa0
A
381 default_pager = MEMORY_OBJECT_DEFAULT_NULL;
382 kr = host_default_memory_manager(host_priv_self(), &default_pager, 0);
1c79356b
A
383 if(kr != KERN_SUCCESS) {
384 error = EAGAIN;
1c79356b
A
385 bs_port_table[i].vp = 0;
386 goto swapon_bailout;
387 }
388
6d2010ae 389 if ((dp_isssd = vnode_pager_isSSD(vp)) == TRUE) {
0b4c1975
A
390 /*
391 * keep the cluster size small since the
392 * seek cost is effectively 0 which means
393 * we don't care much about fragmentation
394 */
0b4c1975
A
395 dp_cluster_size = 2 * PAGE_SIZE;
396 } else {
397 /*
398 * use the default cluster size
399 */
0b4c1975
A
400 dp_cluster_size = 0;
401 }
0b4e3aa0 402 kr = default_pager_backing_store_create(default_pager,
1c79356b 403 -1, /* default priority */
0b4c1975 404 dp_cluster_size,
1c79356b 405 &backing_store);
0b4e3aa0
A
406 memory_object_default_deallocate(default_pager);
407
1c79356b
A
408 if(kr != KERN_SUCCESS) {
409 error = ENOMEM;
1c79356b
A
410 bs_port_table[i].vp = 0;
411 goto swapon_bailout;
412 }
413
b0d623f7
A
414 /* Mark this vnode as being used for swapfile */
415 vnode_lock_spin(vp);
416 SET(vp->v_flag, VSWAP);
417 vnode_unlock(vp);
418
1c79356b
A
419 /*
420 * NOTE: we are able to supply PAGE_SIZE here instead of
421 * an actual record size or block number because:
422 * a: we do not support offsets from the beginning of the
423 * file (allowing for non page size/record modulo offsets.
424 * b: because allow paging will be done modulo page size
425 */
426
91447636
A
427 kr = default_pager_add_file(backing_store, (vnode_ptr_t) vp,
428 PAGE_SIZE, (int)(file_size/PAGE_SIZE));
1c79356b
A
429 if(kr != KERN_SUCCESS) {
430 bs_port_table[i].vp = 0;
431 if(kr == KERN_INVALID_ARGUMENT)
432 error = EINVAL;
433 else
434 error = ENOMEM;
b0d623f7
A
435
436 /* This vnode is not to be used for swapfile */
437 vnode_lock_spin(vp);
438 CLR(vp->v_flag, VSWAP);
439 vnode_unlock(vp);
440
1c79356b
A
441 goto swapon_bailout;
442 }
443 bs_port_table[i].bs = (void *)backing_store;
444 error = 0;
1c79356b 445
13fec989 446 ubc_setthreadcred(vp, p, current_thread());
55e303ae 447
1c79356b 448 /*
91447636 449 * take a long term reference on the vnode to keep
1c79356b
A
450 * vnreclaim() away from this vnode.
451 */
91447636 452 vnode_ref(vp);
1c79356b
A
453
454swapon_bailout:
455 if (vp) {
91447636 456 vnode_put(vp);
1c79356b 457 }
fe8ab488 458 lck_mtx_unlock(macx_lock);
e5568f75 459 AUDIT_MACH_SYSCALL_EXIT(error);
6d2010ae
A
460
461 if (error)
462 printf("macx_swapon FAILED - %d\n", error);
463 else
464 printf("macx_swapon SUCCESS\n");
465
1c79356b
A
466 return(error);
467}
468
469/*
470 * Routine: macx_swapoff
471 * Function:
472 * Syscall interface to remove a file from backing store
473 */
474int
475macx_swapoff(
91447636 476 struct macx_swapoff_args *args)
1c79356b 477{
91447636 478 __unused int flags = args->flags;
1c79356b
A
479 kern_return_t kr;
480 mach_port_t backing_store;
481
482 struct vnode *vp = 0;
483 struct nameidata nd, *ndp;
484 struct proc *p = current_proc();
485 int i;
486 int error;
2d21ac55 487 vfs_context_t ctx = vfs_context_current();
6d2010ae 488 int orig_iopol_disk;
1c79356b 489
e5568f75 490 AUDIT_MACH_SYSCALL_ENTER(AUE_SWAPOFF);
91447636 491
fe8ab488
A
492 lck_mtx_lock(macx_lock);
493
1c79356b
A
494 backing_store = NULL;
495 ndp = &nd;
496
91447636 497 if ((error = suser(kauth_cred_get(), 0)))
1c79356b
A
498 goto swapoff_bailout;
499
1c79356b
A
500 /*
501 * Get the vnode for the paging area.
502 */
6d2010ae 503 NDINIT(ndp, LOOKUP, OP_LOOKUP, FOLLOW | LOCKLEAF | AUDITVNPATH1,
91447636 504 ((IS_64BIT_PROCESS(p)) ? UIO_USERSPACE64 : UIO_USERSPACE32),
b0d623f7 505 (user_addr_t) args->filename, ctx);
1c79356b
A
506
507 if ((error = namei(ndp)))
508 goto swapoff_bailout;
91447636 509 nameidone(ndp);
1c79356b
A
510 vp = ndp->ni_vp;
511
512 if (vp->v_type != VREG) {
513 error = EINVAL;
1c79356b
A
514 goto swapoff_bailout;
515 }
2d21ac55
A
516#if CONFIG_MACF
517 vnode_lock(vp);
518 error = mac_system_check_swapoff(vfs_context_ucred(ctx), vp);
519 vnode_unlock(vp);
520 if (error)
521 goto swapoff_bailout;
522#endif
1c79356b
A
523
524 for(i = 0; i < MAX_BACKING_STORE; i++) {
525 if(bs_port_table[i].vp == vp) {
1c79356b
A
526 break;
527 }
528 }
529 if (i == MAX_BACKING_STORE) {
530 error = EINVAL;
1c79356b
A
531 goto swapoff_bailout;
532 }
533 backing_store = (mach_port_t)bs_port_table[i].bs;
534
39236c6e
A
535 orig_iopol_disk = proc_get_task_policy(current_task(), current_thread(),
536 TASK_POLICY_INTERNAL, TASK_POLICY_IOPOL);
6d2010ae 537
39236c6e
A
538 proc_set_task_policy(current_task(), current_thread(), TASK_POLICY_INTERNAL,
539 TASK_POLICY_IOPOL, IOPOL_THROTTLE);
6d2010ae 540
1c79356b 541 kr = default_pager_backing_store_delete(backing_store);
6d2010ae 542
39236c6e
A
543 proc_set_task_policy(current_task(), current_thread(), TASK_POLICY_INTERNAL,
544 TASK_POLICY_IOPOL, orig_iopol_disk);
6d2010ae 545
1c79356b
A
546 switch (kr) {
547 case KERN_SUCCESS:
548 error = 0;
549 bs_port_table[i].vp = 0;
1c79356b 550 /* This vnode is no longer used for swapfile */
b0d623f7 551 vnode_lock_spin(vp);
1c79356b 552 CLR(vp->v_flag, VSWAP);
b0d623f7 553 vnode_unlock(vp);
1c79356b 554
91447636
A
555 /* get rid of macx_swapon() "long term" reference */
556 vnode_rele(vp);
1c79356b 557
1c79356b
A
558 break;
559 case KERN_FAILURE:
560 error = EAGAIN;
561 break;
562 default:
563 error = EAGAIN;
564 break;
565 }
566
567swapoff_bailout:
568 /* get rid of macx_swapoff() namei() reference */
569 if (vp)
91447636 570 vnode_put(vp);
fe8ab488 571 lck_mtx_unlock(macx_lock);
e5568f75 572 AUDIT_MACH_SYSCALL_EXIT(error);
6d2010ae
A
573
574 if (error)
575 printf("macx_swapoff FAILED - %d\n", error);
576 else
577 printf("macx_swapoff SUCCESS\n");
578
1c79356b
A
579 return(error);
580}
91447636
A
581
582/*
583 * Routine: macx_swapinfo
584 * Function:
585 * Syscall interface to get general swap statistics
586 */
39236c6e
A
587extern uint64_t vm_swap_get_total_space(void);
588extern uint64_t vm_swap_get_used_space(void);
589extern uint64_t vm_swap_get_free_space(void);
590extern boolean_t vm_swap_up;
591
91447636
A
592int
593macx_swapinfo(
594 memory_object_size_t *total_p,
595 memory_object_size_t *avail_p,
596 vm_size_t *pagesize_p,
597 boolean_t *encrypted_p)
598{
599 int error;
600 memory_object_default_t default_pager;
601 default_pager_info_64_t dpi64;
602 kern_return_t kr;
603
604 error = 0;
39236c6e
A
605 if (COMPRESSED_PAGER_IS_ACTIVE) {
606
607 if (vm_swap_up == TRUE) {
608
609 *total_p = vm_swap_get_total_space();
610 *avail_p = vm_swap_get_free_space();
fe8ab488 611 *pagesize_p = (vm_size_t)PAGE_SIZE_64;
39236c6e
A
612 *encrypted_p = TRUE;
613
614 } else {
615
616 *total_p = 0;
617 *avail_p = 0;
618 *pagesize_p = 0;
619 *encrypted_p = FALSE;
620 }
621 } else {
91447636 622
91447636 623 /*
39236c6e 624 * Get a handle on the default pager.
91447636 625 */
39236c6e
A
626 default_pager = MEMORY_OBJECT_DEFAULT_NULL;
627 kr = host_default_memory_manager(host_priv_self(), &default_pager, 0);
628 if (kr != KERN_SUCCESS) {
629 error = EAGAIN; /* XXX why EAGAIN ? */
630 goto done;
631 }
632 if (default_pager == MEMORY_OBJECT_DEFAULT_NULL) {
633 /*
634 * The default pager has not initialized yet,
635 * so it can't be using any swap space at all.
636 */
637 *total_p = 0;
638 *avail_p = 0;
639 *pagesize_p = 0;
640 *encrypted_p = FALSE;
641 goto done;
642 }
643
644 /*
645 * Get swap usage data from default pager.
646 */
647 kr = default_pager_info_64(default_pager, &dpi64);
648 if (kr != KERN_SUCCESS) {
649 error = ENOTSUP;
650 goto done;
651 }
91447636 652
39236c6e
A
653 /*
654 * Provide default pager info to caller.
655 */
656 *total_p = dpi64.dpi_total_space;
657 *avail_p = dpi64.dpi_free_space;
658 *pagesize_p = dpi64.dpi_page_size;
659 if (dpi64.dpi_flags & DPI_ENCRYPTED) {
660 *encrypted_p = TRUE;
661 } else {
662 *encrypted_p = FALSE;
663 }
91447636
A
664
665done:
39236c6e
A
666 if (default_pager != MEMORY_OBJECT_DEFAULT_NULL) {
667 /* release our handle on default pager */
668 memory_object_default_deallocate(default_pager);
669 }
91447636
A
670 }
671 return error;
672}