|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
1.1.1.5 ! root 33: * from: @(#)vm_swap.c 7.18 (Berkeley) 5/6/91
! 34: * vm_swap.c,v 1.9.2.1 1993/07/29 06:01:21 cgd Exp
1.1 root 35: */
36:
37: #include "param.h"
38: #include "systm.h"
39: #include "buf.h"
40: #include "conf.h"
41: #include "proc.h"
42: #include "namei.h"
43: #include "dmap.h" /* XXX */
44: #include "vnode.h"
45: #include "specdev.h"
1.1.1.5 ! root 46: #include "map.h"
1.1 root 47: #include "file.h"
48:
49: /*
50: * Indirect driver for multi-controller paging.
51: */
52:
53: int nswap, nswdev;
54:
55: /*
56: * Set up swap devices.
57: * Initialize linked list of free swap
58: * headers. These do not actually point
59: * to buffers, but rather to pages that
60: * are being swapped in and out.
61: */
1.1.1.5 ! root 62: void
1.1 root 63: swapinit()
64: {
65: register int i;
66: register struct buf *sp = swbuf;
67: struct swdevt *swp;
68: int error;
69:
70: /*
71: * Count swap devices, and adjust total swap space available.
72: * Some of this space will not be available until a swapon()
73: * system is issued, usually when the system goes multi-user.
74: */
75: nswdev = 0;
76: nswap = 0;
77: for (swp = swdevt; swp->sw_dev; swp++) {
78: nswdev++;
79: if (swp->sw_nblks > nswap)
80: nswap = swp->sw_nblks;
81: }
82: if (nswdev == 0)
83: panic("swapinit");
84: if (nswdev > 1)
85: nswap = ((nswap + dmmax - 1) / dmmax) * dmmax;
86: nswap *= nswdev;
87: if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp))
88: panic("swapvp");
89: if (error = swfree(&proc0, 0)) {
1.1.1.5 ! root 90: #ifdef notdef
! 91: printf("swfree errno %d\n", error); /* XXX */
! 92: panic("swapinit swfree 0");
! 93: #endif
! 94: printf("WARNING: no swap space present.\n");
1.1 root 95: }
96:
97: /*
98: * Now set up swap buffer headers.
99: */
100: bswlist.av_forw = sp;
101: for (i = 0; i < nswbuf - 1; i++, sp++)
102: sp->av_forw = sp + 1;
103: sp->av_forw = NULL;
104: }
105:
106: swstrategy(bp)
107: register struct buf *bp;
108: {
109: int sz, off, seg, index;
110: register struct swdevt *sp;
111: struct vnode *vp;
112:
113: #ifdef GENERIC
114: /*
115: * A mini-root gets copied into the front of the swap
116: * and we run over top of the swap area just long
117: * enough for us to do a mkfs and restor of the real
118: * root (sure beats rewriting standalone restor).
119: */
120: #define MINIROOTSIZE 4096
121: if (rootdev == dumpdev)
122: bp->b_blkno += MINIROOTSIZE;
123: #endif
124: sz = howmany(bp->b_bcount, DEV_BSIZE);
125: if (bp->b_blkno + sz > nswap) {
126: bp->b_flags |= B_ERROR;
127: biodone(bp);
128: return;
129: }
130: if (nswdev > 1) {
131: off = bp->b_blkno % dmmax;
132: if (off+sz > dmmax) {
133: bp->b_flags |= B_ERROR;
134: biodone(bp);
135: return;
136: }
137: seg = bp->b_blkno / dmmax;
138: index = seg % nswdev;
139: seg /= nswdev;
140: bp->b_blkno = seg*dmmax + off;
141: } else
142: index = 0;
143: sp = &swdevt[index];
144: if ((bp->b_dev = sp->sw_dev) == 0)
145: panic("swstrategy");
146: if (sp->sw_vp == NULL) {
147: bp->b_error |= B_ERROR;
148: biodone(bp);
149: return;
150: }
151: VHOLD(sp->sw_vp);
152: if ((bp->b_flags & B_READ) == 0) {
153: if (vp = bp->b_vp) {
154: vp->v_numoutput--;
155: if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
156: vp->v_flag &= ~VBWAIT;
157: wakeup((caddr_t)&vp->v_numoutput);
158: }
159: }
160: sp->sw_vp->v_numoutput++;
161: }
162: if (bp->b_vp != NULL)
163: brelvp(bp);
164: bp->b_vp = sp->sw_vp;
165: VOP_STRATEGY(bp);
166: }
167:
168: /*
169: * System call swapon(name) enables swapping on device name,
170: * which must be in the swdevsw. Return EBUSY
171: * if already swapping on this device.
172: */
1.1.1.5 ! root 173: struct swapon_args {
! 174: char *name;
! 175: };
! 176:
1.1 root 177: /* ARGSUSED */
178: swapon(p, uap, retval)
179: struct proc *p;
1.1.1.5 ! root 180: struct swapon_args *uap;
1.1 root 181: int *retval;
182: {
183: register struct vnode *vp;
184: register struct swdevt *sp;
185: register struct nameidata *ndp;
186: dev_t dev;
187: int error;
188: struct nameidata nd;
189:
190: if (error = suser(p->p_ucred, &p->p_acflag))
191: return (error);
192: ndp = &nd;
193: ndp->ni_nameiop = LOOKUP | FOLLOW;
194: ndp->ni_segflg = UIO_USERSPACE;
195: ndp->ni_dirp = uap->name;
196: if (error = namei(ndp, p))
197: return (error);
198: vp = ndp->ni_vp;
199: if (vp->v_type != VBLK) {
200: vrele(vp);
201: return (ENOTBLK);
202: }
203: dev = (dev_t)vp->v_rdev;
204: if (major(dev) >= nblkdev) {
205: vrele(vp);
206: return (ENXIO);
207: }
208: for (sp = &swdevt[0]; sp->sw_dev; sp++)
209: if (sp->sw_dev == dev) {
210: if (sp->sw_freed) {
211: vrele(vp);
212: return (EBUSY);
213: }
214: sp->sw_vp = vp;
215: if (error = swfree(p, sp - swdevt)) {
216: vrele(vp);
217: return (error);
218: }
219: return (0);
220: }
221: vrele(vp);
222: return (EINVAL);
223: }
224:
225: /*
226: * Swfree(index) frees the index'th portion of the swap map.
227: * Each of the nswdev devices provides 1/nswdev'th of the swap
228: * space, which is laid out with blocks of dmmax pages circularly
229: * among the devices.
230: */
231: swfree(p, index)
232: struct proc *p;
233: int index;
234: {
235: register struct swdevt *sp;
236: register swblk_t vsbase;
237: register long blk;
238: struct vnode *vp;
239: register swblk_t dvbase;
240: register int nblks;
241: int error;
242:
243: sp = &swdevt[index];
244: vp = sp->sw_vp;
245: if (error = VOP_OPEN(vp, FREAD|FWRITE, p->p_ucred, p))
246: return (error);
247: sp->sw_freed = 1;
1.1.1.5 ! root 248: nblks = sp->sw_nblks;
1.1 root 249: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
250: blk = nblks - dvbase;
251: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
252: panic("swfree");
253: if (blk > dmmax)
254: blk = dmmax;
1.1.1.5 ! root 255: if (vsbase == 0) {
! 256: /*
! 257: * First of all chunks... initialize the swapmap.
! 258: * Don't use the first cluster of the device
! 259: * in case it starts with a label or boot block.
! 260: */
! 261: rminit(swapmap, blk - ctod(CLSIZE),
! 262: vsbase + ctod(CLSIZE), "swap", nswapmap);
! 263: } else if (dvbase == 0) {
! 264: /*
! 265: * Don't use the first cluster of the device
! 266: * in case it starts with a label or boot block.
! 267: */
! 268: rmfree(swapmap, blk - ctod(CLSIZE),
! 269: vsbase + ctod(CLSIZE));
! 270: } else
! 271: rmfree(swapmap, blk, vsbase);
1.1 root 272: }
273: return (0);
274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.