2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* $NetBSD: mfs_vnops.c,v 1.5 1994/12/14 13:03:52 mycroft Exp $ */
28 * Copyright (c) 1989, 1993
29 * The Regents of the University of California. All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * @(#)mfs_vnops.c 8.5 (Berkeley) 7/28/94
62 #include <sys/param.h>
63 #include <sys/systm.h>
65 #include <sys/kernel.h>
69 #include <sys/vnode.h>
70 #include <sys/malloc.h>
72 #include <miscfs/specfs/specdev.h>
74 #include <machine/vmparam.h>
76 #include <ufs/mfs/mfsnode.h>
77 #include <ufs/mfs/mfsiom.h>
78 #include <ufs/mfs/mfs_extern.h>
81 * mfs vnode operations.
84 #define VOPFUNC int (*)(void *)
86 int (**mfs_vnodeop_p
)(void *);
87 struct vnodeopv_entry_desc mfs_vnodeop_entries
[] = {
88 { &vop_default_desc
, (VOPFUNC
)vn_default_error
},
89 { &vop_lookup_desc
, (VOPFUNC
)mfs_lookup
}, /* lookup */
90 { &vop_create_desc
, (VOPFUNC
)mfs_create
}, /* create */
91 { &vop_mknod_desc
, (VOPFUNC
)mfs_mknod
}, /* mknod */
92 { &vop_open_desc
, (VOPFUNC
)mfs_open
}, /* open */
93 { &vop_close_desc
, (VOPFUNC
)mfs_close
}, /* close */
94 { &vop_access_desc
, (VOPFUNC
)mfs_access
}, /* access */
95 { &vop_getattr_desc
, (VOPFUNC
)mfs_getattr
}, /* getattr */
96 { &vop_setattr_desc
, (VOPFUNC
)mfs_setattr
}, /* setattr */
97 { &vop_read_desc
, (VOPFUNC
)mfs_read
}, /* read */
98 { &vop_write_desc
, (VOPFUNC
)mfs_write
}, /* write */
99 { &vop_ioctl_desc
, (VOPFUNC
)mfs_ioctl
}, /* ioctl */
100 { &vop_select_desc
, (VOPFUNC
)mfs_select
}, /* select */
101 { &vop_mmap_desc
, (VOPFUNC
)mfs_mmap
}, /* mmap */
102 { &vop_fsync_desc
, (VOPFUNC
)spec_fsync
}, /* fsync */
103 { &vop_seek_desc
, (VOPFUNC
)mfs_seek
}, /* seek */
104 { &vop_remove_desc
, (VOPFUNC
)mfs_remove
}, /* remove */
105 { &vop_link_desc
, (VOPFUNC
)mfs_link
}, /* link */
106 { &vop_rename_desc
, (VOPFUNC
)mfs_rename
}, /* rename */
107 { &vop_mkdir_desc
, (VOPFUNC
)mfs_mkdir
}, /* mkdir */
108 { &vop_rmdir_desc
, (VOPFUNC
)mfs_rmdir
}, /* rmdir */
109 { &vop_symlink_desc
, (VOPFUNC
)mfs_symlink
}, /* symlink */
110 { &vop_readdir_desc
, (VOPFUNC
)mfs_readdir
}, /* readdir */
111 { &vop_readlink_desc
, (VOPFUNC
)mfs_readlink
}, /* readlink */
112 { &vop_abortop_desc
, (VOPFUNC
)mfs_abortop
}, /* abortop */
113 { &vop_inactive_desc
, (VOPFUNC
)mfs_inactive
}, /* inactive */
114 { &vop_reclaim_desc
, (VOPFUNC
)mfs_reclaim
}, /* reclaim */
115 { &vop_lock_desc
, (VOPFUNC
)mfs_lock
}, /* lock */
116 { &vop_unlock_desc
, (VOPFUNC
)mfs_unlock
}, /* unlock */
117 { &vop_bmap_desc
, (VOPFUNC
)mfs_bmap
}, /* bmap */
118 { &vop_strategy_desc
, (VOPFUNC
)mfs_strategy
}, /* strategy */
119 { &vop_print_desc
, (VOPFUNC
)mfs_print
}, /* print */
120 { &vop_islocked_desc
, (VOPFUNC
)mfs_islocked
}, /* islocked */
121 { &vop_pathconf_desc
, (VOPFUNC
)mfs_pathconf
}, /* pathconf */
122 { &vop_advlock_desc
, (VOPFUNC
)mfs_advlock
}, /* advlock */
123 { &vop_blkatoff_desc
, (VOPFUNC
)mfs_blkatoff
}, /* blkatoff */
124 { &vop_valloc_desc
, (VOPFUNC
)mfs_valloc
}, /* valloc */
125 { &vop_vfree_desc
, (VOPFUNC
)mfs_vfree
}, /* vfree */
126 { &vop_truncate_desc
, (VOPFUNC
)mfs_truncate
}, /* truncate */
127 { &vop_update_desc
, (VOPFUNC
)mfs_update
}, /* update */
128 { &vop_bwrite_desc
, (VOPFUNC
)mfs_bwrite
}, /* bwrite */
129 { &vop_pgrd_desc
, (VOPFUNC
)mfs_pgrg
}, /* pager read */
130 { &vop_pgwr_desc
, (VOPFUNC
)mfs_pgwr
}, /* pager write */
131 { (struct vnodeop_desc
*)NULL
, (int(*)())NULL
}
133 struct vnodeopv_desc mfs_vnodeop_opv_desc
=
134 { &mfs_vnodeop_p
, mfs_vnodeop_entries
};
139 * Open called to allow memory filesystem to initialize and
140 * validate before actual IO. Record our process identifier
141 * so we can tell when we are doing I/O to ourself.
146 struct vop_open_args
/* {
149 struct ucred *a_cred;
154 if (ap
->a_vp
->v_type
!= VBLK
) {
155 panic("mfs_ioctl not VBLK");
167 struct vop_ioctl_args
/* {
172 struct ucred *a_cred;
181 * Pass I/O requests to the memory filesystem process.
185 struct vop_strategy_args
/* {
189 register struct buf
*bp
= ap
->a_bp
;
190 register struct mfsnode
*mfsp
;
192 struct proc
*p
= curproc
; /* XXX */
194 if (!vfinddev(bp
->b_dev
, VBLK
, &vp
) || vp
->v_usecount
== 0)
195 panic("mfs_strategy: bad dev");
197 /* check for mini-root access */
198 if (mfsp
->mfs_pid
== 0) {
201 base
= mfsp
->mfs_baseoff
+ (bp
->b_blkno
<< DEV_BSHIFT
);
202 if (bp
->b_flags
& B_READ
)
203 bcopy(base
, bp
->b_data
, bp
->b_bcount
);
205 bcopy(bp
->b_data
, base
, bp
->b_bcount
);
207 } else if (mfsp
->mfs_pid
== p
->p_pid
) {
208 mfs_doio(bp
, mfsp
->mfs_baseoff
);
210 bp
->b_actf
= mfsp
->mfs_buflist
;
211 mfsp
->mfs_buflist
= bp
;
218 * Memory file system I/O.
220 * Trivial on the HP since buffer has already been mapping into KVA space.
224 register struct buf
*bp
;
228 base
+= (bp
->b_blkno
<< DEV_BSHIFT
);
229 if (bp
->b_flags
& B_READ
)
230 bp
->b_error
= copyin(base
, bp
->b_data
, bp
->b_bcount
);
232 bp
->b_error
= copyout(bp
->b_data
, base
, bp
->b_bcount
);
234 bp
->b_flags
|= B_ERROR
;
239 * This is a noop, simply returning what one has been given.
243 struct vop_bmap_args
/* {
246 struct vnode **a_vpp;
252 if (ap
->a_vpp
!= NULL
)
253 *ap
->a_vpp
= ap
->a_vp
;
254 if (ap
->a_bnp
!= NULL
)
255 *ap
->a_bnp
= ap
->a_bn
;
260 * Memory filesystem close routine
265 struct vop_close_args
/* {
268 struct ucred *a_cred;
272 register struct vnode
*vp
= ap
->a_vp
;
273 register struct mfsnode
*mfsp
= VTOMFS(vp
);
274 register struct buf
*bp
;
278 * Finish any pending I/O requests.
280 while (bp
= mfsp
->mfs_buflist
) {
281 mfsp
->mfs_buflist
= bp
->b_actf
;
282 mfs_doio(bp
, mfsp
->mfs_baseoff
);
286 * On last close of a memory filesystem
287 * we must invalidate any in core blocks, so that
288 * we can, free up its vnode.
290 if (error
= vinvalbuf(vp
, 1, ap
->a_cred
, ap
->a_p
, 0, 0))
293 * There should be no way to have any more uses of this
294 * vnode, so if we find any other uses, it is a panic.
296 if (vp
->v_usecount
> 1)
297 printf("mfs_close: ref count %d > 1\n", vp
->v_usecount
);
298 if (vp
->v_usecount
> 1 || mfsp
->mfs_buflist
)
301 * Send a request to the filesystem server to exit.
303 mfsp
->mfs_buflist
= (struct buf
*)(-1);
309 * Memory filesystem inactive routine
314 struct vop_inactive_args
/* {
318 register struct mfsnode
*mfsp
= VTOMFS(ap
->a_vp
);
320 if (mfsp
->mfs_buflist
&& mfsp
->mfs_buflist
!= (struct buf
*)(-1))
321 panic("mfs_inactive: not inactive (mfs_buflist %x)",
327 * Reclaim a memory filesystem devvp so that it can be reused.
331 struct vop_reclaim_args
/* {
335 register struct vnode
*vp
= ap
->a_vp
;
337 FREE(vp
->v_data
, M_MFSNODE
);
343 * Print out the contents of an mfsnode.
347 struct vop_print_args
/* {
351 register struct mfsnode
*mfsp
= VTOMFS(ap
->a_vp
);
353 printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp
->mfs_pid
,
354 mfsp
->mfs_baseoff
, mfsp
->mfs_size
);
359 * Block device bad operation
365 panic("mfs_badop called\n");
370 * Memory based filesystem initialization.