break out unmounting part so it can be used by mfs
[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 *
5172d628 17 * @(#)mfs_vnops.c 7.2 (Berkeley) %G%
a3017777
KM
18 */
19
20#include "param.h"
21#include "time.h"
22#include "proc.h"
23#include "buf.h"
24#include "vmmac.h"
25#include "errno.h"
26#include "map.h"
27#include "vnode.h"
28#include "../ufs/inode.h"
29#include "../ufs/mfsiom.h"
30#include "../machine/vmparam.h"
31#include "../machine/pte.h"
32#include "../machine/mtpr.h"
33
a3017777
KM
34static int mfsmap_want; /* 1 => need kernel I/O resources */
35struct map mfsmap[MFS_MAPSIZE];
36extern char mfsiobuf[];
37
38/*
39 * mfs vnode operations.
40 */
41int mfs_open(),
42 mfs_strategy(),
43 mfs_ioctl(),
44 mfs_close(),
45 ufs_inactive(),
46 mfs_badop(),
47 mfs_nullop();
48
49struct vnodeops mfs_vnodeops = {
50 mfs_badop,
51 mfs_badop,
52 mfs_badop,
53 mfs_open,
54 mfs_close,
55 mfs_badop,
56 mfs_badop,
57 mfs_badop,
58 mfs_badop,
59 mfs_badop,
60 mfs_ioctl,
61 mfs_badop,
62 mfs_badop,
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 ufs_inactive,
75 mfs_badop,
76 mfs_badop,
77 mfs_badop,
78 mfs_strategy,
79};
80
81/*
82 * Vnode Operations.
83 *
84 * Open called to allow memory filesystem to initialize and
85 * validate before actual IO. Nothing to do here as the
86 * filesystem is ready to go in the process address space.
87 */
88/* ARGSUSED */
89mfs_open(vp, mode, cred)
90 register struct vnode *vp;
91 int mode;
92 struct ucred *cred;
93{
94
95 if (vp->v_type != VBLK) {
96 panic("mfs_ioctl not VBLK");
97 /* NOTREACHED */
98 }
99 return (0);
100}
101
102/*
103 * Ioctl operation.
104 */
105/* ARGSUSED */
106mfs_ioctl(vp, com, data, fflag, cred)
107 struct vnode *vp;
108 int com;
109 caddr_t data;
110 int fflag;
111 struct ucred *cred;
112{
113
114 return (-1);
115}
116
117/*
118 * Pass I/O requests to the memory filesystem process.
119 */
120mfs_strategy(bp)
121 register struct buf *bp;
122{
123 register struct inode *ip = VTOI(bp->b_vp);
124 int error;
125
126 ILOCK(ip);
5172d628 127 if (bp->b_vp->v_mount == NULL) {
a3017777
KM
128 mfs_doio(bp, (caddr_t)ip->i_diroff);
129 } else {
130 ip->i_spare[0] = (long)bp;
131 wakeup((caddr_t)bp->b_vp);
132 }
133 error = biowait(bp);
134 IUNLOCK(ip);
135 return (error);
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{
222 register struct inode *ip = VTOI(vp);
223
224 /*
225 * On last close of a memory filesystem
226 * we must invalidate any in core blocks, so that
227 * we can, free up its vnode.
228 */
229 bflush(vp->v_mount);
230 if (binval(vp->v_mount))
231 return (0);
232 /*
233 * We don't want to really close the device if it is still
234 * in use. Since every use (buffer, inode, swap, cmap)
235 * holds a reference to the vnode, and because we ensure
236 * that there cannot be more than one vnode per device,
237 * we need only check that we are down to the last
238 * reference before closing.
239 */
240 if (vp->v_count > 1) {
241 printf("mfs_close: ref count %d > 1\n", vp->v_count);
242 return (0);
243 }
244 /*
245 * Send a request to the filesystem server to exit.
246 */
247 ILOCK(ip);
248 ip->i_spare[0] = 0;
249 wakeup((caddr_t)vp);
250 IUNLOCK(ip);
251 return (0);
252}
253
254/*
255 * Block device bad operation
256 */
257mfs_badop()
258{
259
260 printf("mfs_badop called\n");
261 return (ENXIO);
262}
263
264/*
265 * Block device null operation
266 */
267mfs_nullop()
268{
269
270 return (0);
271}
272
273/*
274 * Memory based filesystem initialization.
275 */
276mfs_init()
277{
278
279 rminit(mfsmap, (long)MFS_MAPREG, (long)1, "mfs mapreg", MFS_MAPSIZE);
280}