]> git.saurik.com Git - apple/xnu.git/blame - bsd/ufs/mfs/mfs_vnops.c
xnu-344.23.tar.gz
[apple/xnu.git] / bsd / ufs / mfs / mfs_vnops.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
de355530
A
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.
1c79356b 11 *
de355530
A
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
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
de355530
A
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.
1c79356b
A
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
83int (**mfs_vnodeop_p)(void *);
84struct 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};
130struct 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 */
141int
142mfs_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 */
162int
163mfs_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 */
180int
181mfs_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 */
219void
220mfs_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 */
238int
239mfs_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 */
260int
261mfs_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 */
309int
310mfs_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 */
326int
327mfs_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 */
342int
343mfs_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 */
358int
359mfs_badop()
360{
361
362 panic("mfs_badop called\n");
363 /* NOTREACHED */
364}
365
366/*
367 * Memory based filesystem initialization.
368 */
369mfs_init()
370{
371
372}