1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)vm_sw.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "param.h"
10: #include "systm.h"
11: #include "buf.h"
12: #include "conf.h"
13: #include "dir.h"
14: #include "user.h"
15: #include "inode.h"
16: #include "map.h"
17: #include "uio.h"
18: #include "file.h"
19:
20: struct buf rswbuf;
21: /*
22: * Indirect driver for multi-controller paging.
23: */
24: swstrategy(bp)
25: register struct buf *bp;
26: {
27: int sz, off, seg;
28: dev_t dev;
29:
30: #ifdef GENERIC
31: /*
32: * A mini-root gets copied into the front of the swap
33: * and we run over top of the swap area just long
34: * enough for us to do a mkfs and restor of the real
35: * root (sure beats rewriting standalone restor).
36: */
37: #define MINIROOTSIZE 4096
38: if (rootdev == dumpdev)
39: bp->b_blkno += MINIROOTSIZE;
40: #endif
41: sz = howmany(bp->b_bcount, DEV_BSIZE);
42: if (bp->b_blkno+sz > nswap) {
43: bp->b_flags |= B_ERROR;
44: iodone(bp);
45: return;
46: }
47: if (nswdev > 1) {
48: off = bp->b_blkno % dmmax;
49: if (off+sz > dmmax) {
50: bp->b_flags |= B_ERROR;
51: iodone(bp);
52: return;
53: }
54: seg = bp->b_blkno / dmmax;
55: dev = swdevt[seg % nswdev].sw_dev;
56: seg /= nswdev;
57: bp->b_blkno = seg*dmmax + off;
58: } else
59: dev = swdevt[0].sw_dev;
60: bp->b_dev = dev;
61: if (dev == 0)
62: panic("swstrategy");
63: (*bdevsw[major(dev)].d_strategy)(bp);
64: }
65:
66: swread(dev, uio)
67: dev_t dev;
68: struct uio *uio;
69: {
70:
71: return (physio(swstrategy, &rswbuf, dev, B_READ, minphys, uio));
72: }
73:
74: swwrite(dev, uio)
75: dev_t dev;
76: struct uio *uio;
77: {
78:
79: return (physio(swstrategy, &rswbuf, dev, B_WRITE, minphys, uio));
80: }
81:
82: /*
83: * System call swapon(name) enables swapping on device name,
84: * which must be in the swdevsw. Return EBUSY
85: * if already swapping on this device.
86: */
87: swapon()
88: {
89: struct a {
90: char *name;
91: } *uap = (struct a *)u.u_ap;
92: register struct inode *ip;
93: dev_t dev;
94: register struct swdevt *sp;
95: register struct nameidata *ndp = &u.u_nd;
96:
97: if (!suser())
98: return;
99: ndp->ni_nameiop = LOOKUP | FOLLOW;
100: ndp->ni_segflg = UIO_USERSPACE;
101: ndp->ni_dirp = uap->name;
102: ip = namei(ndp);
103: if (ip == NULL)
104: return;
105: if ((ip->i_mode&IFMT) != IFBLK) {
106: u.u_error = ENOTBLK;
107: iput(ip);
108: return;
109: }
110: dev = (dev_t)ip->i_rdev;
111: iput(ip);
112: if (major(dev) >= nblkdev) {
113: u.u_error = ENXIO;
114: return;
115: }
116: for (sp = &swdevt[0]; sp->sw_dev; sp++)
117: if (sp->sw_dev == dev) {
118: if (sp->sw_freed) {
119: u.u_error = EBUSY;
120: return;
121: }
122: swfree(sp - swdevt);
123: return;
124: }
125: u.u_error = EINVAL;
126: }
127:
128: /*
129: * Swfree(index) frees the index'th portion of the swap map.
130: * Each of the nswdev devices provides 1/nswdev'th of the swap
131: * space, which is laid out with blocks of dmmax pages circularly
132: * among the devices.
133: */
134: swfree(index)
135: int index;
136: {
137: register swblk_t vsbase;
138: register long blk;
139: dev_t dev;
140: register swblk_t dvbase;
141: register int nblks;
142:
143: dev = swdevt[index].sw_dev;
144: (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE);
145: swdevt[index].sw_freed = 1;
146: nblks = swdevt[index].sw_nblks;
147: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
148: blk = nblks - dvbase;
149: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
150: panic("swfree");
151: if (blk > dmmax)
152: blk = dmmax;
153: if (vsbase == 0) {
154: /*
155: * Can't free a block starting at 0 in the swapmap
156: * but need some space for argmap so use 1/2 this
157: * hunk which needs special treatment anyways.
158: */
159: argdev = swdevt[0].sw_dev;
160: rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
161: (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
162: /*
163: * First of all chunks... initialize the swapmap
164: * the second half of the hunk.
165: */
166: rminit(swapmap, (long)blk/2, (long)blk/2,
167: "swap", nswapmap);
168: } else
169: rmfree(swapmap, blk, vsbase);
170: }
171: }
Defined functions
Defined variables
Defined struct's
a
defined in line
89; used 2 times
Defined macros