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*51476Sbostic * @(#)mfs_vfsops.c 7.20 (Berkeley) 11/01/91 839018Smckusick */ 939018Smckusick 10*51476Sbostic #include <sys/param.h> 11*51476Sbostic #include <sys/time.h> 12*51476Sbostic #include <sys/kernel.h> 13*51476Sbostic #include <sys/proc.h> 14*51476Sbostic #include <sys/buf.h> 15*51476Sbostic #include <sys/mount.h> 16*51476Sbostic #include <sys/signalvar.h> 17*51476Sbostic #include <sys/vnode.h> 1839018Smckusick 19*51476Sbostic #include <ufs/ufs/quota.h> 20*51476Sbostic #include <ufs/ufs/inode.h> 21*51476Sbostic #include <ufs/ufs/ufsmount.h> 22*51476Sbostic #include <ufs/ufs/ufs_extern.h> 2347571Skarels 24*51476Sbostic #include <ufs/ffs/fs.h> 25*51476Sbostic #include <ufs/ffs/ffs_extern.h> 26*51476Sbostic 27*51476Sbostic #include <ufs/mfs/mfsnode.h> 28*51476Sbostic #include <ufs/mfs/mfs_extern.h> 29*51476Sbostic 3039018Smckusick extern struct vnodeops mfs_vnodeops; 3139018Smckusick 3239018Smckusick /* 3339018Smckusick * mfs vfs operations. 3439018Smckusick */ 3539018Smckusick struct vfsops mfs_vfsops = { 3639018Smckusick mfs_mount, 3739018Smckusick mfs_start, 38*51476Sbostic ffs_unmount, 3939018Smckusick ufs_root, 4041311Smckusick ufs_quotactl, 4139605Smckusick mfs_statfs, 42*51476Sbostic ffs_sync, 4339018Smckusick ufs_fhtovp, 4439018Smckusick ufs_vptofh, 4539439Smckusick mfs_init, 4639018Smckusick }; 4739018Smckusick 4839018Smckusick /* 4939018Smckusick * VFS Operations. 5039018Smckusick * 5139018Smckusick * mount system call 5239018Smckusick */ 5339389Smckusick /* ARGSUSED */ 54*51476Sbostic int 5548040Smckusick mfs_mount(mp, path, data, ndp, p) 5640347Smckusick register struct mount *mp; 5739018Smckusick char *path; 5839018Smckusick caddr_t data; 5939018Smckusick struct nameidata *ndp; 6048040Smckusick struct proc *p; 6139018Smckusick { 6239018Smckusick struct vnode *devvp; 6339018Smckusick struct mfs_args args; 6439018Smckusick struct ufsmount *ump; 6539018Smckusick register struct fs *fs; 6639389Smckusick register struct mfsnode *mfsp; 6739018Smckusick static int mfs_minor; 6839018Smckusick u_int size; 6939018Smckusick int error; 7039018Smckusick 7141397Smckusick if (mp->mnt_flag & MNT_UPDATE) { 7239337Smckusick ump = VFSTOUFS(mp); 7339337Smckusick fs = ump->um_fs; 7441397Smckusick if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 7539337Smckusick fs->fs_ronly = 0; 7639337Smckusick return (0); 7739337Smckusick } 7839018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 7939018Smckusick return (error); 8039389Smckusick error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 8139389Smckusick if (error) 8239018Smckusick return (error); 8339389Smckusick devvp->v_type = VBLK; 8439616Smckusick if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 8539439Smckusick panic("mfs_mount: dup dev"); 8639389Smckusick mfsp = VTOMFS(devvp); 8739389Smckusick mfsp->mfs_baseoff = args.base; 8839389Smckusick mfsp->mfs_size = args.size; 8939389Smckusick mfsp->mfs_vnode = devvp; 9048040Smckusick mfsp->mfs_pid = p->p_pid; 9139389Smckusick mfsp->mfs_buflist = (struct buf *)0; 92*51476Sbostic if (error = ffs_mountfs(devvp, mp, p)) { 9340877Smckusick mfsp->mfs_buflist = (struct buf *)-1; 9439018Smckusick vrele(devvp); 9539018Smckusick return (error); 9639018Smckusick } 9739018Smckusick ump = VFSTOUFS(mp); 9839018Smckusick fs = ump->um_fs; 9939018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 10039018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 10141397Smckusick bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 10241397Smckusick MNAMELEN); 10341397Smckusick (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 10440347Smckusick &size); 10541397Smckusick bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 106*51476Sbostic (void) mfs_statfs(mp, &mp->mnt_stat, p); 10739018Smckusick return (0); 10839018Smckusick } 10939018Smckusick 11041111Skarels int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 11141111Skarels 11239018Smckusick /* 11339018Smckusick * Used to grab the process and keep it in the kernel to service 11439018Smckusick * memory filesystem I/O requests. 11539018Smckusick * 11639018Smckusick * Loop servicing I/O requests. 11739018Smckusick * Copy the requested data into or out of the memory filesystem 11839018Smckusick * address space. 11939018Smckusick */ 12039018Smckusick /* ARGSUSED */ 121*51476Sbostic int 12248040Smckusick mfs_start(mp, flags, p) 12339018Smckusick struct mount *mp; 12439018Smckusick int flags; 12548040Smckusick struct proc *p; 12639018Smckusick { 12739018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 12839389Smckusick register struct mfsnode *mfsp = VTOMFS(vp); 12939018Smckusick register struct buf *bp; 13039018Smckusick register caddr_t base; 13141111Skarels int error = 0; 13239018Smckusick 13339389Smckusick base = mfsp->mfs_baseoff; 13439389Smckusick while (mfsp->mfs_buflist != (struct buf *)(-1)) { 13539389Smckusick while (bp = mfsp->mfs_buflist) { 13639389Smckusick mfsp->mfs_buflist = bp->av_forw; 13739357Smckusick mfs_doio(bp, base); 13839357Smckusick wakeup((caddr_t)bp); 13939357Smckusick } 14044331Skarels /* 14144331Skarels * If a non-ignored signal is received, try to unmount. 14244331Skarels * If that fails, clear the signal (it has been "processed"), 14344331Skarels * otherwise we will loop here, as tsleep will always return 14444331Skarels * EINTR/ERESTART. 14544331Skarels */ 14644331Skarels if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) 14748040Smckusick if (dounmount(mp, MNT_NOFORCE, p) != 0) 14844331Skarels CLRSIG(p, CURSIG(p)); 14939357Smckusick } 15041111Skarels return (error); 15139018Smckusick } 15239605Smckusick 15339605Smckusick /* 15439605Smckusick * Get file system statistics. 15539605Smckusick */ 15648040Smckusick mfs_statfs(mp, sbp, p) 15739605Smckusick struct mount *mp; 15839605Smckusick struct statfs *sbp; 15948040Smckusick struct proc *p; 16039605Smckusick { 16139605Smckusick int error; 16239605Smckusick 163*51476Sbostic error = ffs_statfs(mp, sbp, p); 16439605Smckusick sbp->f_type = MOUNT_MFS; 16539605Smckusick return (error); 16639605Smckusick } 167