]>
git.saurik.com Git - apple/xnu.git/blob - bsd/ufs/mfs/mfs_vfsops.c
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 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
27 * Copyright (c) 1989, 1990, 1993, 1994
28 * The Regents of the University of California. All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94
61 #include <sys/param.h>
62 #include <sys/systm.h>
64 #include <sys/kernel.h>
67 #include <sys/mount.h>
68 #include <sys/signalvar.h>
69 #include <sys/vnode.h>
70 #include <sys/malloc.h>
72 #include <ufs/ufs/quota.h>
73 #include <ufs/ufs/inode.h>
74 #include <ufs/ufs/ufsmount.h>
75 #include <ufs/ufs/ufs_extern.h>
77 #include <ufs/ffs/fs.h>
78 #include <ufs/ffs/ffs_extern.h>
80 #include <ufs/mfs/mfsnode.h>
81 #include <ufs/mfs/mfs_extern.h>
83 caddr_t mfs_rootbase
; /* address of mini-root in kernel virtual memory */
84 u_long mfs_rootsize
; /* size of mini-root in bytes */
86 static int mfs_minor
; /* used for building internal dev_t */
88 extern int (**mfs_vnodeop_p
)(void *);
93 struct vfsops mfs_vfsops
= {
109 * Called by main() when mfs is going to be mounted as root.
111 * Name is updated by mount(8) after booting.
113 #define ROOTNAME "mfs_root"
117 extern struct vnode
*rootvp
;
118 register struct fs
*fs
;
119 register struct mount
*mp
;
120 struct proc
*p
= kernel_proc
; /* XXX - WMG*/
121 struct ufsmount
*ump
;
122 struct mfsnode
*mfsp
;
127 * Get vnodes for swapdev and rootdev.
130 if (bdevvp(swapdev
, &swapdev_vp
) || bdevvp(rootdev
, &rootvp
))
131 panic("mfs_mountroot: can't setup bdevvp's");
133 if ( bdevvp(rootdev
, &rootvp
))
134 panic("mfs_mountroot: can't setup bdevvp's");
137 MALLOC_ZONE(mp
, struct mount
*,
138 sizeof(struct mount
), M_MOUNT
, M_WAITOK
);
139 bzero((char *)mp
, (u_long
)sizeof(struct mount
));
141 /* Initialize the default IO constraints */
142 mp
->mnt_maxreadcnt
= mp
->mnt_maxwritecnt
= MAXPHYS
;
143 mp
->mnt_segreadcnt
= mp
->mnt_segwritecnt
= 32;
145 mp
->mnt_op
= &mfs_vfsops
;
146 mp
->mnt_flag
= MNT_RDONLY
;
147 MALLOC(mfsp
, struct mfsnode
*, sizeof(struct mfsnode
), M_MFSNODE
, M_WAITOK
);
148 rootvp
->v_data
= mfsp
;
149 rootvp
->v_op
= mfs_vnodeop_p
;
150 rootvp
->v_tag
= VT_MFS
;
151 mfsp
->mfs_baseoff
= mfs_rootbase
;
152 mfsp
->mfs_size
= mfs_rootsize
;
153 mfsp
->mfs_vnode
= rootvp
;
154 mfsp
->mfs_pid
= p
->p_pid
;
155 mfsp
->mfs_buflist
= (struct buf
*)0;
156 if (error
= ffs_mountfs(rootvp
, mp
, p
)) {
157 vrele(rootvp
); /* release the reference from bdevvp() */
158 _FREE_ZONE(mp
, sizeof (struct mount
), M_MOUNT
);
159 _FREE(mfsp
, M_MFSNODE
);
162 if (error
= vfs_lock(mp
)) {
163 (void)ffs_unmount(mp
, 0, p
);
164 _FREE_ZONE(mp
, sizeof (struct mount
), M_MOUNT
);
165 _FREE(mfsp
, M_MFSNODE
);
168 CIRCLEQ_INSERT_TAIL(&mountlist
, mp
, mnt_list
);
169 mp
->mnt_vnodecovered
= NULLVP
;
172 bzero(fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
));
173 fs
->fs_fsmnt
[0] = '/';
174 bcopy(fs
->fs_fsmnt
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
);
175 (void) copystr(ROOTNAME
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
177 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
178 (void)ffs_statfs(mp
, &mp
->mnt_stat
, p
);
185 * This is called early in boot to set the base address and size
188 mfs_initminiroot(base
)
191 struct fs
*fs
= (struct fs
*)(base
+ SBOFF
);
192 extern int (*mountroot
)();
194 /* check for valid super block */
195 if (fs
->fs_magic
!= FS_MAGIC
|| fs
->fs_bsize
> MAXBSIZE
||
196 fs
->fs_bsize
< sizeof(struct fs
))
198 mountroot
= mfs_mountroot
;
200 mfs_rootsize
= fs
->fs_fsize
* fs
->fs_size
;
201 rootdev
= makedev(255, mfs_minor
++);
202 return (mfs_rootsize
);
212 mfs_mount(mp
, path
, data
, ndp
, p
)
213 register struct mount
*mp
;
216 struct nameidata
*ndp
;
220 struct mfs_args args
;
221 struct ufsmount
*ump
;
222 register struct fs
*fs
;
223 register struct mfsnode
*mfsp
;
227 if (error
= copyin(data
, (caddr_t
)&args
, sizeof (struct mfs_args
)))
231 * If updating, check whether changing from read-only to
232 * read/write; if there is no device name, that's all we do.
234 if (mp
->mnt_flag
& MNT_UPDATE
) {
237 if (fs
->fs_ronly
== 0 && (mp
->mnt_flag
& MNT_RDONLY
)) {
239 if (mp
->mnt_flag
& MNT_FORCE
)
243 error
= ffs_flushfiles(mp
, flags
, p
);
248 if (fs
->fs_ronly
&& (mp
->mnt_kern_flag
& MNTK_WANTRDWR
))
252 return (vfs_export(mp
, &ump
->um_export
, &args
.export
));
256 MALLOC(mfsp
, struct mfsnode
*, sizeof(struct mfsnode
), M_MFSNODE
, M_WAITOK
);
257 error
= getnewvnode(VT_MFS
, (struct mount
*)0, mfs_vnodeop_p
, &devvp
);
259 FREE(mfsp
, M_MFSNODE
);
262 devvp
->v_type
= VBLK
;
263 if (checkalias(devvp
, makedev(255, mfs_minor
++), (struct mount
*)0))
264 panic("mfs_mount: dup dev");
265 devvp
->v_data
= mfsp
;
266 mfsp
->mfs_baseoff
= args
.base
;
267 mfsp
->mfs_size
= args
.size
;
268 mfsp
->mfs_vnode
= devvp
;
269 mfsp
->mfs_pid
= p
->p_pid
;
270 mfsp
->mfs_buflist
= (struct buf
*)0;
271 if (error
= ffs_mountfs(devvp
, mp
, p
)) {
272 mfsp
->mfs_buflist
= (struct buf
*)-1;
278 (void) copyinstr(path
, fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
) - 1, &size
);
279 bzero(fs
->fs_fsmnt
+ size
, sizeof(fs
->fs_fsmnt
) - size
);
280 bcopy(fs
->fs_fsmnt
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
);
281 (void) copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
283 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
287 int mfs_pri
= PWAIT
| PCATCH
; /* XXX prob. temp */
290 * Used to grab the process and keep it in the kernel to service
291 * memory filesystem I/O requests.
293 * Loop servicing I/O requests.
294 * Copy the requested data into or out of the memory filesystem
299 mfs_start(mp
, flags
, p
)
304 register struct vnode
*vp
= VFSTOUFS(mp
)->um_devvp
;
305 register struct mfsnode
*mfsp
= VTOMFS(vp
);
306 register struct buf
*bp
;
307 register caddr_t base
;
310 base
= mfsp
->mfs_baseoff
;
311 while (mfsp
->mfs_buflist
!= (struct buf
*)(-1)) {
312 while (bp
= mfsp
->mfs_buflist
) {
313 mfsp
->mfs_buflist
= bp
->b_actf
;
318 * If a non-ignored signal is received, try to unmount.
319 * If that fails, clear the signal (it has been "processed"),
320 * otherwise we will loop here, as tsleep will always return
323 if (error
= tsleep((caddr_t
)vp
, mfs_pri
, "mfsidl", 0))
324 if (dounmount(mp
, 0, p
) != 0)
325 CLRSIG(p
, CURSIG(p
));
331 * Get file system statistics.
333 mfs_statfs(mp
, sbp
, p
)
340 error
= ffs_statfs(mp
, sbp
, p
);
346 strncpy(&sbp
->f_fstypename
[0], mp
->mnt_op
->vfs_name
, MFSNAMELEN
);
347 sbp
->f_fstypename
[MFSNAMELEN
] = '\0';