Add copyright
[unix-history] / usr / src / sys / vm / vm_swap.c
CommitLineData
da7c5cc6
KM
1/*
2 * Copyright (c) 1982 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_swap.c 6.6 (Berkeley) %G%
7 */
013037be 8
94368568
JB
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"
013037be
BJ
19
20struct buf rswbuf;
21/*
22 * Indirect driver for multi-controller paging.
23 */
24swstrategy(bp)
25 register struct buf *bp;
26{
27 int sz, off, seg;
28 dev_t dev;
29
b9ee5d20
BJ
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 */
8c5046eb 37#define MINIROOTSIZE 4096
b9ee5d20
BJ
38 if (rootdev == dumpdev)
39 bp->b_blkno += MINIROOTSIZE;
40#endif
ca1f746a 41 sz = howmany(bp->b_bcount, DEV_BSIZE);
d668d9ba 42 if (bp->b_blkno+sz > nswap) {
013037be
BJ
43 bp->b_flags |= B_ERROR;
44 iodone(bp);
45 return;
46 }
d668d9ba
SL
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;
013037be
BJ
60 bp->b_dev = dev;
61 if (dev == 0)
62 panic("swstrategy");
63 (*bdevsw[major(dev)].d_strategy)(bp);
64}
65
5699bf69
BJ
66swread(dev, uio)
67 dev_t dev;
68 struct uio *uio;
013037be
BJ
69{
70
30c36259 71 return (physio(swstrategy, &rswbuf, dev, B_READ, minphys, uio));
013037be
BJ
72}
73
5699bf69
BJ
74swwrite(dev, uio)
75 dev_t dev;
76 struct uio *uio;
013037be
BJ
77{
78
30c36259 79 return (physio(swstrategy, &rswbuf, dev, B_WRITE, minphys, uio));
013037be
BJ
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 */
2dfa06c1 87swapon()
013037be 88{
2dfa06c1
SL
89 struct a {
90 char *name;
715baff1 91 } *uap = (struct a *)u.u_ap;
013037be
BJ
92 register struct inode *ip;
93 dev_t dev;
94 register struct swdevt *sp;
715baff1 95 register struct nameidata *ndp = &u.u_nd;
013037be 96
dca9bb95
KM
97 if (!suser())
98 return;
715baff1
KM
99 ndp->ni_nameiop = LOOKUP | FOLLOW;
100 ndp->ni_segflg = UIO_USERSPACE;
101 ndp->ni_dirp = uap->name;
102 ip = namei(ndp);
013037be
BJ
103 if (ip == NULL)
104 return;
105 if ((ip->i_mode&IFMT) != IFBLK) {
106 u.u_error = ENOTBLK;
107 iput(ip);
108 return;
109 }
76e9203a 110 dev = (dev_t)ip->i_rdev;
013037be
BJ
111 iput(ip);
112 if (major(dev) >= nblkdev) {
113 u.u_error = ENXIO;
114 return;
115 }
ae0ffeb1 116 for (sp = &swdevt[0]; sp->sw_dev; sp++)
013037be
BJ
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 }
ae0ffeb1 125 u.u_error = EINVAL;
013037be
BJ
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
d668d9ba 131 * space, which is laid out with blocks of dmmax pages circularly
013037be
BJ
132 * among the devices.
133 */
134swfree(index)
135 int index;
136{
137 register swblk_t vsbase;
39d536e6 138 register long blk;
e438ed8e 139 dev_t dev;
d668d9ba
SL
140 register swblk_t dvbase;
141 register int nblks;
013037be 142
e438ed8e
BJ
143 dev = swdevt[index].sw_dev;
144 (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE);
013037be 145 swdevt[index].sw_freed = 1;
d668d9ba
SL
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;
013037be
BJ
153 if (vsbase == 0) {
154 /*
155 * Can't free a block starting at 0 in the swapmap
c84ff1f9 156 * but need some space for argmap so use 1/2 this
013037be
BJ
157 * hunk which needs special treatment anyways.
158 */
159 argdev = swdevt[0].sw_dev;
e438ed8e
BJ
160 rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
161 (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
c84ff1f9
BJ
162 /*
163 * First of all chunks... initialize the swapmap
164 * the second half of the hunk.
165 */
a29f7995
BJ
166 rminit(swapmap, (long)blk/2, (long)blk/2,
167 "swap", nswapmap);
013037be 168 } else
c84ff1f9 169 rmfree(swapmap, blk, vsbase);
013037be
BJ
170 }
171}