]>
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 * 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 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1989, 1990, 1993, 1994
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94
58 #include <sys/param.h>
59 #include <sys/systm.h>
61 #include <sys/kernel.h>
64 #include <sys/mount.h>
65 #include <sys/signalvar.h>
66 #include <sys/vnode.h>
67 #include <sys/malloc.h>
69 #include <ufs/ufs/quota.h>
70 #include <ufs/ufs/inode.h>
71 #include <ufs/ufs/ufsmount.h>
72 #include <ufs/ufs/ufs_extern.h>
74 #include <ufs/ffs/fs.h>
75 #include <ufs/ffs/ffs_extern.h>
77 #include <ufs/mfs/mfsnode.h>
78 #include <ufs/mfs/mfs_extern.h>
80 caddr_t mfs_rootbase
; /* address of mini-root in kernel virtual memory */
81 u_long mfs_rootsize
; /* size of mini-root in bytes */
83 static int mfs_minor
; /* used for building internal dev_t */
85 extern int (**mfs_vnodeop_p
)(void *);
90 struct vfsops mfs_vfsops
= {
106 * Called by main() when mfs is going to be mounted as root.
108 * Name is updated by mount(8) after booting.
110 #define ROOTNAME "mfs_root"
114 extern struct vnode
*rootvp
;
115 register struct fs
*fs
;
116 register struct mount
*mp
;
117 struct proc
*p
= kernel_proc
; /* XXX - WMG*/
118 struct ufsmount
*ump
;
119 struct mfsnode
*mfsp
;
124 * Get vnodes for swapdev and rootdev.
127 if (bdevvp(swapdev
, &swapdev_vp
) || bdevvp(rootdev
, &rootvp
))
128 panic("mfs_mountroot: can't setup bdevvp's");
130 if ( bdevvp(rootdev
, &rootvp
))
131 panic("mfs_mountroot: can't setup bdevvp's");
134 MALLOC_ZONE(mp
, struct mount
*,
135 sizeof(struct mount
), M_MOUNT
, M_WAITOK
);
136 bzero((char *)mp
, (u_long
)sizeof(struct mount
));
138 /* Initialize the default IO constraints */
139 mp
->mnt_maxreadcnt
= mp
->mnt_maxwritecnt
= MAXPHYS
;
140 mp
->mnt_segreadcnt
= mp
->mnt_segwritecnt
= 32;
142 mp
->mnt_op
= &mfs_vfsops
;
143 mp
->mnt_flag
= MNT_RDONLY
;
144 MALLOC(mfsp
, struct mfsnode
*, sizeof(struct mfsnode
), M_MFSNODE
, M_WAITOK
);
145 rootvp
->v_data
= mfsp
;
146 rootvp
->v_op
= mfs_vnodeop_p
;
147 rootvp
->v_tag
= VT_MFS
;
148 mfsp
->mfs_baseoff
= mfs_rootbase
;
149 mfsp
->mfs_size
= mfs_rootsize
;
150 mfsp
->mfs_vnode
= rootvp
;
151 mfsp
->mfs_pid
= p
->p_pid
;
152 mfsp
->mfs_buflist
= (struct buf
*)0;
153 if (error
= ffs_mountfs(rootvp
, mp
, p
)) {
154 _FREE_ZONE(mp
, sizeof (struct mount
), M_MOUNT
);
155 _FREE(mfsp
, M_MFSNODE
);
158 if (error
= vfs_lock(mp
)) {
159 (void)ffs_unmount(mp
, 0, p
);
160 _FREE_ZONE(mp
, sizeof (struct mount
), M_MOUNT
);
161 _FREE(mfsp
, M_MFSNODE
);
164 CIRCLEQ_INSERT_TAIL(&mountlist
, mp
, mnt_list
);
165 mp
->mnt_vnodecovered
= NULLVP
;
168 bzero(fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
));
169 fs
->fs_fsmnt
[0] = '/';
170 bcopy(fs
->fs_fsmnt
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
);
171 (void) copystr(ROOTNAME
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
173 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
174 (void)ffs_statfs(mp
, &mp
->mnt_stat
, p
);
181 * This is called early in boot to set the base address and size
184 mfs_initminiroot(base
)
187 struct fs
*fs
= (struct fs
*)(base
+ SBOFF
);
188 extern int (*mountroot
)();
190 /* check for valid super block */
191 if (fs
->fs_magic
!= FS_MAGIC
|| fs
->fs_bsize
> MAXBSIZE
||
192 fs
->fs_bsize
< sizeof(struct fs
))
194 mountroot
= mfs_mountroot
;
196 mfs_rootsize
= fs
->fs_fsize
* fs
->fs_size
;
197 rootdev
= makedev(255, mfs_minor
++);
198 return (mfs_rootsize
);
208 mfs_mount(mp
, path
, data
, ndp
, p
)
209 register struct mount
*mp
;
212 struct nameidata
*ndp
;
216 struct mfs_args args
;
217 struct ufsmount
*ump
;
218 register struct fs
*fs
;
219 register struct mfsnode
*mfsp
;
223 if (error
= copyin(data
, (caddr_t
)&args
, sizeof (struct mfs_args
)))
227 * If updating, check whether changing from read-only to
228 * read/write; if there is no device name, that's all we do.
230 if (mp
->mnt_flag
& MNT_UPDATE
) {
233 if (fs
->fs_ronly
== 0 && (mp
->mnt_flag
& MNT_RDONLY
)) {
235 if (mp
->mnt_flag
& MNT_FORCE
)
239 error
= ffs_flushfiles(mp
, flags
, p
);
244 if (fs
->fs_ronly
&& (mp
->mnt_kern_flag
& MNTK_WANTRDWR
))
248 return (vfs_export(mp
, &ump
->um_export
, &args
.export
));
252 MALLOC(mfsp
, struct mfsnode
*, sizeof(struct mfsnode
), M_MFSNODE
, M_WAITOK
);
253 error
= getnewvnode(VT_MFS
, (struct mount
*)0, mfs_vnodeop_p
, &devvp
);
255 FREE(mfsp
, M_MFSNODE
);
258 devvp
->v_type
= VBLK
;
259 if (checkalias(devvp
, makedev(255, mfs_minor
++), (struct mount
*)0))
260 panic("mfs_mount: dup dev");
261 devvp
->v_data
= mfsp
;
262 mfsp
->mfs_baseoff
= args
.base
;
263 mfsp
->mfs_size
= args
.size
;
264 mfsp
->mfs_vnode
= devvp
;
265 mfsp
->mfs_pid
= p
->p_pid
;
266 mfsp
->mfs_buflist
= (struct buf
*)0;
267 if (error
= ffs_mountfs(devvp
, mp
, p
)) {
268 mfsp
->mfs_buflist
= (struct buf
*)-1;
274 (void) copyinstr(path
, fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
) - 1, &size
);
275 bzero(fs
->fs_fsmnt
+ size
, sizeof(fs
->fs_fsmnt
) - size
);
276 bcopy(fs
->fs_fsmnt
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
);
277 (void) copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
279 bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
283 int mfs_pri
= PWAIT
| PCATCH
; /* XXX prob. temp */
286 * Used to grab the process and keep it in the kernel to service
287 * memory filesystem I/O requests.
289 * Loop servicing I/O requests.
290 * Copy the requested data into or out of the memory filesystem
295 mfs_start(mp
, flags
, p
)
300 register struct vnode
*vp
= VFSTOUFS(mp
)->um_devvp
;
301 register struct mfsnode
*mfsp
= VTOMFS(vp
);
302 register struct buf
*bp
;
303 register caddr_t base
;
306 base
= mfsp
->mfs_baseoff
;
307 while (mfsp
->mfs_buflist
!= (struct buf
*)(-1)) {
308 while (bp
= mfsp
->mfs_buflist
) {
309 mfsp
->mfs_buflist
= bp
->b_actf
;
314 * If a non-ignored signal is received, try to unmount.
315 * If that fails, clear the signal (it has been "processed"),
316 * otherwise we will loop here, as tsleep will always return
319 if (error
= tsleep((caddr_t
)vp
, mfs_pri
, "mfsidl", 0))
320 if (dounmount(mp
, 0, p
) != 0)
321 CLRSIG(p
, CURSIG(p
));
327 * Get file system statistics.
329 mfs_statfs(mp
, sbp
, p
)
336 error
= ffs_statfs(mp
, sbp
, p
);
342 strncpy(&sbp
->f_fstypename
[0], mp
->mnt_op
->vfs_name
, MFSNAMELEN
);
343 sbp
->f_fstypename
[MFSNAMELEN
] = '\0';