speed-ups using the new constants
[unix-history] / usr / src / sys / vm / vm_swap.c
CommitLineData
4f083fd7 1/* vm_swap.c 4.15 82/11/13 */
013037be
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/buf.h"
6#include "../h/conf.h"
7#include "../h/dir.h"
8#include "../h/user.h"
9#include "../h/inode.h"
10#include "../h/map.h"
5699bf69 11#include "../h/uio.h"
ca1f746a 12#include "../h/file.h"
4f083fd7 13#include "../h/nami.h"
013037be
BJ
14
15struct buf rswbuf;
16/*
17 * Indirect driver for multi-controller paging.
18 */
19swstrategy(bp)
20 register struct buf *bp;
21{
22 int sz, off, seg;
23 dev_t dev;
24
b9ee5d20
BJ
25#ifdef GENERIC
26 /*
27 * A mini-root gets copied into the front of the swap
28 * and we run over top of the swap area just long
29 * enough for us to do a mkfs and restor of the real
30 * root (sure beats rewriting standalone restor).
31 */
32#define MINIROOTSIZE 2048
33 if (rootdev == dumpdev)
34 bp->b_blkno += MINIROOTSIZE;
35#endif
ca1f746a 36 sz = howmany(bp->b_bcount, DEV_BSIZE);
013037be
BJ
37 off = bp->b_blkno % DMMAX;
38 if (bp->b_blkno+sz > nswap || off+sz > DMMAX) {
39 bp->b_flags |= B_ERROR;
40 iodone(bp);
41 return;
42 }
43 seg = bp->b_blkno / DMMAX;
44 dev = swdevt[seg % nswdev].sw_dev;
45 seg /= nswdev;
46 bp->b_blkno = seg*DMMAX + off;
47 bp->b_dev = dev;
48 if (dev == 0)
49 panic("swstrategy");
50 (*bdevsw[major(dev)].d_strategy)(bp);
51}
52
5699bf69
BJ
53swread(dev, uio)
54 dev_t dev;
55 struct uio *uio;
013037be
BJ
56{
57
30c36259 58 return (physio(swstrategy, &rswbuf, dev, B_READ, minphys, uio));
013037be
BJ
59}
60
5699bf69
BJ
61swwrite(dev, uio)
62 dev_t dev;
63 struct uio *uio;
013037be
BJ
64{
65
30c36259 66 return (physio(swstrategy, &rswbuf, dev, B_WRITE, minphys, uio));
013037be
BJ
67}
68
69/*
70 * System call swapon(name) enables swapping on device name,
71 * which must be in the swdevsw. Return EBUSY
72 * if already swapping on this device.
73 */
c4206698 74oswapon()
013037be 75{
013037be
BJ
76 register struct inode *ip;
77 dev_t dev;
78 register struct swdevt *sp;
79
4f083fd7 80 ip = namei(uchar, LOOKUP, 1);
013037be
BJ
81 if (ip == NULL)
82 return;
83 if ((ip->i_mode&IFMT) != IFBLK) {
84 u.u_error = ENOTBLK;
85 iput(ip);
86 return;
87 }
76e9203a 88 dev = (dev_t)ip->i_rdev;
013037be
BJ
89 iput(ip);
90 if (major(dev) >= nblkdev) {
91 u.u_error = ENXIO;
92 return;
93 }
94 /*
95 * Search starting at second table entry,
96 * since first (primary swap area) is freed at boot.
97 */
98 for (sp = &swdevt[1]; sp->sw_dev; sp++)
99 if (sp->sw_dev == dev) {
100 if (sp->sw_freed) {
101 u.u_error = EBUSY;
102 return;
103 }
104 swfree(sp - swdevt);
105 return;
106 }
107 u.u_error = ENODEV;
108}
109
110/*
111 * Swfree(index) frees the index'th portion of the swap map.
112 * Each of the nswdev devices provides 1/nswdev'th of the swap
113 * space, which is laid out with blocks of DMMAX pages circularly
114 * among the devices.
115 */
116swfree(index)
117 int index;
118{
119 register swblk_t vsbase;
39d536e6 120 register long blk;
e438ed8e 121 dev_t dev;
013037be 122
e438ed8e
BJ
123 dev = swdevt[index].sw_dev;
124 (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE);
013037be
BJ
125 swdevt[index].sw_freed = 1;
126 for (vsbase = index*DMMAX; vsbase < nswap; vsbase += nswdev*DMMAX) {
127 blk = nswap - vsbase;
128 if (blk > DMMAX)
129 blk = DMMAX;
130 if (vsbase == 0) {
131 /*
132 * Can't free a block starting at 0 in the swapmap
c84ff1f9 133 * but need some space for argmap so use 1/2 this
013037be
BJ
134 * hunk which needs special treatment anyways.
135 */
136 argdev = swdevt[0].sw_dev;
e438ed8e
BJ
137 rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
138 (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
c84ff1f9
BJ
139 /*
140 * First of all chunks... initialize the swapmap
141 * the second half of the hunk.
142 */
a29f7995
BJ
143 rminit(swapmap, (long)blk/2, (long)blk/2,
144 "swap", nswapmap);
013037be 145 } else
c84ff1f9 146 rmfree(swapmap, blk, vsbase);
013037be
BJ
147 }
148}