139018Smckusick /* 241111Skarels * Copyright (c) 1989, 1990 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*43068Smckusick * @(#)mfs_vfsops.c 7.15 (Berkeley) 06/09/90 1839018Smckusick */ 1939018Smckusick 2039018Smckusick #include "param.h" 2139357Smckusick #include "time.h" 22*43068Smckusick #include "kernel.h" 2339357Smckusick #include "user.h" 2439357Smckusick #include "proc.h" 2539018Smckusick #include "buf.h" 2639018Smckusick #include "mount.h" 2739018Smckusick #include "vnode.h" 2841311Smckusick #include "../ufs/quota.h" 2939389Smckusick #include "../ufs/inode.h" 3039018Smckusick #include "../ufs/ufsmount.h" 3139389Smckusick #include "../ufs/mfsnode.h" 3239018Smckusick #include "../ufs/fs.h" 3339018Smckusick 3439018Smckusick extern struct vnodeops mfs_vnodeops; 3539018Smckusick 3639018Smckusick /* 3739018Smckusick * mfs vfs operations. 3839018Smckusick */ 3939018Smckusick int mfs_mount(); 4039018Smckusick int mfs_start(); 4139018Smckusick int ufs_unmount(); 4239018Smckusick int ufs_root(); 4341311Smckusick int ufs_quotactl(); 4439605Smckusick int mfs_statfs(); 4539018Smckusick int ufs_sync(); 4639018Smckusick int ufs_fhtovp(); 4739018Smckusick int ufs_vptofh(); 4839439Smckusick int mfs_init(); 4939018Smckusick 5039018Smckusick struct vfsops mfs_vfsops = { 5139018Smckusick mfs_mount, 5239018Smckusick mfs_start, 5339018Smckusick ufs_unmount, 5439018Smckusick ufs_root, 5541311Smckusick ufs_quotactl, 5639605Smckusick mfs_statfs, 5739018Smckusick ufs_sync, 5839018Smckusick ufs_fhtovp, 5939018Smckusick ufs_vptofh, 6039439Smckusick mfs_init, 6139018Smckusick }; 6239018Smckusick 6339018Smckusick /* 6439018Smckusick * VFS Operations. 6539018Smckusick * 6639018Smckusick * mount system call 6739018Smckusick */ 6839389Smckusick /* ARGSUSED */ 6939018Smckusick mfs_mount(mp, path, data, ndp) 7040347Smckusick register struct mount *mp; 7139018Smckusick char *path; 7239018Smckusick caddr_t data; 7339018Smckusick struct nameidata *ndp; 7439018Smckusick { 7539018Smckusick struct vnode *devvp; 7639018Smckusick struct mfs_args args; 7739018Smckusick struct ufsmount *ump; 7839018Smckusick register struct fs *fs; 7939389Smckusick register struct mfsnode *mfsp; 8039018Smckusick static int mfs_minor; 8139018Smckusick u_int size; 8239018Smckusick int error; 8339018Smckusick 8441397Smckusick if (mp->mnt_flag & MNT_UPDATE) { 8539337Smckusick ump = VFSTOUFS(mp); 8639337Smckusick fs = ump->um_fs; 8741397Smckusick if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 8839337Smckusick fs->fs_ronly = 0; 8939337Smckusick return (0); 9039337Smckusick } 9139018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 9239018Smckusick return (error); 9339389Smckusick error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 9439389Smckusick if (error) 9539018Smckusick return (error); 9639389Smckusick devvp->v_type = VBLK; 9739616Smckusick if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 9839439Smckusick panic("mfs_mount: dup dev"); 9939389Smckusick mfsp = VTOMFS(devvp); 10039389Smckusick mfsp->mfs_baseoff = args.base; 10139389Smckusick mfsp->mfs_size = args.size; 10239389Smckusick mfsp->mfs_vnode = devvp; 10339389Smckusick mfsp->mfs_pid = u.u_procp->p_pid; 10439389Smckusick mfsp->mfs_buflist = (struct buf *)0; 10540347Smckusick if (error = mountfs(devvp, mp)) { 10640877Smckusick mfsp->mfs_buflist = (struct buf *)-1; 10739018Smckusick vrele(devvp); 10839018Smckusick return (error); 10939018Smckusick } 11039018Smckusick ump = VFSTOUFS(mp); 11139018Smckusick fs = ump->um_fs; 11239018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 11339018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 11441397Smckusick bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 11541397Smckusick MNAMELEN); 11641397Smckusick (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 11740347Smckusick &size); 11841397Smckusick bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 11941397Smckusick (void) mfs_statfs(mp, &mp->mnt_stat); 12039018Smckusick return (0); 12139018Smckusick } 12239018Smckusick 12341111Skarels int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 12441111Skarels 12539018Smckusick /* 12639018Smckusick * Used to grab the process and keep it in the kernel to service 12739018Smckusick * memory filesystem I/O requests. 12839018Smckusick * 12939018Smckusick * Loop servicing I/O requests. 13039018Smckusick * Copy the requested data into or out of the memory filesystem 13139018Smckusick * address space. 13239018Smckusick */ 13339018Smckusick /* ARGSUSED */ 13439018Smckusick mfs_start(mp, flags) 13539018Smckusick struct mount *mp; 13639018Smckusick int flags; 13739018Smckusick { 13839018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 13939389Smckusick register struct mfsnode *mfsp = VTOMFS(vp); 14039018Smckusick register struct buf *bp; 14139018Smckusick register caddr_t base; 14241111Skarels int error = 0; 14339018Smckusick 14439389Smckusick base = mfsp->mfs_baseoff; 14539389Smckusick while (mfsp->mfs_buflist != (struct buf *)(-1)) { 14639389Smckusick while (bp = mfsp->mfs_buflist) { 14739389Smckusick mfsp->mfs_buflist = bp->av_forw; 14839357Smckusick mfs_doio(bp, base); 14939357Smckusick wakeup((caddr_t)bp); 15039357Smckusick } 15141111Skarels if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) { 15241111Skarels /* 153*43068Smckusick * Give other processes a chance to run. 154*43068Smckusick */ 155*43068Smckusick sleep(&lbolt, PVFS); 156*43068Smckusick /* 15741111Skarels * We have received a signal, so try to unmount. 15841111Skarels */ 15941111Skarels (void) dounmount(mp, MNT_NOFORCE); 16041111Skarels } 16139357Smckusick } 16241111Skarels return (error); 16339018Smckusick } 16439605Smckusick 16539605Smckusick /* 16639605Smckusick * Get file system statistics. 16739605Smckusick */ 16839605Smckusick mfs_statfs(mp, sbp) 16939605Smckusick struct mount *mp; 17039605Smckusick struct statfs *sbp; 17139605Smckusick { 17239605Smckusick int error; 17339605Smckusick 17439605Smckusick error = ufs_statfs(mp, sbp); 17539605Smckusick sbp->f_type = MOUNT_MFS; 17639605Smckusick return (error); 17739605Smckusick } 178