* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)vm_swap.c 7.23 (Berkeley) %G%
#include <sys/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
;
register struct proc
*p
= &proc0
; /* XXX */
* 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(p
, 0)) {
printf("swfree errno %d\n", error
); /* XXX */
panic("swapinit swfree 0");
* Now set up swap buffer headers.
for (i
= 0; i
< nswbuf
- 1; i
++, sp
++) {
sp
->b_rcred
= sp
->b_wcred
= p
->p_ucred
;
sp
->b_rcred
= sp
->b_wcred
= p
->p_ucred
;
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
;
bp
->b_blkno
<<= sp
->sw_bshift
;
bp
->b_blksize
= sp
->sw_blksize
;
(*bdevsw
[major(bp
->b_dev
)].d_strategy
)(bp
);
* 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
;
if (error
= suser(p
->p_ucred
, &p
->p_acflag
))
NDINIT(&nd
, LOOKUP
, FOLLOW
, UIO_USERSPACE
, uap
->name
, p
);
if (vp
->v_type
!= VBLK
) {
if (major(dev
) >= nblkdev
) {
for (sp
= &swdevt
[0]; sp
->sw_dev
; sp
++)
u
.u_error
= swfree(sp
- swdevt
);
long argdbsize
; /* XXX */
* 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
;
register struct swdevt
*sp
;
if (error
= (*bdevsw
[major(dev
)].d_open
)(dev
, FREAD
|FWRITE
, S_IFBLK
))
for (dvbase
= 0; dvbase
< nblks
; dvbase
+= dmmax
) {
if ((vsbase
= index
*dmmax
+ dvbase
*nswdev
) >= nswap
)
* First of all chunks... initialize the swapmap
* the second half of the hunk.
rminit(swapmap
, (long)(blk
/2), (long)(blk
/2),
} else if (dvbase
== 0) {
* Don't use the first cluster of the device
* in case it starts with a label or boot block.
rmfree(swapmap
, blk
- ctod(CLSIZE
),
} else if (dvbase
== 0) {
* Don't use the first cluster of the device
* in case it starts with a label or boot block.
rmfree(swapmap
, blk
- ctod(CLSIZE
),
rmfree(swapmap
, blk
, vsbase
);