* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)vm_swap.c 7.13 (Berkeley) %G%
* Indirect driver for multi-controller paging.
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
;
register struct nameidata
*ndp
= &u
.u_nd
;
if (error
= suser(u
.u_cred
, &u
.u_acflag
))
ndp
->ni_nameiop
= LOOKUP
| FOLLOW
;
ndp
->ni_segflg
= UIO_USERSPACE
;
ndp
->ni_dirp
= uap
->name
;
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
)
* Can't free a block starting at 0 in the swapmap
* but need some space for argmap so use 1/2 this
* hunk which needs special treatment anyways.
argdbsize
= sp
->sw_blksize
;
((blk
/ 2) * DEV_BSIZE
- CLBYTES
) / argdbsize
,
CLBYTES
/ argdbsize
, "argmap", ARGMAPSIZE
);
rminit(argmap
, (long)(blk
/2-ctod(CLSIZE
)),
(long)ctod(CLSIZE
), "argmap", ARGMAPSIZE
);
* 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
);