|
|
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: *
33: * @(#)vm_swap.c 7.18 (Berkeley) 5/6/91
34: */
1.1.1.2 root 35: static char rcsid[] = "$Header: /usr/bill/working/sys/vm/RCS/vm_swap.c,v 1.3 92/01/21 21:58:25 william Exp $";
1.1 root 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"
46: #include "file.h"
1.1.1.2 root 47: #include "rlist.h"
1.1 root 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: */
62: swapinit()
63: {
64: register int i;
65: register struct buf *sp = swbuf;
66: struct swdevt *swp;
67: int error;
68:
69: /*
70: * Count swap devices, and adjust total swap space available.
71: * Some of this space will not be available until a swapon()
72: * system is issued, usually when the system goes multi-user.
73: */
74: nswdev = 0;
75: nswap = 0;
76: for (swp = swdevt; swp->sw_dev; swp++) {
77: nswdev++;
78: if (swp->sw_nblks > nswap)
79: nswap = swp->sw_nblks;
80: }
81: if (nswdev == 0)
82: panic("swapinit");
83: if (nswdev > 1)
84: nswap = ((nswap + dmmax - 1) / dmmax) * dmmax;
85: nswap *= nswdev;
86: if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp))
87: panic("swapvp");
88: if (error = swfree(&proc0, 0)) {
1.1.1.3 ! root 89: printf("\nwarning: no swap space present (yet)\n");
! 90: /* printf("(swfree (..., 0) -> %d)\n", error); /* XXX */
! 91: /*panic("swapinit swfree 0");*/
1.1 root 92: }
93:
94: /*
95: * Now set up swap buffer headers.
96: */
97: bswlist.av_forw = sp;
98: for (i = 0; i < nswbuf - 1; i++, sp++)
99: sp->av_forw = sp + 1;
100: sp->av_forw = NULL;
101: }
102:
103: swstrategy(bp)
104: register struct buf *bp;
105: {
106: int sz, off, seg, index;
107: register struct swdevt *sp;
108: struct vnode *vp;
109:
110: #ifdef GENERIC
111: /*
112: * A mini-root gets copied into the front of the swap
113: * and we run over top of the swap area just long
114: * enough for us to do a mkfs and restor of the real
115: * root (sure beats rewriting standalone restor).
116: */
117: #define MINIROOTSIZE 4096
118: if (rootdev == dumpdev)
119: bp->b_blkno += MINIROOTSIZE;
120: #endif
121: sz = howmany(bp->b_bcount, DEV_BSIZE);
122: if (bp->b_blkno + sz > nswap) {
123: bp->b_flags |= B_ERROR;
124: biodone(bp);
125: return;
126: }
127: if (nswdev > 1) {
128: off = bp->b_blkno % dmmax;
129: if (off+sz > dmmax) {
130: bp->b_flags |= B_ERROR;
131: biodone(bp);
132: return;
133: }
134: seg = bp->b_blkno / dmmax;
135: index = seg % nswdev;
136: seg /= nswdev;
137: bp->b_blkno = seg*dmmax + off;
138: } else
139: index = 0;
140: sp = &swdevt[index];
141: if ((bp->b_dev = sp->sw_dev) == 0)
142: panic("swstrategy");
143: if (sp->sw_vp == NULL) {
144: bp->b_error |= B_ERROR;
145: biodone(bp);
146: return;
147: }
148: VHOLD(sp->sw_vp);
149: if ((bp->b_flags & B_READ) == 0) {
150: if (vp = bp->b_vp) {
151: vp->v_numoutput--;
152: if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
153: vp->v_flag &= ~VBWAIT;
154: wakeup((caddr_t)&vp->v_numoutput);
155: }
156: }
157: sp->sw_vp->v_numoutput++;
158: }
159: if (bp->b_vp != NULL)
160: brelvp(bp);
161: bp->b_vp = sp->sw_vp;
162: VOP_STRATEGY(bp);
163: }
164:
165: /*
166: * System call swapon(name) enables swapping on device name,
167: * which must be in the swdevsw. Return EBUSY
168: * if already swapping on this device.
169: */
170: /* ARGSUSED */
171: swapon(p, uap, retval)
172: struct proc *p;
173: struct args {
174: char *name;
175: } *uap;
176: int *retval;
177: {
178: register struct vnode *vp;
179: register struct swdevt *sp;
180: register struct nameidata *ndp;
181: dev_t dev;
182: int error;
183: struct nameidata nd;
184:
185: if (error = suser(p->p_ucred, &p->p_acflag))
186: return (error);
187: ndp = &nd;
188: ndp->ni_nameiop = LOOKUP | FOLLOW;
189: ndp->ni_segflg = UIO_USERSPACE;
190: ndp->ni_dirp = uap->name;
191: if (error = namei(ndp, p))
192: return (error);
193: vp = ndp->ni_vp;
194: if (vp->v_type != VBLK) {
195: vrele(vp);
196: return (ENOTBLK);
197: }
198: dev = (dev_t)vp->v_rdev;
199: if (major(dev) >= nblkdev) {
200: vrele(vp);
201: return (ENXIO);
202: }
203: for (sp = &swdevt[0]; sp->sw_dev; sp++)
204: if (sp->sw_dev == dev) {
205: if (sp->sw_freed) {
206: vrele(vp);
207: return (EBUSY);
208: }
209: sp->sw_vp = vp;
1.1.1.3 ! root 210: printf("adding swap: ");
1.1 root 211: if (error = swfree(p, sp - swdevt)) {
1.1.1.3 ! root 212: printf("failed! (unchanged)\n");
1.1 root 213: vrele(vp);
214: return (error);
215: }
216: return (0);
217: }
218: vrele(vp);
219: return (EINVAL);
220: }
221:
222: /*
223: * Swfree(index) frees the index'th portion of the swap map.
224: * Each of the nswdev devices provides 1/nswdev'th of the swap
225: * space, which is laid out with blocks of dmmax pages circularly
226: * among the devices.
227: */
228: swfree(p, index)
229: struct proc *p;
230: int index;
231: {
232: register struct swdevt *sp;
233: register swblk_t vsbase;
234: register long blk;
235: struct vnode *vp;
236: register swblk_t dvbase;
237: register int nblks;
238: int error;
239:
240: sp = &swdevt[index];
1.1.1.3 ! root 241: nblks = sp->sw_nblks;
! 242: if (nblks <= 0)
! 243: return(ENXIO);
1.1 root 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.3 ! root 248:
! 249: /*printf("%d blocks from device %d/%d ",
! 250: sp->sw_nblks, major(sp->sw_dev), minor(sp->sw_dev));*/
1.1 root 251: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
252: blk = nblks - dvbase;
253: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
254: panic("swfree");
255: if (blk > dmmax)
256: blk = dmmax;
1.1.1.3 ! root 257: rlist_free(&swapmap, vsbase, vsbase + blk - 1);
1.1 root 258: }
259: return (0);
260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.