]> git.saurik.com Git - apple/xnu.git/blob - bsd/ufs/mfs/mfs_vnops.c
xnu-344.23.tar.gz
[apple/xnu.git] / bsd / ufs / mfs / mfs_vnops.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /* $NetBSD: mfs_vnops.c,v 1.5 1994/12/14 13:03:52 mycroft Exp $ */
23
24 /*
25 * Copyright (c) 1989, 1993
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 *
56 * @(#)mfs_vnops.c 8.5 (Berkeley) 7/28/94
57 */
58
59 #include <sys/param.h>
60 #include <sys/systm.h>
61 #include <sys/time.h>
62 #include <sys/kernel.h>
63 #include <sys/proc.h>
64 #include <sys/buf.h>
65 #include <sys/map.h>
66 #include <sys/vnode.h>
67 #include <sys/malloc.h>
68
69 #include <miscfs/specfs/specdev.h>
70
71 #include <machine/vmparam.h>
72
73 #include <ufs/mfs/mfsnode.h>
74 #include <ufs/mfs/mfsiom.h>
75 #include <ufs/mfs/mfs_extern.h>
76
77 /*
78 * mfs vnode operations.
79 */
80
81 #define VOPFUNC int (*)(void *)
82
83 int (**mfs_vnodeop_p)(void *);
84 struct vnodeopv_entry_desc mfs_vnodeop_entries[] = {
85 { &vop_default_desc, (VOPFUNC)vn_default_error },
86 { &vop_lookup_desc, (VOPFUNC)mfs_lookup }, /* lookup */
87 { &vop_create_desc, (VOPFUNC)mfs_create }, /* create */
88 { &vop_mknod_desc, (VOPFUNC)mfs_mknod }, /* mknod */
89 { &vop_open_desc, (VOPFUNC)mfs_open }, /* open */
90 { &vop_close_desc, (VOPFUNC)mfs_close }, /* close */
91 { &vop_access_desc, (VOPFUNC)mfs_access }, /* access */
92 { &vop_getattr_desc, (VOPFUNC)mfs_getattr }, /* getattr */
93 { &vop_setattr_desc, (VOPFUNC)mfs_setattr }, /* setattr */
94 { &vop_read_desc, (VOPFUNC)mfs_read }, /* read */
95 { &vop_write_desc, (VOPFUNC)mfs_write }, /* write */
96 { &vop_ioctl_desc, (VOPFUNC)mfs_ioctl }, /* ioctl */
97 { &vop_select_desc, (VOPFUNC)mfs_select }, /* select */
98 { &vop_mmap_desc, (VOPFUNC)mfs_mmap }, /* mmap */
99 { &vop_fsync_desc, (VOPFUNC)spec_fsync }, /* fsync */
100 { &vop_seek_desc, (VOPFUNC)mfs_seek }, /* seek */
101 { &vop_remove_desc, (VOPFUNC)mfs_remove }, /* remove */
102 { &vop_link_desc, (VOPFUNC)mfs_link }, /* link */
103 { &vop_rename_desc, (VOPFUNC)mfs_rename }, /* rename */
104 { &vop_mkdir_desc, (VOPFUNC)mfs_mkdir }, /* mkdir */
105 { &vop_rmdir_desc, (VOPFUNC)mfs_rmdir }, /* rmdir */
106 { &vop_symlink_desc, (VOPFUNC)mfs_symlink }, /* symlink */
107 { &vop_readdir_desc, (VOPFUNC)mfs_readdir }, /* readdir */
108 { &vop_readlink_desc, (VOPFUNC)mfs_readlink }, /* readlink */
109 { &vop_abortop_desc, (VOPFUNC)mfs_abortop }, /* abortop */
110 { &vop_inactive_desc, (VOPFUNC)mfs_inactive }, /* inactive */
111 { &vop_reclaim_desc, (VOPFUNC)mfs_reclaim }, /* reclaim */
112 { &vop_lock_desc, (VOPFUNC)mfs_lock }, /* lock */
113 { &vop_unlock_desc, (VOPFUNC)mfs_unlock }, /* unlock */
114 { &vop_bmap_desc, (VOPFUNC)mfs_bmap }, /* bmap */
115 { &vop_strategy_desc, (VOPFUNC)mfs_strategy }, /* strategy */
116 { &vop_print_desc, (VOPFUNC)mfs_print }, /* print */
117 { &vop_islocked_desc, (VOPFUNC)mfs_islocked }, /* islocked */
118 { &vop_pathconf_desc, (VOPFUNC)mfs_pathconf }, /* pathconf */
119 { &vop_advlock_desc, (VOPFUNC)mfs_advlock }, /* advlock */
120 { &vop_blkatoff_desc, (VOPFUNC)mfs_blkatoff }, /* blkatoff */
121 { &vop_valloc_desc, (VOPFUNC)mfs_valloc }, /* valloc */
122 { &vop_vfree_desc, (VOPFUNC)mfs_vfree }, /* vfree */
123 { &vop_truncate_desc, (VOPFUNC)mfs_truncate }, /* truncate */
124 { &vop_update_desc, (VOPFUNC)mfs_update }, /* update */
125 { &vop_bwrite_desc, (VOPFUNC)mfs_bwrite }, /* bwrite */
126 { &vop_pgrd_desc, (VOPFUNC)mfs_pgrg }, /* pager read */
127 { &vop_pgwr_desc, (VOPFUNC)mfs_pgwr }, /* pager write */
128 { (struct vnodeop_desc*)NULL, (int(*)())NULL }
129 };
130 struct vnodeopv_desc mfs_vnodeop_opv_desc =
131 { &mfs_vnodeop_p, mfs_vnodeop_entries };
132
133 /*
134 * Vnode Operations.
135 *
136 * Open called to allow memory filesystem to initialize and
137 * validate before actual IO. Record our process identifier
138 * so we can tell when we are doing I/O to ourself.
139 */
140 /* ARGSUSED */
141 int
142 mfs_open(ap)
143 struct vop_open_args /* {
144 struct vnode *a_vp;
145 int a_mode;
146 struct ucred *a_cred;
147 struct proc *a_p;
148 } */ *ap;
149 {
150
151 if (ap->a_vp->v_type != VBLK) {
152 panic("mfs_ioctl not VBLK");
153 /* NOTREACHED */
154 }
155 return (0);
156 }
157
158 /*
159 * Ioctl operation.
160 */
161 /* ARGSUSED */
162 int
163 mfs_ioctl(ap)
164 struct vop_ioctl_args /* {
165 struct vnode *a_vp;
166 u_long a_command;
167 caddr_t a_data;
168 int a_fflag;
169 struct ucred *a_cred;
170 struct proc *a_p;
171 } */ *ap;
172 {
173
174 return (ENOTTY);
175 }
176
177 /*
178 * Pass I/O requests to the memory filesystem process.
179 */
180 int
181 mfs_strategy(ap)
182 struct vop_strategy_args /* {
183 struct buf *a_bp;
184 } */ *ap;
185 {
186 register struct buf *bp = ap->a_bp;
187 register struct mfsnode *mfsp;
188 struct vnode *vp;
189 struct proc *p = curproc; /* XXX */
190
191 if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0)
192 panic("mfs_strategy: bad dev");
193 mfsp = VTOMFS(vp);
194 /* check for mini-root access */
195 if (mfsp->mfs_pid == 0) {
196 caddr_t base;
197
198 base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT);
199 if (bp->b_flags & B_READ)
200 bcopy(base, bp->b_data, bp->b_bcount);
201 else
202 bcopy(bp->b_data, base, bp->b_bcount);
203 biodone(bp);
204 } else if (mfsp->mfs_pid == p->p_pid) {
205 mfs_doio(bp, mfsp->mfs_baseoff);
206 } else {
207 bp->b_actf = mfsp->mfs_buflist;
208 mfsp->mfs_buflist = bp;
209 wakeup((caddr_t)vp);
210 }
211 return (0);
212 }
213
214 /*
215 * Memory file system I/O.
216 *
217 * Trivial on the HP since buffer has already been mapping into KVA space.
218 */
219 void
220 mfs_doio(bp, base)
221 register struct buf *bp;
222 caddr_t base;
223 {
224
225 base += (bp->b_blkno << DEV_BSHIFT);
226 if (bp->b_flags & B_READ)
227 bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
228 else
229 bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
230 if (bp->b_error)
231 bp->b_flags |= B_ERROR;
232 biodone(bp);
233 }
234
235 /*
236 * This is a noop, simply returning what one has been given.
237 */
238 int
239 mfs_bmap(ap)
240 struct vop_bmap_args /* {
241 struct vnode *a_vp;
242 daddr_t a_bn;
243 struct vnode **a_vpp;
244 daddr_t *a_bnp;
245 int *a_runp;
246 } */ *ap;
247 {
248
249 if (ap->a_vpp != NULL)
250 *ap->a_vpp = ap->a_vp;
251 if (ap->a_bnp != NULL)
252 *ap->a_bnp = ap->a_bn;
253 return (0);
254 }
255
256 /*
257 * Memory filesystem close routine
258 */
259 /* ARGSUSED */
260 int
261 mfs_close(ap)
262 struct vop_close_args /* {
263 struct vnode *a_vp;
264 int a_fflag;
265 struct ucred *a_cred;
266 struct proc *a_p;
267 } */ *ap;
268 {
269 register struct vnode *vp = ap->a_vp;
270 register struct mfsnode *mfsp = VTOMFS(vp);
271 register struct buf *bp;
272 int error;
273
274 /*
275 * Finish any pending I/O requests.
276 */
277 while (bp = mfsp->mfs_buflist) {
278 mfsp->mfs_buflist = bp->b_actf;
279 mfs_doio(bp, mfsp->mfs_baseoff);
280 wakeup((caddr_t)bp);
281 }
282 /*
283 * On last close of a memory filesystem
284 * we must invalidate any in core blocks, so that
285 * we can, free up its vnode.
286 */
287 if (error = vinvalbuf(vp, 1, ap->a_cred, ap->a_p, 0, 0))
288 return (error);
289 /*
290 * There should be no way to have any more uses of this
291 * vnode, so if we find any other uses, it is a panic.
292 */
293 if (vp->v_usecount > 1)
294 printf("mfs_close: ref count %d > 1\n", vp->v_usecount);
295 if (vp->v_usecount > 1 || mfsp->mfs_buflist)
296 panic("mfs_close");
297 /*
298 * Send a request to the filesystem server to exit.
299 */
300 mfsp->mfs_buflist = (struct buf *)(-1);
301 wakeup((caddr_t)vp);
302 return (0);
303 }
304
305 /*
306 * Memory filesystem inactive routine
307 */
308 /* ARGSUSED */
309 int
310 mfs_inactive(ap)
311 struct vop_inactive_args /* {
312 struct vnode *a_vp;
313 } */ *ap;
314 {
315 register struct mfsnode *mfsp = VTOMFS(ap->a_vp);
316
317 if (mfsp->mfs_buflist && mfsp->mfs_buflist != (struct buf *)(-1))
318 panic("mfs_inactive: not inactive (mfs_buflist %x)",
319 mfsp->mfs_buflist);
320 return (0);
321 }
322
323 /*
324 * Reclaim a memory filesystem devvp so that it can be reused.
325 */
326 int
327 mfs_reclaim(ap)
328 struct vop_reclaim_args /* {
329 struct vnode *a_vp;
330 } */ *ap;
331 {
332 register struct vnode *vp = ap->a_vp;
333
334 FREE(vp->v_data, M_MFSNODE);
335 vp->v_data = NULL;
336 return (0);
337 }
338
339 /*
340 * Print out the contents of an mfsnode.
341 */
342 int
343 mfs_print(ap)
344 struct vop_print_args /* {
345 struct vnode *a_vp;
346 } */ *ap;
347 {
348 register struct mfsnode *mfsp = VTOMFS(ap->a_vp);
349
350 printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp->mfs_pid,
351 mfsp->mfs_baseoff, mfsp->mfs_size);
352 return (0);
353 }
354
355 /*
356 * Block device bad operation
357 */
358 int
359 mfs_badop()
360 {
361
362 panic("mfs_badop called\n");
363 /* NOTREACHED */
364 }
365
366 /*
367 * Memory based filesystem initialization.
368 */
369 mfs_init()
370 {
371
372 }