|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution is only permitted until one year after the first shipment
6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
7: * binary forms are permitted provided that: (1) source distributions retain
8: * this entire copyright notice and comment, and (2) distributions including
9: * binaries display the following acknowledgement: This product includes
10: * software developed by the University of California, Berkeley and its
11: * contributors'' in the documentation or other materials provided with the
12: * distribution and in all advertising materials mentioning features or use
13: * of this software. Neither the name of the University nor the names of
14: * its contributors may be used to endorse or promote products derived from
15: * this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: *
20: * @(#)vm_sw.c 7.14 (Berkeley) 6/28/90
21: */
22:
23: #include "param.h"
24: #include "systm.h"
25: #include "buf.h"
26: #include "conf.h"
27: #include "user.h"
28: #include "vnode.h"
29: #include "specdev.h"
30: #include "map.h"
31: #include "file.h"
32:
33: /*
34: * Indirect driver for multi-controller paging.
35: */
36: swstrategy(bp)
37: register struct buf *bp;
38: {
39: int sz, off, seg, index;
40: register struct swdevt *sp;
41: struct vnode *vp;
42:
43: #ifdef GENERIC
44: /*
45: * A mini-root gets copied into the front of the swap
46: * and we run over top of the swap area just long
47: * enough for us to do a mkfs and restor of the real
48: * root (sure beats rewriting standalone restor).
49: */
50: #define MINIROOTSIZE 4096
51: if (rootdev == dumpdev)
52: bp->b_blkno += MINIROOTSIZE;
53: #endif
54: sz = howmany(bp->b_bcount, DEV_BSIZE);
55: if (bp->b_blkno+sz > nswap) {
56: bp->b_flags |= B_ERROR;
57: biodone(bp);
58: return;
59: }
60: if (nswdev > 1) {
61: off = bp->b_blkno % dmmax;
62: if (off+sz > dmmax) {
63: bp->b_flags |= B_ERROR;
64: biodone(bp);
65: return;
66: }
67: seg = bp->b_blkno / dmmax;
68: index = seg % nswdev;
69: seg /= nswdev;
70: bp->b_blkno = seg*dmmax + off;
71: } else
72: index = 0;
73: sp = &swdevt[index];
74: if ((bp->b_dev = sp->sw_dev) == 0)
75: panic("swstrategy");
76: if (sp->sw_vp == NULL) {
77: bp->b_error |= B_ERROR;
78: biodone(bp);
79: return;
80: }
81: VHOLD(sp->sw_vp);
82: if ((bp->b_flags & B_READ) == 0) {
83: if (vp = bp->b_vp) {
84: vp->v_numoutput--;
85: if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
86: vp->v_flag &= ~VBWAIT;
87: wakeup((caddr_t)&vp->v_numoutput);
88: }
89: }
90: sp->sw_vp->v_numoutput++;
91: }
92: if (bp->b_vp != NULL)
93: brelvp(bp);
94: bp->b_vp = sp->sw_vp;
95: VOP_STRATEGY(bp);
96: }
97:
98: /*
99: * System call swapon(name) enables swapping on device name,
100: * which must be in the swdevsw. Return EBUSY
101: * if already swapping on this device.
102: */
103: /* ARGSUSED */
104: swapon(p, uap, retval)
105: struct proc *p;
106: struct args {
107: char *name;
108: } *uap;
109: int *retval;
110: {
111: register struct vnode *vp;
112: register struct swdevt *sp;
113: register struct nameidata *ndp = &u.u_nd;
114: dev_t dev;
115: int error;
116:
117: if (error = suser(u.u_cred, &u.u_acflag))
118: return (error);
119: ndp->ni_nameiop = LOOKUP | FOLLOW;
120: ndp->ni_segflg = UIO_USERSPACE;
121: ndp->ni_dirp = uap->name;
122: if (error = namei(ndp))
123: return (error);
124: vp = ndp->ni_vp;
125: if (vp->v_type != VBLK) {
126: vrele(vp);
127: return (ENOTBLK);
128: }
129: dev = (dev_t)vp->v_rdev;
130: if (major(dev) >= nblkdev) {
131: vrele(vp);
132: return (ENXIO);
133: }
134: for (sp = &swdevt[0]; sp->sw_dev; sp++)
135: if (sp->sw_dev == dev) {
136: if (sp->sw_freed) {
137: vrele(vp);
138: return (EBUSY);
139: }
140: sp->sw_vp = vp;
141: if (error = swfree(sp - swdevt)) {
142: vrele(vp);
143: return (error);
144: }
145: return (0);
146: }
147: vrele(vp);
148: return (EINVAL);
149: }
150:
151: /*
152: * Swfree(index) frees the index'th portion of the swap map.
153: * Each of the nswdev devices provides 1/nswdev'th of the swap
154: * space, which is laid out with blocks of dmmax pages circularly
155: * among the devices.
156: */
157: swfree(index)
158: int index;
159: {
160: register struct swdevt *sp;
161: register swblk_t vsbase;
162: register long blk;
163: struct vnode *vp;
164: register swblk_t dvbase;
165: register int nblks;
166: int error;
167:
168: sp = &swdevt[index];
169: vp = sp->sw_vp;
170: if (error = VOP_OPEN(vp, FREAD|FWRITE, u.u_cred))
171: return (error);
172: sp->sw_freed = 1;
173: nblks = sp->sw_nblks;
174: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
175: blk = nblks - dvbase;
176: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
177: panic("swfree");
178: if (blk > dmmax)
179: blk = dmmax;
180: if (vsbase == 0) {
181: /*
182: * Can't free a block starting at 0 in the swapmap
183: * but need some space for argmap so use 1/2 this
184: * hunk which needs special treatment anyways.
185: */
186: argdev = sp->sw_dev;
187: if (argdev_vp)
188: vrele(argdev_vp);
189: VREF(vp);
190: argdev_vp = vp;
191: rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
192: (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
193: /*
194: * First of all chunks... initialize the swapmap
195: * the second half of the hunk.
196: */
197: rminit(swapmap, (long)(blk/2), (long)(blk/2),
198: "swap", nswapmap);
199: } else if (dvbase == 0) {
200: /*
201: * Don't use the first cluster of the device
202: * in case it starts with a label or boot block.
203: */
204: rmfree(swapmap, blk - ctod(CLSIZE),
205: vsbase + ctod(CLSIZE));
206: } else
207: rmfree(swapmap, blk, vsbase);
208: }
209: return (0);
210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.