reverse sense of pid/pgrp for fcntl, SIOCSPGRP (pgrp is negative)
[unix-history] / usr / src / sys / vm / vm_swap.c
CommitLineData
dca9bb95 1/* vm_swap.c 6.5 85/05/22 */
013037be 2
94368568
JB
3#include "param.h"
4#include "systm.h"
5#include "buf.h"
6#include "conf.h"
7#include "dir.h"
8#include "user.h"
9#include "inode.h"
10#include "map.h"
11#include "uio.h"
12#include "file.h"
013037be
BJ
13
14struct buf rswbuf;
15/*
16 * Indirect driver for multi-controller paging.
17 */
18swstrategy(bp)
19 register struct buf *bp;
20{
21 int sz, off, seg;
22 dev_t dev;
23
b9ee5d20
BJ
24#ifdef GENERIC
25 /*
26 * A mini-root gets copied into the front of the swap
27 * and we run over top of the swap area just long
28 * enough for us to do a mkfs and restor of the real
29 * root (sure beats rewriting standalone restor).
30 */
8c5046eb 31#define MINIROOTSIZE 4096
b9ee5d20
BJ
32 if (rootdev == dumpdev)
33 bp->b_blkno += MINIROOTSIZE;
34#endif
ca1f746a 35 sz = howmany(bp->b_bcount, DEV_BSIZE);
d668d9ba 36 if (bp->b_blkno+sz > nswap) {
013037be
BJ
37 bp->b_flags |= B_ERROR;
38 iodone(bp);
39 return;
40 }
d668d9ba
SL
41 if (nswdev > 1) {
42 off = bp->b_blkno % dmmax;
43 if (off+sz > dmmax) {
44 bp->b_flags |= B_ERROR;
45 iodone(bp);
46 return;
47 }
48 seg = bp->b_blkno / dmmax;
49 dev = swdevt[seg % nswdev].sw_dev;
50 seg /= nswdev;
51 bp->b_blkno = seg*dmmax + off;
52 } else
53 dev = swdevt[0].sw_dev;
013037be
BJ
54 bp->b_dev = dev;
55 if (dev == 0)
56 panic("swstrategy");
57 (*bdevsw[major(dev)].d_strategy)(bp);
58}
59
5699bf69
BJ
60swread(dev, uio)
61 dev_t dev;
62 struct uio *uio;
013037be
BJ
63{
64
30c36259 65 return (physio(swstrategy, &rswbuf, dev, B_READ, minphys, uio));
013037be
BJ
66}
67
5699bf69
BJ
68swwrite(dev, uio)
69 dev_t dev;
70 struct uio *uio;
013037be
BJ
71{
72
30c36259 73 return (physio(swstrategy, &rswbuf, dev, B_WRITE, minphys, uio));
013037be
BJ
74}
75
76/*
77 * System call swapon(name) enables swapping on device name,
78 * which must be in the swdevsw. Return EBUSY
79 * if already swapping on this device.
80 */
2dfa06c1 81swapon()
013037be 82{
2dfa06c1
SL
83 struct a {
84 char *name;
715baff1 85 } *uap = (struct a *)u.u_ap;
013037be
BJ
86 register struct inode *ip;
87 dev_t dev;
88 register struct swdevt *sp;
715baff1 89 register struct nameidata *ndp = &u.u_nd;
013037be 90
dca9bb95
KM
91 if (!suser())
92 return;
715baff1
KM
93 ndp->ni_nameiop = LOOKUP | FOLLOW;
94 ndp->ni_segflg = UIO_USERSPACE;
95 ndp->ni_dirp = uap->name;
96 ip = namei(ndp);
013037be
BJ
97 if (ip == NULL)
98 return;
99 if ((ip->i_mode&IFMT) != IFBLK) {
100 u.u_error = ENOTBLK;
101 iput(ip);
102 return;
103 }
76e9203a 104 dev = (dev_t)ip->i_rdev;
013037be
BJ
105 iput(ip);
106 if (major(dev) >= nblkdev) {
107 u.u_error = ENXIO;
108 return;
109 }
ae0ffeb1 110 for (sp = &swdevt[0]; sp->sw_dev; sp++)
013037be
BJ
111 if (sp->sw_dev == dev) {
112 if (sp->sw_freed) {
113 u.u_error = EBUSY;
114 return;
115 }
116 swfree(sp - swdevt);
117 return;
118 }
ae0ffeb1 119 u.u_error = EINVAL;
013037be
BJ
120}
121
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{
131 register swblk_t vsbase;
39d536e6 132 register long blk;
e438ed8e 133 dev_t dev;
d668d9ba
SL
134 register swblk_t dvbase;
135 register int nblks;
013037be 136
e438ed8e
BJ
137 dev = swdevt[index].sw_dev;
138 (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE);
013037be 139 swdevt[index].sw_freed = 1;
d668d9ba
SL
140 nblks = swdevt[index].sw_nblks;
141 for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
142 blk = nblks - dvbase;
143 if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
144 panic("swfree");
145 if (blk > dmmax)
146 blk = dmmax;
013037be
BJ
147 if (vsbase == 0) {
148 /*
149 * Can't free a block starting at 0 in the swapmap
c84ff1f9 150 * but need some space for argmap so use 1/2 this
013037be
BJ
151 * hunk which needs special treatment anyways.
152 */
153 argdev = swdevt[0].sw_dev;
e438ed8e
BJ
154 rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
155 (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
c84ff1f9
BJ
156 /*
157 * First of all chunks... initialize the swapmap
158 * the second half of the hunk.
159 */
a29f7995
BJ
160 rminit(swapmap, (long)blk/2, (long)blk/2,
161 "swap", nswapmap);
013037be 162 } else
c84ff1f9 163 rmfree(swapmap, blk, vsbase);
013037be
BJ
164 }
165}