139018Smckusick /* 241111Skarels * Copyright (c) 1989, 1990 The Regents of the University of California. 339018Smckusick * All rights reserved. 439018Smckusick * 544536Sbostic * %sccs.include.redist.c% 639018Smckusick * 7*48040Smckusick * @(#)mfs_vfsops.c 7.19 (Berkeley) 04/16/91 839018Smckusick */ 939018Smckusick 1039018Smckusick #include "param.h" 1139357Smckusick #include "time.h" 1243068Smckusick #include "kernel.h" 1339357Smckusick #include "proc.h" 1439018Smckusick #include "buf.h" 1539018Smckusick #include "mount.h" 1647571Skarels #include "signalvar.h" 1739018Smckusick #include "vnode.h" 1839018Smckusick 1947571Skarels #include "quota.h" 2047571Skarels #include "inode.h" 2147571Skarels #include "ufsmount.h" 2247571Skarels #include "mfsnode.h" 2347571Skarels #include "fs.h" 2447571Skarels 2539018Smckusick extern struct vnodeops mfs_vnodeops; 2639018Smckusick 2739018Smckusick /* 2839018Smckusick * mfs vfs operations. 2939018Smckusick */ 3039018Smckusick int mfs_mount(); 3139018Smckusick int mfs_start(); 3239018Smckusick int ufs_unmount(); 3339018Smckusick int ufs_root(); 3441311Smckusick int ufs_quotactl(); 3539605Smckusick int mfs_statfs(); 3639018Smckusick int ufs_sync(); 3739018Smckusick int ufs_fhtovp(); 3839018Smckusick int ufs_vptofh(); 3939439Smckusick int mfs_init(); 4039018Smckusick 4139018Smckusick struct vfsops mfs_vfsops = { 4239018Smckusick mfs_mount, 4339018Smckusick mfs_start, 4439018Smckusick ufs_unmount, 4539018Smckusick ufs_root, 4641311Smckusick ufs_quotactl, 4739605Smckusick mfs_statfs, 4839018Smckusick ufs_sync, 4939018Smckusick ufs_fhtovp, 5039018Smckusick ufs_vptofh, 5139439Smckusick mfs_init, 5239018Smckusick }; 5339018Smckusick 5439018Smckusick /* 5539018Smckusick * VFS Operations. 5639018Smckusick * 5739018Smckusick * mount system call 5839018Smckusick */ 5939389Smckusick /* ARGSUSED */ 60*48040Smckusick mfs_mount(mp, path, data, ndp, p) 6140347Smckusick register struct mount *mp; 6239018Smckusick char *path; 6339018Smckusick caddr_t data; 6439018Smckusick struct nameidata *ndp; 65*48040Smckusick struct proc *p; 6639018Smckusick { 6739018Smckusick struct vnode *devvp; 6839018Smckusick struct mfs_args args; 6939018Smckusick struct ufsmount *ump; 7039018Smckusick register struct fs *fs; 7139389Smckusick register struct mfsnode *mfsp; 7239018Smckusick static int mfs_minor; 7339018Smckusick u_int size; 7439018Smckusick int error; 7539018Smckusick 7641397Smckusick if (mp->mnt_flag & MNT_UPDATE) { 7739337Smckusick ump = VFSTOUFS(mp); 7839337Smckusick fs = ump->um_fs; 7941397Smckusick if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 8039337Smckusick fs->fs_ronly = 0; 8139337Smckusick return (0); 8239337Smckusick } 8339018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 8439018Smckusick return (error); 8539389Smckusick error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 8639389Smckusick if (error) 8739018Smckusick return (error); 8839389Smckusick devvp->v_type = VBLK; 8939616Smckusick if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 9039439Smckusick panic("mfs_mount: dup dev"); 9139389Smckusick mfsp = VTOMFS(devvp); 9239389Smckusick mfsp->mfs_baseoff = args.base; 9339389Smckusick mfsp->mfs_size = args.size; 9439389Smckusick mfsp->mfs_vnode = devvp; 95*48040Smckusick mfsp->mfs_pid = p->p_pid; 9639389Smckusick mfsp->mfs_buflist = (struct buf *)0; 9740347Smckusick if (error = mountfs(devvp, mp)) { 9840877Smckusick mfsp->mfs_buflist = (struct buf *)-1; 9939018Smckusick vrele(devvp); 10039018Smckusick return (error); 10139018Smckusick } 10239018Smckusick ump = VFSTOUFS(mp); 10339018Smckusick fs = ump->um_fs; 10439018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 10539018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 10641397Smckusick bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 10741397Smckusick MNAMELEN); 10841397Smckusick (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 10940347Smckusick &size); 11041397Smckusick bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 11141397Smckusick (void) mfs_statfs(mp, &mp->mnt_stat); 11239018Smckusick return (0); 11339018Smckusick } 11439018Smckusick 11541111Skarels int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 11641111Skarels 11739018Smckusick /* 11839018Smckusick * Used to grab the process and keep it in the kernel to service 11939018Smckusick * memory filesystem I/O requests. 12039018Smckusick * 12139018Smckusick * Loop servicing I/O requests. 12239018Smckusick * Copy the requested data into or out of the memory filesystem 12339018Smckusick * address space. 12439018Smckusick */ 12539018Smckusick /* ARGSUSED */ 126*48040Smckusick mfs_start(mp, flags, p) 12739018Smckusick struct mount *mp; 12839018Smckusick int flags; 129*48040Smckusick struct proc *p; 13039018Smckusick { 13139018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 13239389Smckusick register struct mfsnode *mfsp = VTOMFS(vp); 13339018Smckusick register struct buf *bp; 13439018Smckusick register caddr_t base; 13541111Skarels int error = 0; 13639018Smckusick 13739389Smckusick base = mfsp->mfs_baseoff; 13839389Smckusick while (mfsp->mfs_buflist != (struct buf *)(-1)) { 13939389Smckusick while (bp = mfsp->mfs_buflist) { 14039389Smckusick mfsp->mfs_buflist = bp->av_forw; 14139357Smckusick mfs_doio(bp, base); 14239357Smckusick wakeup((caddr_t)bp); 14339357Smckusick } 14444331Skarels /* 14544331Skarels * If a non-ignored signal is received, try to unmount. 14644331Skarels * If that fails, clear the signal (it has been "processed"), 14744331Skarels * otherwise we will loop here, as tsleep will always return 14844331Skarels * EINTR/ERESTART. 14944331Skarels */ 15044331Skarels if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) 151*48040Smckusick if (dounmount(mp, MNT_NOFORCE, p) != 0) 15244331Skarels CLRSIG(p, CURSIG(p)); 15339357Smckusick } 15441111Skarels return (error); 15539018Smckusick } 15639605Smckusick 15739605Smckusick /* 15839605Smckusick * Get file system statistics. 15939605Smckusick */ 160*48040Smckusick mfs_statfs(mp, sbp, p) 16139605Smckusick struct mount *mp; 16239605Smckusick struct statfs *sbp; 163*48040Smckusick struct proc *p; 16439605Smckusick { 16539605Smckusick int error; 16639605Smckusick 167*48040Smckusick error = ufs_statfs(mp, sbp, p); 16839605Smckusick sbp->f_type = MOUNT_MFS; 16939605Smckusick return (error); 17039605Smckusick } 171