../machine should be machine
[unix-history] / usr / src / sys / ufs / mfs / mfs_vnops.c
CommitLineData
a3017777
KM
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
f317c143 17 * @(#)mfs_vnops.c 7.7 (Berkeley) %G%
a3017777
KM
18 */
19
20#include "param.h"
21#include "time.h"
ba72b75d 22#include "kernel.h"
a3017777 23#include "proc.h"
ba72b75d 24#include "user.h"
a3017777
KM
25#include "buf.h"
26#include "vmmac.h"
27#include "errno.h"
28#include "map.h"
29#include "vnode.h"
a3e73aa4 30#include "../ufs/mfsnode.h"
a3017777 31#include "../ufs/mfsiom.h"
f317c143
KM
32#include "machine/vmparam.h"
33#include "machine/pte.h"
34#include "machine/mtpr.h"
a3017777 35
a3017777
KM
36static int mfsmap_want; /* 1 => need kernel I/O resources */
37struct map mfsmap[MFS_MAPSIZE];
38extern char mfsiobuf[];
39
40/*
41 * mfs vnode operations.
42 */
43int mfs_open(),
44 mfs_strategy(),
45 mfs_ioctl(),
46 mfs_close(),
a3e73aa4 47 mfs_inactive(),
a3017777
KM
48 mfs_badop(),
49 mfs_nullop();
50
51struct vnodeops mfs_vnodeops = {
52 mfs_badop,
53 mfs_badop,
54 mfs_badop,
55 mfs_open,
56 mfs_close,
57 mfs_badop,
58 mfs_badop,
59 mfs_badop,
60 mfs_badop,
61 mfs_badop,
62 mfs_ioctl,
63 mfs_badop,
64 mfs_badop,
65 mfs_badop,
66 mfs_badop,
67 mfs_badop,
68 mfs_badop,
69 mfs_badop,
70 mfs_badop,
71 mfs_badop,
72 mfs_badop,
73 mfs_badop,
74 mfs_badop,
75 mfs_badop,
a3e73aa4
KM
76 mfs_inactive,
77 mfs_nullop,
a3017777
KM
78 mfs_badop,
79 mfs_badop,
80 mfs_badop,
81 mfs_strategy,
82};
83
84/*
85 * Vnode Operations.
86 *
87 * Open called to allow memory filesystem to initialize and
ba72b75d
KM
88 * validate before actual IO. Record our process identifier
89 * so we can tell when we are doing I/O to ourself.
a3017777
KM
90 */
91/* ARGSUSED */
92mfs_open(vp, mode, cred)
93 register struct vnode *vp;
94 int mode;
95 struct ucred *cred;
96{
97
98 if (vp->v_type != VBLK) {
99 panic("mfs_ioctl not VBLK");
100 /* NOTREACHED */
101 }
102 return (0);
103}
104
105/*
106 * Ioctl operation.
107 */
108/* ARGSUSED */
109mfs_ioctl(vp, com, data, fflag, cred)
110 struct vnode *vp;
111 int com;
112 caddr_t data;
113 int fflag;
114 struct ucred *cred;
115{
116
117 return (-1);
118}
119
120/*
121 * Pass I/O requests to the memory filesystem process.
122 */
123mfs_strategy(bp)
124 register struct buf *bp;
125{
a3e73aa4 126 register struct mfsnode *mfsp = VTOMFS(bp->b_vp);
a3017777 127
a3e73aa4
KM
128 if (mfsp->mfs_pid == u.u_procp->p_pid) {
129 mfs_doio(bp, mfsp->mfs_baseoff);
a3017777 130 } else {
a3e73aa4
KM
131 bp->av_forw = mfsp->mfs_buflist;
132 mfsp->mfs_buflist = bp;
a3017777
KM
133 wakeup((caddr_t)bp->b_vp);
134 }
ba72b75d 135 return (0);
a3017777
KM
136}
137
138/*
139 * Memory file system I/O.
140 *
141 * Essentially play ubasetup() and disk interrupt service routine by
142 * doing the copies to or from the memfs process. If doing physio
143 * (i.e. pagein), we must map the I/O through the kernel virtual
144 * address space.
145 */
146mfs_doio(bp, base)
147 register struct buf *bp;
148 caddr_t base;
149{
150 register struct pte *pte, *ppte;
151 register caddr_t vaddr;
152 int off, npf, npf2, reg;
153 caddr_t kernaddr, offset;
154
155 /*
156 * For phys I/O, map the b_addr into kernel virtual space using
157 * the Mfsiomap pte's.
158 */
159 if ((bp->b_flags & B_PHYS) == 0) {
160 kernaddr = bp->b_un.b_addr;
161 } else {
162 if (bp->b_flags & (B_PAGET | B_UAREA | B_DIRTY))
163 panic("swap on memfs?");
164 off = (int)bp->b_un.b_addr & PGOFSET;
165 npf = btoc(bp->b_bcount + off);
166 /*
167 * Get some mapping page table entries
168 */
169 while ((reg = rmalloc(mfsmap, (long)npf)) == 0) {
170 mfsmap_want++;
171 sleep((caddr_t)&mfsmap_want, PZERO-1);
172 }
173 reg--;
174 pte = vtopte(bp->b_proc, btop(bp->b_un.b_addr));
175 /*
176 * Do vmaccess() but with the Mfsiomap page table.
177 */
178 ppte = &Mfsiomap[reg];
179 vaddr = &mfsiobuf[reg * NBPG];
180 kernaddr = vaddr + off;
181 for (npf2 = npf; npf2; npf2--) {
182 mapin(ppte, (u_int)vaddr, pte->pg_pfnum,
183 (int)(PG_V|PG_KW));
184#if defined(tahoe)
185 if ((bp->b_flags & B_READ) == 0)
186 mtpr(P1DC, vaddr);
187#endif
188 ppte++;
189 pte++;
190 vaddr += NBPG;
191 }
192 }
193 offset = base + (bp->b_blkno << DEV_BSHIFT);
194 if (bp->b_flags & B_READ)
195 bp->b_error = copyin(offset, kernaddr, bp->b_bcount);
196 else
197 bp->b_error = copyout(kernaddr, offset, bp->b_bcount);
198 if (bp->b_error)
199 bp->b_flags |= B_ERROR;
200 /*
201 * Release pte's used by physical I/O.
202 */
203 if (bp->b_flags & B_PHYS) {
204 rmfree(mfsmap, (long)npf, (long)++reg);
205 if (mfsmap_want) {
206 mfsmap_want = 0;
207 wakeup((caddr_t)&mfsmap_want);
208 }
209 }
210 biodone(bp);
211}
212
213/*
214 * Memory filesystem close routine
215 */
216/* ARGSUSED */
217mfs_close(vp, flag, cred)
218 register struct vnode *vp;
219 int flag;
220 struct ucred *cred;
221{
a3e73aa4 222 register struct mfsnode *mfsp = VTOMFS(vp);
5350b6c1 223 register struct buf *bp;
a3017777 224
5350b6c1
KM
225 /*
226 * Finish any pending I/O requests.
227 */
228 while (bp = mfsp->mfs_buflist) {
229 mfsp->mfs_buflist = bp->av_forw;
230 mfs_doio(bp, mfsp->mfs_baseoff);
231 wakeup((caddr_t)bp);
232 }
a3017777
KM
233 /*
234 * On last close of a memory filesystem
235 * we must invalidate any in core blocks, so that
236 * we can, free up its vnode.
237 */
238 bflush(vp->v_mount);
239 if (binval(vp->v_mount))
240 return (0);
241 /*
5350b6c1
KM
242 * There should be no way to have any more uses of this
243 * vnode, so if we find any other uses, it is a panic.
a3017777 244 */
5350b6c1 245 if (vp->v_count > 1)
a3017777 246 printf("mfs_close: ref count %d > 1\n", vp->v_count);
5350b6c1
KM
247 if (vp->v_count > 1 || mfsp->mfs_buflist)
248 panic("mfs_close");
a3017777
KM
249 /*
250 * Send a request to the filesystem server to exit.
251 */
a3e73aa4 252 mfsp->mfs_buflist = (struct buf *)(-1);
a3017777 253 wakeup((caddr_t)vp);
a3017777
KM
254 return (0);
255}
256
a3e73aa4
KM
257/*
258 * Memory filesystem inactive routine
259 */
260/* ARGSUSED */
261mfs_inactive(vp)
262 struct vnode *vp;
263{
264
265 if (VTOMFS(vp)->mfs_buflist != (struct buf *)(-1))
266 panic("mfs_inactive: not inactive");
a3e73aa4
KM
267 return (0);
268}
269
a3017777
KM
270/*
271 * Block device bad operation
272 */
273mfs_badop()
274{
275
a3e73aa4
KM
276 panic("mfs_badop called\n");
277 /* NOTREACHED */
a3017777
KM
278}
279
280/*
281 * Block device null operation
282 */
283mfs_nullop()
284{
285
286 return (0);
287}
288
289/*
290 * Memory based filesystem initialization.
291 */
292mfs_init()
293{
294
295 rminit(mfsmap, (long)MFS_MAPREG, (long)1, "mfs mapreg", MFS_MAPSIZE);
296}