2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
22 /* $NetBSD: mfs_vnops.c,v 1.5 1994/12/14 13:03:52 mycroft Exp $ */
25 * Copyright (c) 1989, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
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.
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
56 * @(#)mfs_vnops.c 8.5 (Berkeley) 7/28/94
59 #include <sys/param.h>
60 #include <sys/systm.h>
62 #include <sys/kernel.h>
66 #include <sys/vnode.h>
67 #include <sys/malloc.h>
69 #include <miscfs/specfs/specdev.h>
71 #include <machine/vmparam.h>
73 #include <ufs/mfs/mfsnode.h>
74 #include <ufs/mfs/mfsiom.h>
75 #include <ufs/mfs/mfs_extern.h>
78 * mfs vnode operations.
81 #define VOPFUNC int (*)(void *)
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
}
130 struct vnodeopv_desc mfs_vnodeop_opv_desc
=
131 { &mfs_vnodeop_p
, mfs_vnodeop_entries
};
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.
143 struct vop_open_args
/* {
146 struct ucred *a_cred;
151 if (ap
->a_vp
->v_type
!= VBLK
) {
152 panic("mfs_ioctl not VBLK");
164 struct vop_ioctl_args
/* {
169 struct ucred *a_cred;
178 * Pass I/O requests to the memory filesystem process.
182 struct vop_strategy_args
/* {
186 register struct buf
*bp
= ap
->a_bp
;
187 register struct mfsnode
*mfsp
;
189 struct proc
*p
= curproc
; /* XXX */
191 if (!vfinddev(bp
->b_dev
, VBLK
, &vp
) || vp
->v_usecount
== 0)
192 panic("mfs_strategy: bad dev");
194 /* check for mini-root access */
195 if (mfsp
->mfs_pid
== 0) {
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
);
202 bcopy(bp
->b_data
, base
, bp
->b_bcount
);
204 } else if (mfsp
->mfs_pid
== p
->p_pid
) {
205 mfs_doio(bp
, mfsp
->mfs_baseoff
);
207 bp
->b_actf
= mfsp
->mfs_buflist
;
208 mfsp
->mfs_buflist
= bp
;
215 * Memory file system I/O.
217 * Trivial on the HP since buffer has already been mapping into KVA space.
221 register struct buf
*bp
;
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
);
229 bp
->b_error
= copyout(bp
->b_data
, base
, bp
->b_bcount
);
231 bp
->b_flags
|= B_ERROR
;
236 * This is a noop, simply returning what one has been given.
240 struct vop_bmap_args
/* {
243 struct vnode **a_vpp;
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
;
257 * Memory filesystem close routine
262 struct vop_close_args
/* {
265 struct ucred *a_cred;
269 register struct vnode
*vp
= ap
->a_vp
;
270 register struct mfsnode
*mfsp
= VTOMFS(vp
);
271 register struct buf
*bp
;
275 * Finish any pending I/O requests.
277 while (bp
= mfsp
->mfs_buflist
) {
278 mfsp
->mfs_buflist
= bp
->b_actf
;
279 mfs_doio(bp
, mfsp
->mfs_baseoff
);
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.
287 if (error
= vinvalbuf(vp
, 1, ap
->a_cred
, ap
->a_p
, 0, 0))
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.
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
)
298 * Send a request to the filesystem server to exit.
300 mfsp
->mfs_buflist
= (struct buf
*)(-1);
306 * Memory filesystem inactive routine
311 struct vop_inactive_args
/* {
315 register struct mfsnode
*mfsp
= VTOMFS(ap
->a_vp
);
317 if (mfsp
->mfs_buflist
&& mfsp
->mfs_buflist
!= (struct buf
*)(-1))
318 panic("mfs_inactive: not inactive (mfs_buflist %x)",
324 * Reclaim a memory filesystem devvp so that it can be reused.
328 struct vop_reclaim_args
/* {
332 register struct vnode
*vp
= ap
->a_vp
;
334 FREE(vp
->v_data
, M_MFSNODE
);
340 * Print out the contents of an mfsnode.
344 struct vop_print_args
/* {
348 register struct mfsnode
*mfsp
= VTOMFS(ap
->a_vp
);
350 printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp
->mfs_pid
,
351 mfsp
->mfs_baseoff
, mfsp
->mfs_size
);
356 * Block device bad operation
362 panic("mfs_badop called\n");
367 * Memory based filesystem initialization.