|
|
1.1 root 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, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)mfs_vnops.c 7.22 (Berkeley) 4/16/91
34: */
35:
36: #include "param.h"
37: #include "systm.h"
38: #include "time.h"
39: #include "kernel.h"
40: #include "proc.h"
41: #include "buf.h"
42: #include "map.h"
43: #include "vnode.h"
44:
45: #include "mfsnode.h"
46: #include "mfsiom.h"
47:
48: #include "machine/vmparam.h"
49: #include "machine/mtpr.h"
50:
51: #if !defined(hp300) && !defined(i386)
52: static int mfsmap_want; /* 1 => need kernel I/O resources */
53: struct map mfsmap[MFS_MAPSIZE];
54: extern char mfsiobuf[];
55: #endif
56:
57: /*
58: * mfs vnode operations.
59: */
60: struct vnodeops mfs_vnodeops = {
61: mfs_lookup, /* lookup */
62: mfs_create, /* create */
63: mfs_mknod, /* mknod */
64: mfs_open, /* open */
65: mfs_close, /* close */
66: mfs_access, /* access */
67: mfs_getattr, /* getattr */
68: mfs_setattr, /* setattr */
69: mfs_read, /* read */
70: mfs_write, /* write */
71: mfs_ioctl, /* ioctl */
72: mfs_select, /* select */
73: mfs_mmap, /* mmap */
74: mfs_fsync, /* fsync */
75: mfs_seek, /* seek */
76: mfs_remove, /* remove */
77: mfs_link, /* link */
78: mfs_rename, /* rename */
79: mfs_mkdir, /* mkdir */
80: mfs_rmdir, /* rmdir */
81: mfs_symlink, /* symlink */
82: mfs_readdir, /* readdir */
83: mfs_readlink, /* readlink */
84: mfs_abortop, /* abortop */
85: mfs_inactive, /* inactive */
86: mfs_reclaim, /* reclaim */
87: mfs_lock, /* lock */
88: mfs_unlock, /* unlock */
89: mfs_bmap, /* bmap */
90: mfs_strategy, /* strategy */
91: mfs_print, /* print */
92: mfs_islocked, /* islocked */
93: mfs_advlock, /* advlock */
94: };
95:
96: /*
97: * Vnode Operations.
98: *
99: * Open called to allow memory filesystem to initialize and
100: * validate before actual IO. Record our process identifier
101: * so we can tell when we are doing I/O to ourself.
102: */
103: /* ARGSUSED */
104: mfs_open(vp, mode, cred, p)
105: register struct vnode *vp;
106: int mode;
107: struct ucred *cred;
108: struct proc *p;
109: {
110:
111: if (vp->v_type != VBLK) {
112: panic("mfs_ioctl not VBLK");
113: /* NOTREACHED */
114: }
115: return (0);
116: }
117:
118: /*
119: * Ioctl operation.
120: */
121: /* ARGSUSED */
122: mfs_ioctl(vp, com, data, fflag, cred, p)
123: struct vnode *vp;
124: int com;
125: caddr_t data;
126: int fflag;
127: struct ucred *cred;
128: struct proc *p;
129: {
130:
131: return (-1);
132: }
133:
134: /*
135: * Pass I/O requests to the memory filesystem process.
136: */
137: mfs_strategy(bp)
138: register struct buf *bp;
139: {
140: register struct mfsnode *mfsp;
141: struct vnode *vp;
142: struct proc *p = curproc; /* XXX */
143:
144: if (vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0)
145: panic("mfs_strategy: bad dev");
146: mfsp = VTOMFS(vp);
147: if (mfsp->mfs_pid == p->p_pid) {
148: mfs_doio(bp, mfsp->mfs_baseoff);
149: } else {
150: bp->av_forw = mfsp->mfs_buflist;
151: mfsp->mfs_buflist = bp;
152: wakeup((caddr_t)vp);
153: }
154: return (0);
155: }
156:
157: #if defined(vax) || defined(tahoe)
158: /*
159: * Memory file system I/O.
160: *
161: * Essentially play ubasetup() and disk interrupt service routine by
162: * doing the copies to or from the memfs process. If doing physio
163: * (i.e. pagein), we must map the I/O through the kernel virtual
164: * address space.
165: */
166: mfs_doio(bp, base)
167: register struct buf *bp;
168: caddr_t base;
169: {
170: register struct pte *pte, *ppte;
171: register caddr_t vaddr;
172: int off, npf, npf2, reg;
173: caddr_t kernaddr, offset;
174:
175: /*
176: * For phys I/O, map the b_addr into kernel virtual space using
177: * the Mfsiomap pte's.
178: */
179: if ((bp->b_flags & B_PHYS) == 0) {
180: kernaddr = bp->b_un.b_addr;
181: } else {
182: if (bp->b_flags & (B_PAGET | B_UAREA | B_DIRTY))
183: panic("swap on memfs?");
184: off = (int)bp->b_un.b_addr & PGOFSET;
185: npf = btoc(bp->b_bcount + off);
186: /*
187: * Get some mapping page table entries
188: */
189: while ((reg = rmalloc(mfsmap, (long)npf)) == 0) {
190: mfsmap_want++;
191: sleep((caddr_t)&mfsmap_want, PZERO-1);
192: }
193: reg--;
194: pte = vtopte(bp->b_proc, btop(bp->b_un.b_addr));
195: /*
196: * Do vmaccess() but with the Mfsiomap page table.
197: */
198: ppte = &Mfsiomap[reg];
199: vaddr = &mfsiobuf[reg * NBPG];
200: kernaddr = vaddr + off;
201: for (npf2 = npf; npf2; npf2--) {
202: mapin(ppte, (u_int)vaddr, pte->pg_pfnum,
203: (int)(PG_V|PG_KW));
204: #if defined(tahoe)
205: if ((bp->b_flags & B_READ) == 0)
206: mtpr(P1DC, vaddr);
207: #endif
208: ppte++;
209: pte++;
210: vaddr += NBPG;
211: }
212: }
213: offset = base + (bp->b_blkno << DEV_BSHIFT);
214: if (bp->b_flags & B_READ)
215: bp->b_error = copyin(offset, kernaddr, bp->b_bcount);
216: else
217: bp->b_error = copyout(kernaddr, offset, bp->b_bcount);
218: if (bp->b_error)
219: bp->b_flags |= B_ERROR;
220: /*
221: * Release pte's used by physical I/O.
222: */
223: if (bp->b_flags & B_PHYS) {
224: rmfree(mfsmap, (long)npf, (long)++reg);
225: if (mfsmap_want) {
226: mfsmap_want = 0;
227: wakeup((caddr_t)&mfsmap_want);
228: }
229: }
230: biodone(bp);
231: }
232: #endif /* vax || tahoe */
233:
234: #if defined(hp300) || defined(i386)
235: /*
236: * Memory file system I/O.
237: *
238: * Trivial on the HP since buffer has already been mapping into KVA space.
239: */
240: mfs_doio(bp, base)
241: register struct buf *bp;
242: caddr_t base;
243: {
244: base += (bp->b_blkno << DEV_BSHIFT);
245: if (bp->b_flags & B_READ)
246: bp->b_error = copyin(base, bp->b_un.b_addr, bp->b_bcount);
247: else
248: bp->b_error = copyout(bp->b_un.b_addr, base, bp->b_bcount);
249: if (bp->b_error)
250: bp->b_flags |= B_ERROR;
251: biodone(bp);
252: }
253: #endif
254:
255: /*
256: * This is a noop, simply returning what one has been given.
257: */
258: mfs_bmap(vp, bn, vpp, bnp)
259: struct vnode *vp;
260: daddr_t bn;
261: struct vnode **vpp;
262: daddr_t *bnp;
263: {
264:
265: if (vpp != NULL)
266: *vpp = vp;
267: if (bnp != NULL)
268: *bnp = bn;
269: return (0);
270: }
271:
272: /*
273: * Memory filesystem close routine
274: */
275: /* ARGSUSED */
276: mfs_close(vp, flag, cred, p)
277: register struct vnode *vp;
278: int flag;
279: struct ucred *cred;
280: struct proc *p;
281: {
282: register struct mfsnode *mfsp = VTOMFS(vp);
283: register struct buf *bp;
284:
285: /*
286: * Finish any pending I/O requests.
287: */
288: while (bp = mfsp->mfs_buflist) {
289: mfsp->mfs_buflist = bp->av_forw;
290: mfs_doio(bp, mfsp->mfs_baseoff);
291: wakeup((caddr_t)bp);
292: }
293: /*
294: * On last close of a memory filesystem
295: * we must invalidate any in core blocks, so that
296: * we can, free up its vnode.
297: */
298: vflushbuf(vp, 0);
299: if (vinvalbuf(vp, 1))
300: return (0);
301: /*
302: * There should be no way to have any more uses of this
303: * vnode, so if we find any other uses, it is a panic.
304: */
305: if (vp->v_usecount > 1)
306: printf("mfs_close: ref count %d > 1\n", vp->v_usecount);
307: if (vp->v_usecount > 1 || mfsp->mfs_buflist)
308: panic("mfs_close");
309: /*
310: * Send a request to the filesystem server to exit.
311: */
312: mfsp->mfs_buflist = (struct buf *)(-1);
313: wakeup((caddr_t)vp);
314: return (0);
315: }
316:
317: /*
318: * Memory filesystem inactive routine
319: */
320: /* ARGSUSED */
321: mfs_inactive(vp, p)
322: struct vnode *vp;
323: struct proc *p;
324: {
325:
326: if (VTOMFS(vp)->mfs_buflist != (struct buf *)(-1))
327: panic("mfs_inactive: not inactive");
328: return (0);
329: }
330:
331: /*
332: * Print out the contents of an mfsnode.
333: */
334: mfs_print(vp)
335: struct vnode *vp;
336: {
337: register struct mfsnode *mfsp = VTOMFS(vp);
338:
339: printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp->mfs_pid,
340: mfsp->mfs_baseoff, mfsp->mfs_size);
341: }
342:
343: /*
344: * Block device bad operation
345: */
346: mfs_badop()
347: {
348:
349: panic("mfs_badop called\n");
350: /* NOTREACHED */
351: }
352:
353: /*
354: * Memory based filesystem initialization.
355: */
356: mfs_init()
357: {
358:
359: #if !defined(hp300) && !defined(i386)
360: rminit(mfsmap, (long)MFS_MAPREG, (long)1, "mfs mapreg", MFS_MAPSIZE);
361: #endif
362: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.