139018Smckusick /* 239018Smckusick * Copyright (c) 1989 The Regents of the University of California. 339018Smckusick * All rights reserved. 439018Smckusick * 539018Smckusick * Redistribution and use in source and binary forms are permitted 639018Smckusick * provided that the above copyright notice and this paragraph are 739018Smckusick * duplicated in all such forms and that any documentation, 839018Smckusick * advertising materials, and other materials related to such 939018Smckusick * distribution and use acknowledge that the software was developed 1039018Smckusick * by the University of California, Berkeley. The name of the 1139018Smckusick * University may not be used to endorse or promote products derived 1239018Smckusick * from this software without specific prior written permission. 1339018Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1439018Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1539018Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1639018Smckusick * 17*39616Smckusick * @(#)mfs_vfsops.c 7.8 (Berkeley) 11/25/89 1839018Smckusick */ 1939018Smckusick 2039018Smckusick #include "param.h" 2139357Smckusick #include "time.h" 2239357Smckusick #include "user.h" 2339357Smckusick #include "proc.h" 2439018Smckusick #include "buf.h" 2539018Smckusick #include "mount.h" 2639018Smckusick #include "vnode.h" 2739389Smckusick #include "../ufs/inode.h" 2839018Smckusick #include "../ufs/ufsmount.h" 2939389Smckusick #include "../ufs/mfsnode.h" 3039018Smckusick #include "../ufs/fs.h" 3139018Smckusick 3239018Smckusick extern struct vnodeops mfs_vnodeops; 3339018Smckusick 3439018Smckusick /* 3539018Smckusick * mfs vfs operations. 3639018Smckusick */ 3739018Smckusick int mfs_mount(); 3839018Smckusick int mfs_start(); 3939018Smckusick int ufs_unmount(); 4039018Smckusick int ufs_root(); 4139605Smckusick int mfs_statfs(); 4239018Smckusick int ufs_sync(); 4339018Smckusick int ufs_fhtovp(); 4439018Smckusick int ufs_vptofh(); 4539439Smckusick int mfs_init(); 4639018Smckusick 4739018Smckusick struct vfsops mfs_vfsops = { 4839018Smckusick mfs_mount, 4939018Smckusick mfs_start, 5039018Smckusick ufs_unmount, 5139018Smckusick ufs_root, 5239605Smckusick mfs_statfs, 5339018Smckusick ufs_sync, 5439018Smckusick ufs_fhtovp, 5539018Smckusick ufs_vptofh, 5639439Smckusick mfs_init, 5739018Smckusick }; 5839018Smckusick 5939018Smckusick /* 6039018Smckusick * VFS Operations. 6139018Smckusick * 6239018Smckusick * mount system call 6339018Smckusick */ 6439389Smckusick /* ARGSUSED */ 6539018Smckusick mfs_mount(mp, path, data, ndp) 6639018Smckusick struct mount *mp; 6739018Smckusick char *path; 6839018Smckusick caddr_t data; 6939018Smckusick struct nameidata *ndp; 7039018Smckusick { 7139018Smckusick struct vnode *devvp; 7239018Smckusick struct mfs_args args; 7339018Smckusick struct ufsmount *ump; 7439018Smckusick register struct fs *fs; 7539389Smckusick register struct mfsnode *mfsp; 7639018Smckusick static int mfs_minor; 7739018Smckusick u_int size; 7839018Smckusick int error; 7939018Smckusick 8039337Smckusick if (mp->m_flag & M_UPDATE) { 8139337Smckusick ump = VFSTOUFS(mp); 8239337Smckusick fs = ump->um_fs; 8339337Smckusick if (fs->fs_ronly && (mp->m_flag & M_RDONLY) == 0) 8439337Smckusick fs->fs_ronly = 0; 8539337Smckusick return (0); 8639337Smckusick } 8739018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 8839018Smckusick return (error); 8939389Smckusick error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 9039389Smckusick if (error) 9139018Smckusick return (error); 9239389Smckusick devvp->v_type = VBLK; 93*39616Smckusick if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 9439439Smckusick panic("mfs_mount: dup dev"); 9539389Smckusick mfsp = VTOMFS(devvp); 9639389Smckusick mfsp->mfs_baseoff = args.base; 9739389Smckusick mfsp->mfs_size = args.size; 9839389Smckusick mfsp->mfs_vnode = devvp; 9939389Smckusick mfsp->mfs_pid = u.u_procp->p_pid; 10039389Smckusick mfsp->mfs_buflist = (struct buf *)0; 10139018Smckusick error = mountfs(devvp, mp); 10239018Smckusick if (error) { 10339018Smckusick vrele(devvp); 10439018Smckusick return (error); 10539018Smckusick } 10639018Smckusick ump = VFSTOUFS(mp); 10739018Smckusick fs = ump->um_fs; 10839018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 10939018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 11039018Smckusick (void) copyinstr(args.name, ump->um_mntname, MNAMELEN - 1, &size); 11139018Smckusick bzero(ump->um_mntname + size, MNAMELEN - size); 11239018Smckusick return (0); 11339018Smckusick } 11439018Smckusick 11539018Smckusick /* 11639018Smckusick * Used to grab the process and keep it in the kernel to service 11739018Smckusick * memory filesystem I/O requests. 11839018Smckusick * 11939018Smckusick * Loop servicing I/O requests. 12039018Smckusick * Copy the requested data into or out of the memory filesystem 12139018Smckusick * address space. 12239018Smckusick */ 12339018Smckusick /* ARGSUSED */ 12439018Smckusick mfs_start(mp, flags) 12539018Smckusick struct mount *mp; 12639018Smckusick int flags; 12739018Smckusick { 12839018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 12939389Smckusick register struct mfsnode *mfsp = VTOMFS(vp); 13039018Smckusick register struct buf *bp; 13139018Smckusick register caddr_t base; 13239018Smckusick 13339389Smckusick base = mfsp->mfs_baseoff; 13439357Smckusick if (setjmp(&u.u_qsave)) { 13539357Smckusick /* 13639357Smckusick * We have received a signal, so try to unmount. 13739357Smckusick */ 13839357Smckusick (void) dounmount(mp, MNT_NOFORCE); 13939357Smckusick } else { 14039357Smckusick sleep((caddr_t)vp, PWAIT); 14139018Smckusick } 14239389Smckusick while (mfsp->mfs_buflist != (struct buf *)(-1)) { 14339389Smckusick while (bp = mfsp->mfs_buflist) { 14439389Smckusick mfsp->mfs_buflist = bp->av_forw; 14539357Smckusick mfs_doio(bp, base); 14639357Smckusick wakeup((caddr_t)bp); 14739357Smckusick } 14839357Smckusick sleep((caddr_t)vp, PWAIT); 14939357Smckusick } 15039018Smckusick return (0); 15139018Smckusick } 15239605Smckusick 15339605Smckusick /* 15439605Smckusick * Get file system statistics. 15539605Smckusick */ 15639605Smckusick mfs_statfs(mp, sbp) 15739605Smckusick struct mount *mp; 15839605Smckusick struct statfs *sbp; 15939605Smckusick { 16039605Smckusick int error; 16139605Smckusick 16239605Smckusick error = ufs_statfs(mp, sbp); 16339605Smckusick sbp->f_type = MOUNT_MFS; 16439605Smckusick return (error); 16539605Smckusick } 166