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*39357Smckusick * @(#)mfs_vfsops.c 7.4 (Berkeley) 10/20/89 1839018Smckusick */ 1939018Smckusick 2039018Smckusick #include "param.h" 21*39357Smckusick #include "time.h" 22*39357Smckusick #include "user.h" 23*39357Smckusick #include "proc.h" 2439018Smckusick #include "buf.h" 2539018Smckusick #include "mount.h" 2639018Smckusick #include "vnode.h" 2739018Smckusick #include "../ufs/ufsmount.h" 2839018Smckusick #include "../ufs/inode.h" 2939018Smckusick #include "../ufs/fs.h" 3039018Smckusick 3139018Smckusick extern struct vnodeops mfs_vnodeops; 3239018Smckusick 3339018Smckusick /* 3439018Smckusick * mfs vfs operations. 3539018Smckusick */ 3639018Smckusick int mfs_mount(); 3739018Smckusick int mfs_start(); 3839018Smckusick int ufs_unmount(); 3939018Smckusick int ufs_root(); 4039018Smckusick int ufs_statfs(); 4139018Smckusick int ufs_sync(); 4239018Smckusick int ufs_fhtovp(); 4339018Smckusick int ufs_vptofh(); 4439018Smckusick 4539018Smckusick struct vfsops mfs_vfsops = { 4639018Smckusick mfs_mount, 4739018Smckusick mfs_start, 4839018Smckusick ufs_unmount, 4939018Smckusick ufs_root, 5039018Smckusick ufs_statfs, 5139018Smckusick ufs_sync, 5239018Smckusick ufs_fhtovp, 5339018Smckusick ufs_vptofh, 5439018Smckusick }; 5539018Smckusick 5639018Smckusick /* 5739018Smckusick * VFS Operations. 5839018Smckusick * 5939018Smckusick * mount system call 6039018Smckusick */ 6139018Smckusick mfs_mount(mp, path, data, ndp) 6239018Smckusick struct mount *mp; 6339018Smckusick char *path; 6439018Smckusick caddr_t data; 6539018Smckusick struct nameidata *ndp; 6639018Smckusick { 6739018Smckusick struct vnode *devvp; 6839018Smckusick struct mfs_args args; 6939018Smckusick struct ufsmount *ump; 7039018Smckusick register struct fs *fs; 7139018Smckusick static int mfs_minor; 7239018Smckusick u_int size; 7339018Smckusick int error; 7439018Smckusick 7539337Smckusick if (mp->m_flag & M_UPDATE) { 7639337Smckusick ump = VFSTOUFS(mp); 7739337Smckusick fs = ump->um_fs; 7839337Smckusick if (fs->fs_ronly && (mp->m_flag & M_RDONLY) == 0) 7939337Smckusick fs->fs_ronly = 0; 8039337Smckusick return (0); 8139337Smckusick } 8239018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 8339018Smckusick return (error); 8439018Smckusick if ((error = bdevvp(NODEV, &devvp)) != 0) 8539018Smckusick return (error); 8639018Smckusick devvp->v_op = &mfs_vnodeops; 8739018Smckusick devvp->v_rdev = makedev(255, mfs_minor++); 8839018Smckusick VTOI(devvp)->i_diroff = (long)args.base; 8939018Smckusick VTOI(devvp)->i_endoff = args.size; 9039018Smckusick error = mountfs(devvp, mp); 9139018Smckusick if (error) { 9239018Smckusick vrele(devvp); 9339018Smckusick return (error); 9439018Smckusick } 9539018Smckusick ump = VFSTOUFS(mp); 9639018Smckusick fs = ump->um_fs; 9739018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 9839018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 9939018Smckusick (void) copyinstr(args.name, ump->um_mntname, MNAMELEN - 1, &size); 10039018Smckusick bzero(ump->um_mntname + size, MNAMELEN - size); 10139018Smckusick return (0); 10239018Smckusick } 10339018Smckusick 10439018Smckusick /* 10539018Smckusick * Used to grab the process and keep it in the kernel to service 10639018Smckusick * memory filesystem I/O requests. 10739018Smckusick * 10839018Smckusick * Loop servicing I/O requests. 10939018Smckusick * Copy the requested data into or out of the memory filesystem 11039018Smckusick * address space. 11139018Smckusick */ 11239018Smckusick /* ARGSUSED */ 11339018Smckusick mfs_start(mp, flags) 11439018Smckusick struct mount *mp; 11539018Smckusick int flags; 11639018Smckusick { 11739018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 11839018Smckusick register struct inode *ip = VTOI(vp); 11939018Smckusick register struct buf *bp; 12039018Smckusick register caddr_t base; 12139018Smckusick 12239018Smckusick base = (caddr_t)ip->i_diroff; 123*39357Smckusick if (setjmp(&u.u_qsave)) { 124*39357Smckusick /* 125*39357Smckusick * We have received a signal, so try to unmount. 126*39357Smckusick */ 127*39357Smckusick (void) dounmount(mp, MNT_NOFORCE); 128*39357Smckusick } else { 129*39357Smckusick sleep((caddr_t)vp, PWAIT); 13039018Smckusick } 131*39357Smckusick while (ip->i_spare[0] != -1) { 132*39357Smckusick while (bp = (struct buf *)ip->i_spare[0]) { 133*39357Smckusick ip->i_spare[0] = (long)bp->av_forw; 134*39357Smckusick mfs_doio(bp, base); 135*39357Smckusick wakeup((caddr_t)bp); 136*39357Smckusick } 137*39357Smckusick sleep((caddr_t)vp, PWAIT); 138*39357Smckusick } 13939018Smckusick return (0); 14039018Smckusick } 141