* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)vm_swap.c 7.18 (Berkeley) 5/6/91
static char rcsid
[] = "$Header: /usr/bill/working/sys/vm/RCS/vm_swap.c,v 1.3 92/01/21 21:58:25 william Exp $";
#include "dmap.h" /* XXX */
* Indirect driver for multi-controller paging.
* Initialize linked list of free swap
* headers. These do not actually point
* to buffers, but rather to pages that
* are being swapped in and out.
register struct buf
*sp
= swbuf
;
* Count swap devices, and adjust total swap space available.
* Some of this space will not be available until a swapon()
* system is issued, usually when the system goes multi-user.
for (swp
= swdevt
; swp
->sw_dev
; swp
++) {
if (swp
->sw_nblks
> nswap
)
nswap
= ((nswap
+ dmmax
- 1) / dmmax
) * dmmax
;
if (bdevvp(swdevt
[0].sw_dev
, &swdevt
[0].sw_vp
))
if (error
= swfree(&proc0
, 0)) {
printf("\nwarning: no swap space present (yet)\n");
/* printf("(swfree (..., 0) -> %d)\n", error); /* XXX */
/*panic("swapinit swfree 0");*/
* Now set up swap buffer headers.
for (i
= 0; i
< nswbuf
- 1; i
++, sp
++)
register struct swdevt
*sp
;
* A mini-root gets copied into the front of the swap
* and we run over top of the swap area just long
* enough for us to do a mkfs and restor of the real
* root (sure beats rewriting standalone restor).
#define MINIROOTSIZE 4096
bp
->b_blkno
+= MINIROOTSIZE
;
sz
= howmany(bp
->b_bcount
, DEV_BSIZE
);
if (bp
->b_blkno
+ sz
> nswap
) {
off
= bp
->b_blkno
% dmmax
;
seg
= bp
->b_blkno
/ dmmax
;
bp
->b_blkno
= seg
*dmmax
+ off
;
if ((bp
->b_dev
= sp
->sw_dev
) == 0)
if ((bp
->b_flags
& B_READ
) == 0) {
if ((vp
->v_flag
& VBWAIT
) && vp
->v_numoutput
<= 0) {
wakeup((caddr_t
)&vp
->v_numoutput
);
sp
->sw_vp
->v_numoutput
++;
* System call swapon(name) enables swapping on device name,
* which must be in the swdevsw. Return EBUSY
* if already swapping on this device.
register struct vnode
*vp
;
register struct swdevt
*sp
;
register struct nameidata
*ndp
;
if (error
= suser(p
->p_ucred
, &p
->p_acflag
))
ndp
->ni_nameiop
= LOOKUP
| FOLLOW
;
ndp
->ni_segflg
= UIO_USERSPACE
;
ndp
->ni_dirp
= uap
->name
;
if (error
= namei(ndp
, p
))
if (vp
->v_type
!= VBLK
) {
if (major(dev
) >= nblkdev
) {
for (sp
= &swdevt
[0]; sp
->sw_dev
; sp
++)
if (error
= swfree(p
, sp
- swdevt
)) {
printf("failed! (unchanged)\n");
* Swfree(index) frees the index'th portion of the swap map.
* Each of the nswdev devices provides 1/nswdev'th of the swap
* space, which is laid out with blocks of dmmax pages circularly
register struct swdevt
*sp
;
if (error
= VOP_OPEN(vp
, FREAD
|FWRITE
, p
->p_ucred
, p
))
/*printf("%d blocks from device %d/%d ",
sp->sw_nblks, major(sp->sw_dev), minor(sp->sw_dev));*/
for (dvbase
= 0; dvbase
< nblks
; dvbase
+= dmmax
) {
if ((vsbase
= index
*dmmax
+ dvbase
*nswdev
) >= nswap
)
rlist_free(&swapmap
, vsbase
, vsbase
+ blk
- 1);