get rid of extraneous header files
[unix-history] / usr / src / sys / vm / vm_swap.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
849cbd39 6 * @(#)vm_swap.c 7.4 (Berkeley) %G%
da7c5cc6 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"
ec67a3ce 19#include "stat.h"
609e7cfa 20#include "stat.h"
013037be 21
013037be
BJ
22/*
23 * Indirect driver for multi-controller paging.
24 */
25swstrategy(bp)
26 register struct buf *bp;
27{
ec67a3ce
MK
28 int sz, off, seg, index;
29 register struct swdevt *sp;
013037be 30
b9ee5d20
BJ
31#ifdef GENERIC
32 /*
33 * A mini-root gets copied into the front of the swap
34 * and we run over top of the swap area just long
35 * enough for us to do a mkfs and restor of the real
36 * root (sure beats rewriting standalone restor).
37 */
8c5046eb 38#define MINIROOTSIZE 4096
b9ee5d20
BJ
39 if (rootdev == dumpdev)
40 bp->b_blkno += MINIROOTSIZE;
41#endif
ca1f746a 42 sz = howmany(bp->b_bcount, DEV_BSIZE);
d668d9ba 43 if (bp->b_blkno+sz > nswap) {
013037be 44 bp->b_flags |= B_ERROR;
ec67a3ce 45 biodone(bp);
013037be
BJ
46 return;
47 }
d668d9ba
SL
48 if (nswdev > 1) {
49 off = bp->b_blkno % dmmax;
50 if (off+sz > dmmax) {
51 bp->b_flags |= B_ERROR;
ec67a3ce 52 biodone(bp);
d668d9ba
SL
53 return;
54 }
55 seg = bp->b_blkno / dmmax;
ec67a3ce 56 index = seg % nswdev;
d668d9ba
SL
57 seg /= nswdev;
58 bp->b_blkno = seg*dmmax + off;
59 } else
ec67a3ce
MK
60 index = 0;
61 sp = &swdevt[index];
62#ifdef SECSIZE
63 bp->b_blkno <<= sp->sw_bshift;
64 bp->b_blksize = sp->sw_blksize;
65#endif SECSIZE
66 bp->b_dev = sp->sw_dev;
67 if (bp->b_dev == 0)
013037be 68 panic("swstrategy");
ec67a3ce 69 (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
013037be
BJ
70}
71
013037be
BJ
72/*
73 * System call swapon(name) enables swapping on device name,
74 * which must be in the swdevsw. Return EBUSY
75 * if already swapping on this device.
76 */
2dfa06c1 77swapon()
013037be 78{
2dfa06c1
SL
79 struct a {
80 char *name;
715baff1 81 } *uap = (struct a *)u.u_ap;
013037be
BJ
82 register struct inode *ip;
83 dev_t dev;
84 register struct swdevt *sp;
715baff1 85 register struct nameidata *ndp = &u.u_nd;
013037be 86
849cbd39 87 if (u.u_error = suser(u.u_cred, &u.u_acflag))
dca9bb95 88 return;
715baff1
KM
89 ndp->ni_nameiop = LOOKUP | FOLLOW;
90 ndp->ni_segflg = UIO_USERSPACE;
91 ndp->ni_dirp = uap->name;
92 ip = namei(ndp);
013037be
BJ
93 if (ip == NULL)
94 return;
95 if ((ip->i_mode&IFMT) != IFBLK) {
96 u.u_error = ENOTBLK;
97 iput(ip);
98 return;
99 }
76e9203a 100 dev = (dev_t)ip->i_rdev;
013037be
BJ
101 iput(ip);
102 if (major(dev) >= nblkdev) {
103 u.u_error = ENXIO;
104 return;
105 }
ae0ffeb1 106 for (sp = &swdevt[0]; sp->sw_dev; sp++)
013037be
BJ
107 if (sp->sw_dev == dev) {
108 if (sp->sw_freed) {
109 u.u_error = EBUSY;
110 return;
111 }
ec67a3ce 112 u.u_error = swfree(sp - swdevt);
013037be
BJ
113 return;
114 }
ae0ffeb1 115 u.u_error = EINVAL;
013037be
BJ
116}
117
ec67a3ce
MK
118#ifdef SECSIZE
119long argdbsize; /* XXX */
120
121#endif SECSIZE
013037be
BJ
122/*
123 * Swfree(index) frees the index'th portion of the swap map.
124 * Each of the nswdev devices provides 1/nswdev'th of the swap
d668d9ba 125 * space, which is laid out with blocks of dmmax pages circularly
013037be
BJ
126 * among the devices.
127 */
128swfree(index)
129 int index;
130{
609e7cfa 131 register struct swdevt *sp;
ec67a3ce 132 register struct swdevt *sp;
013037be 133 register swblk_t vsbase;
39d536e6 134 register long blk;
e438ed8e 135 dev_t dev;
d668d9ba
SL
136 register swblk_t dvbase;
137 register int nblks;
ec67a3ce 138 int error;
609e7cfa 139 int error;
013037be 140
ec67a3ce
MK
141 sp = &swdevt[index];
142 dev = sp->sw_dev;
143 if (error = (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE, S_IFBLK))
144 return (error);
145 sp->sw_freed = 1;
146 nblks = sp->sw_nblks;
d668d9ba
SL
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 */
ec67a3ce
MK
159 argdev = sp->sw_dev;
160#ifdef SECSIZE
161 argdbsize = sp->sw_blksize;
162 rminit(argmap,
163 ((blk / 2) * DEV_BSIZE - CLBYTES) / argdbsize,
164 CLBYTES / argdbsize, "argmap", ARGMAPSIZE);
165#else SECSIZE
e438ed8e
BJ
166 rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
167 (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
ec67a3ce 168#endif SECSIZE
c84ff1f9
BJ
169 /*
170 * First of all chunks... initialize the swapmap
171 * the second half of the hunk.
172 */
a29f7995
BJ
173 rminit(swapmap, (long)blk/2, (long)blk/2,
174 "swap", nswapmap);
ec67a3ce
MK
175 } else if (dvbase == 0) {
176 /*
177 * Don't use the first cluster of the device
178 * in case it starts with a label or boot block.
179 */
180 rmfree(swapmap, blk - ctod(CLSIZE),
181 vsbase + ctod(CLSIZE));
609e7cfa
MK
182 } else if (dvbase == 0) {
183 /*
184 * Don't use the first cluster of the device
185 * in case it starts with a label or boot block.
186 */
187 rmfree(swapmap, blk - ctod(CLSIZE),
188 vsbase + ctod(CLSIZE));
013037be 189 } else
c84ff1f9 190 rmfree(swapmap, blk, vsbase);
013037be 191 }
ec67a3ce 192 return (0);
609e7cfa 193 return (0);
013037be 194}