|
|
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)) {
89: printf("swfree errno %d\n", error); /* XXX */
90: panic("swapinit swfree 0");
91: }
92:
93: /*
94: * Now set up swap buffer headers.
95: */
96: bswlist.av_forw = sp;
97: for (i = 0; i < nswbuf - 1; i++, sp++)
98: sp->av_forw = sp + 1;
99: sp->av_forw = NULL;
100: }
101:
102: swstrategy(bp)
103: register struct buf *bp;
104: {
105: int sz, off, seg, index;
106: register struct swdevt *sp;
107: struct vnode *vp;
108:
109: #ifdef GENERIC
110: /*
111: * A mini-root gets copied into the front of the swap
112: * and we run over top of the swap area just long
113: * enough for us to do a mkfs and restor of the real
114: * root (sure beats rewriting standalone restor).
115: */
116: #define MINIROOTSIZE 4096
117: if (rootdev == dumpdev)
118: bp->b_blkno += MINIROOTSIZE;
119: #endif
120: sz = howmany(bp->b_bcount, DEV_BSIZE);
121: if (bp->b_blkno + sz > nswap) {
122: bp->b_flags |= B_ERROR;
123: biodone(bp);
124: return;
125: }
126: if (nswdev > 1) {
127: off = bp->b_blkno % dmmax;
128: if (off+sz > dmmax) {
129: bp->b_flags |= B_ERROR;
130: biodone(bp);
131: return;
132: }
133: seg = bp->b_blkno / dmmax;
134: index = seg % nswdev;
135: seg /= nswdev;
136: bp->b_blkno = seg*dmmax + off;
137: } else
138: index = 0;
139: sp = &swdevt[index];
140: if ((bp->b_dev = sp->sw_dev) == 0)
141: panic("swstrategy");
142: if (sp->sw_vp == NULL) {
143: bp->b_error |= B_ERROR;
144: biodone(bp);
145: return;
146: }
147: VHOLD(sp->sw_vp);
148: if ((bp->b_flags & B_READ) == 0) {
149: if (vp = bp->b_vp) {
150: vp->v_numoutput--;
151: if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
152: vp->v_flag &= ~VBWAIT;
153: wakeup((caddr_t)&vp->v_numoutput);
154: }
155: }
156: sp->sw_vp->v_numoutput++;
157: }
158: if (bp->b_vp != NULL)
159: brelvp(bp);
160: bp->b_vp = sp->sw_vp;
161: VOP_STRATEGY(bp);
162: }
163:
164: /*
165: * System call swapon(name) enables swapping on device name,
166: * which must be in the swdevsw. Return EBUSY
167: * if already swapping on this device.
168: */
169: /* ARGSUSED */
170: swapon(p, uap, retval)
171: struct proc *p;
172: struct args {
173: char *name;
174: } *uap;
175: int *retval;
176: {
177: register struct vnode *vp;
178: register struct swdevt *sp;
179: register struct nameidata *ndp;
180: dev_t dev;
181: int error;
182: struct nameidata nd;
183:
184: if (error = suser(p->p_ucred, &p->p_acflag))
185: return (error);
186: ndp = &nd;
187: ndp->ni_nameiop = LOOKUP | FOLLOW;
188: ndp->ni_segflg = UIO_USERSPACE;
189: ndp->ni_dirp = uap->name;
190: if (error = namei(ndp, p))
191: return (error);
192: vp = ndp->ni_vp;
193: if (vp->v_type != VBLK) {
194: vrele(vp);
195: return (ENOTBLK);
196: }
197: dev = (dev_t)vp->v_rdev;
198: if (major(dev) >= nblkdev) {
199: vrele(vp);
200: return (ENXIO);
201: }
202: for (sp = &swdevt[0]; sp->sw_dev; sp++)
203: if (sp->sw_dev == dev) {
204: if (sp->sw_freed) {
205: vrele(vp);
206: return (EBUSY);
207: }
208: sp->sw_vp = vp;
209: if (error = swfree(p, sp - swdevt)) {
210: vrele(vp);
211: return (error);
212: }
213: return (0);
214: }
215: vrele(vp);
216: return (EINVAL);
217: }
218:
219: /*
220: * Swfree(index) frees the index'th portion of the swap map.
221: * Each of the nswdev devices provides 1/nswdev'th of the swap
222: * space, which is laid out with blocks of dmmax pages circularly
223: * among the devices.
224: */
225: swfree(p, index)
226: struct proc *p;
227: int index;
228: {
229: register struct swdevt *sp;
230: register swblk_t vsbase;
231: register long blk;
232: struct vnode *vp;
233: register swblk_t dvbase;
234: register int nblks;
235: int error;
236:
237: sp = &swdevt[index];
238: vp = sp->sw_vp;
239: if (error = VOP_OPEN(vp, FREAD|FWRITE, p->p_ucred, p))
240: return (error);
241: sp->sw_freed = 1;
242: nblks = sp->sw_nblks;
243: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
244: blk = nblks - dvbase;
245: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
246: panic("swfree");
247: if (blk > dmmax)
248: blk = dmmax;
1.1.1.2 ! root 249: /*
! 250: * Don't use the first cluster of the device
! 251: * in case it starts with a label or boot block.
! 252: */
! 253: if (dvbase == 0)
! 254: rlist_free(&swapmap, vsbase + ctod(CLSIZE),
! 255: vsbase + blk - 1);
! 256: else
! 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.