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