| 2480 | } |
| 2481 | |
| 2482 | static int |
| 2483 | swapoff_one(struct swdevt *sp, struct ucred *cred) |
| 2484 | { |
| 2485 | u_long nblks; |
| 2486 | #ifdef MAC |
| 2487 | int error; |
| 2488 | #endif |
| 2489 | |
| 2490 | sx_assert(&swdev_syscall_lock, SA_XLOCKED); |
| 2491 | #ifdef MAC |
| 2492 | (void) vn_lock(sp->sw_vp, LK_EXCLUSIVE | LK_RETRY); |
| 2493 | error = mac_system_check_swapoff(cred, sp->sw_vp); |
| 2494 | (void) VOP_UNLOCK(sp->sw_vp); |
| 2495 | if (error != 0) |
| 2496 | return (error); |
| 2497 | #endif |
| 2498 | nblks = sp->sw_nblks; |
| 2499 | |
| 2500 | /* |
| 2501 | * We can turn off this swap device safely only if the |
| 2502 | * available virtual memory in the system will fit the amount |
| 2503 | * of data we will have to page back in, plus an epsilon so |
| 2504 | * the system doesn't become critically low on swap space. |
| 2505 | */ |
| 2506 | if (vm_free_count() + swap_pager_avail < nblks + nswap_lowat) |
| 2507 | return (ENOMEM); |
| 2508 | |
| 2509 | /* |
| 2510 | * Prevent further allocations on this device. |
| 2511 | */ |
| 2512 | mtx_lock(&sw_dev_mtx); |
| 2513 | sp->sw_flags |= SW_CLOSING; |
| 2514 | swap_pager_avail -= blist_fill(sp->sw_blist, 0, nblks); |
| 2515 | swap_total -= nblks; |
| 2516 | mtx_unlock(&sw_dev_mtx); |
| 2517 | |
| 2518 | /* |
| 2519 | * Page in the contents of the device and close it. |
| 2520 | */ |
| 2521 | swap_pager_swapoff(sp); |
| 2522 | |
| 2523 | sp->sw_close(curthread, sp); |
| 2524 | mtx_lock(&sw_dev_mtx); |
| 2525 | sp->sw_id = NULL; |
| 2526 | TAILQ_REMOVE(&swtailq, sp, sw_list); |
| 2527 | nswapdev--; |
| 2528 | if (nswapdev == 0) { |
| 2529 | swap_pager_full = 2; |
| 2530 | swap_pager_almost_full = 1; |
| 2531 | } |
| 2532 | if (swdevhd == sp) |
| 2533 | swdevhd = NULL; |
| 2534 | mtx_unlock(&sw_dev_mtx); |
| 2535 | blist_destroy(sp->sw_blist); |
| 2536 | free(sp, M_VMPGDATA); |
| 2537 | return (0); |
| 2538 | } |
| 2539 |
no test coverage detected