86469a9dd346ca5a5e672b72c9e2091063776043
* Copyright (c) 1989, 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
* @(#)mfs_vfsops.c 8.8 (Berkeley) %G%
#include <sys/signalvar.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/ufs_extern.h>
#include <ufs/ffs/ffs_extern.h>
#include <ufs/mfs/mfsnode.h>
#include <ufs/mfs/mfs_extern.h>
caddr_t mfs_rootbase
; /* address of mini-root in kernel virtual memory */
u_long mfs_rootsize
; /* size of mini-root in bytes */
static int mfs_minor
; /* used for building internal dev_t */
extern int (**mfs_vnodeop_p
)();
struct vfsops mfs_vfsops
= {
* Called by main() when mfs is going to be mounted as root.
extern struct vnode
*rootvp
;
struct proc
*p
= curproc
; /* XXX */
* Get vnodes for swapdev and rootdev.
if (bdevvp(swapdev
, &swapdev_vp
) || bdevvp(rootdev
, &rootvp
))
panic("mfs_mountroot: can't setup bdevvp's");
if (error
= vfs_rootmountalloc("mfs", "mfs_root", &mp
))
mfsp
= malloc(sizeof *mfsp
, M_MFSNODE
, M_WAITOK
);
rootvp
->v_op
= mfs_vnodeop_p
;
mfsp
->mfs_baseoff
= mfs_rootbase
;
mfsp
->mfs_size
= mfs_rootsize
;
mfsp
->mfs_vnode
= rootvp
;
mfsp
->mfs_pid
= p
->p_pid
;
mfsp
->mfs_buflist
= (struct buf
*)0;
if (error
= ffs_mountfs(rootvp
, mp
, p
)) {
mp
->mnt_vfc
->vfc_refcount
--;
if (error
= vfs_lock(mp
)) {
(void)ffs_unmount(mp
, 0, p
);
mp
->mnt_vfc
->vfc_refcount
--;
CIRCLEQ_INSERT_TAIL(&mountlist
, mp
, mnt_list
);
(void) copystr(mp
->mnt_stat
.f_mntonname
, fs
->fs_fsmnt
, MNAMELEN
- 1, 0);
(void)ffs_statfs(mp
, &mp
->mnt_stat
, p
);
* This is called early in boot to set the base address and size
struct fs
*fs
= (struct fs
*)(base
+ SBOFF
);
extern int (*mountroot
)();
/* check for valid super block */
if (fs
->fs_magic
!= FS_MAGIC
|| fs
->fs_bsize
> MAXBSIZE
||
fs
->fs_bsize
< sizeof(struct fs
))
mountroot
= mfs_mountroot
;
mfs_rootsize
= fs
->fs_fsize
* fs
->fs_size
;
rootdev
= makedev(255, mfs_minor
++);
mfs_mount(mp
, path
, data
, ndp
, p
)
register struct mount
*mp
;
register struct mfsnode
*mfsp
;
if (error
= copyin(data
, (caddr_t
)&args
, sizeof (struct mfs_args
)))
* If updating, check whether changing from read-only to
* read/write; if there is no device name, that's all we do.
if (mp
->mnt_flag
& MNT_UPDATE
) {
if (fs
->fs_ronly
== 0 && (mp
->mnt_flag
& MNT_RDONLY
)) {
if (mp
->mnt_flag
& MNT_FORCE
)
error
= ffs_flushfiles(mp
, flags
, p
);
if (fs
->fs_ronly
&& (mp
->mnt_flag
& MNT_WANTRDWR
))
return (vfs_export(mp
, &ump
->um_export
, &args
.export
));
error
= getnewvnode(VT_MFS
, (struct mount
*)0, mfs_vnodeop_p
, &devvp
);
if (checkalias(devvp
, makedev(255, mfs_minor
++), (struct mount
*)0))
panic("mfs_mount: dup dev");
mfsp
= (struct mfsnode
*)malloc(sizeof *mfsp
, M_MFSNODE
, M_WAITOK
);
mfsp
->mfs_baseoff
= args
.base
;
mfsp
->mfs_size
= args
.size
;
mfsp
->mfs_pid
= p
->p_pid
;
mfsp
->mfs_buflist
= (struct buf
*)0;
if (error
= ffs_mountfs(devvp
, mp
, p
)) {
mfsp
->mfs_buflist
= (struct buf
*)-1;
(void) copyinstr(path
, fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
) - 1, &size
);
bzero(fs
->fs_fsmnt
+ size
, sizeof(fs
->fs_fsmnt
) - size
);
bcopy((caddr_t
)fs
->fs_fsmnt
, (caddr_t
)mp
->mnt_stat
.f_mntonname
,
(void) copyinstr(args
.fspec
, mp
->mnt_stat
.f_mntfromname
, MNAMELEN
- 1,
bzero(mp
->mnt_stat
.f_mntfromname
+ size
, MNAMELEN
- size
);
(void) mfs_statfs(mp
, &mp
->mnt_stat
, p
);
int mfs_pri
= PWAIT
| PCATCH
; /* XXX prob. temp */
* Used to grab the process and keep it in the kernel to service
* memory filesystem I/O requests.
* Loop servicing I/O requests.
* Copy the requested data into or out of the memory filesystem
register struct vnode
*vp
= VFSTOUFS(mp
)->um_devvp
;
register struct mfsnode
*mfsp
= VTOMFS(vp
);
base
= mfsp
->mfs_baseoff
;
while (mfsp
->mfs_buflist
!= (struct buf
*)(-1)) {
while (bp
= mfsp
->mfs_buflist
) {
mfsp
->mfs_buflist
= bp
->b_actf
;
* If a non-ignored signal is received, try to unmount.
* If that fails, clear the signal (it has been "processed"),
* otherwise we will loop here, as tsleep will always return
if (error
= tsleep((caddr_t
)vp
, mfs_pri
, "mfsidl", 0))
if (dounmount(mp
, 0, p
) != 0)
* Get file system statistics.
error
= ffs_statfs(mp
, sbp
, p
);
sbp
->f_type
= mp
->mnt_vfc
->vfc_typenum
;