rework namei interface to eliminate global variables
[unix-history] / usr / src / sys / vm / vm_swap.c
CommitLineData
b11be056 1/* vm_swap.c 6.1 83/07/29 */
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 */
8c5046eb 32#define MINIROOTSIZE 4096
b9ee5d20
BJ
33 if (rootdev == dumpdev)
34 bp->b_blkno += MINIROOTSIZE;
35#endif
ca1f746a 36 sz = howmany(bp->b_bcount, DEV_BSIZE);
d668d9ba 37 if (bp->b_blkno+sz > nswap) {
013037be
BJ
38 bp->b_flags |= B_ERROR;
39 iodone(bp);
40 return;
41 }
d668d9ba
SL
42 if (nswdev > 1) {
43 off = bp->b_blkno % dmmax;
44 if (off+sz > dmmax) {
45 bp->b_flags |= B_ERROR;
46 iodone(bp);
47 return;
48 }
49 seg = bp->b_blkno / dmmax;
50 dev = swdevt[seg % nswdev].sw_dev;
51 seg /= nswdev;
52 bp->b_blkno = seg*dmmax + off;
53 } else
54 dev = swdevt[0].sw_dev;
013037be
BJ
55 bp->b_dev = dev;
56 if (dev == 0)
57 panic("swstrategy");
58 (*bdevsw[major(dev)].d_strategy)(bp);
59}
60
5699bf69
BJ
61swread(dev, uio)
62 dev_t dev;
63 struct uio *uio;
013037be
BJ
64{
65
30c36259 66 return (physio(swstrategy, &rswbuf, dev, B_READ, minphys, uio));
013037be
BJ
67}
68
5699bf69
BJ
69swwrite(dev, uio)
70 dev_t dev;
71 struct uio *uio;
013037be
BJ
72{
73
30c36259 74 return (physio(swstrategy, &rswbuf, dev, B_WRITE, minphys, uio));
013037be
BJ
75}
76
77/*
78 * System call swapon(name) enables swapping on device name,
79 * which must be in the swdevsw. Return EBUSY
80 * if already swapping on this device.
81 */
2dfa06c1 82swapon()
013037be 83{
2dfa06c1
SL
84 struct a {
85 char *name;
86 };
013037be
BJ
87 register struct inode *ip;
88 dev_t dev;
89 register struct swdevt *sp;
90
4f083fd7 91 ip = namei(uchar, LOOKUP, 1);
013037be
BJ
92 if (ip == NULL)
93 return;
94 if ((ip->i_mode&IFMT) != IFBLK) {
95 u.u_error = ENOTBLK;
96 iput(ip);
97 return;
98 }
76e9203a 99 dev = (dev_t)ip->i_rdev;
013037be
BJ
100 iput(ip);
101 if (major(dev) >= nblkdev) {
102 u.u_error = ENXIO;
103 return;
104 }
105 /*
106 * Search starting at second table entry,
107 * since first (primary swap area) is freed at boot.
108 */
109 for (sp = &swdevt[1]; sp->sw_dev; sp++)
110 if (sp->sw_dev == dev) {
111 if (sp->sw_freed) {
112 u.u_error = EBUSY;
113 return;
114 }
115 swfree(sp - swdevt);
116 return;
117 }
118 u.u_error = ENODEV;
119}
120
121/*
122 * Swfree(index) frees the index'th portion of the swap map.
123 * Each of the nswdev devices provides 1/nswdev'th of the swap
d668d9ba 124 * space, which is laid out with blocks of dmmax pages circularly
013037be
BJ
125 * among the devices.
126 */
127swfree(index)
128 int index;
129{
130 register swblk_t vsbase;
39d536e6 131 register long blk;
e438ed8e 132 dev_t dev;
d668d9ba
SL
133 register swblk_t dvbase;
134 register int nblks;
013037be 135
e438ed8e
BJ
136 dev = swdevt[index].sw_dev;
137 (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE);
013037be 138 swdevt[index].sw_freed = 1;
d668d9ba
SL
139 nblks = swdevt[index].sw_nblks;
140 for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
141 blk = nblks - dvbase;
142 if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
143 panic("swfree");
144 if (blk > dmmax)
145 blk = dmmax;
013037be
BJ
146 if (vsbase == 0) {
147 /*
148 * Can't free a block starting at 0 in the swapmap
c84ff1f9 149 * but need some space for argmap so use 1/2 this
013037be
BJ
150 * hunk which needs special treatment anyways.
151 */
152 argdev = swdevt[0].sw_dev;
e438ed8e
BJ
153 rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
154 (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
c84ff1f9
BJ
155 /*
156 * First of all chunks... initialize the swapmap
157 * the second half of the hunk.
158 */
a29f7995
BJ
159 rminit(swapmap, (long)blk/2, (long)blk/2,
160 "swap", nswapmap);
013037be 161 } else
c84ff1f9 162 rmfree(swapmap, blk, vsbase);
013037be
BJ
163 }
164}