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*51980Smckusick * @(#)mfs_vfsops.c 7.22 (Berkeley) 12/16/91 839018Smckusick */ 939018Smckusick 1051476Sbostic #include <sys/param.h> 1151476Sbostic #include <sys/time.h> 1251476Sbostic #include <sys/kernel.h> 1351476Sbostic #include <sys/proc.h> 1451476Sbostic #include <sys/buf.h> 1551476Sbostic #include <sys/mount.h> 1651476Sbostic #include <sys/signalvar.h> 1751476Sbostic #include <sys/vnode.h> 18*51980Smckusick #include <sys/malloc.h> 1939018Smckusick 2051476Sbostic #include <ufs/ufs/quota.h> 2151476Sbostic #include <ufs/ufs/inode.h> 2251476Sbostic #include <ufs/ufs/ufsmount.h> 2351476Sbostic #include <ufs/ufs/ufs_extern.h> 2447571Skarels 2551476Sbostic #include <ufs/ffs/fs.h> 2651476Sbostic #include <ufs/ffs/ffs_extern.h> 2751476Sbostic 2851476Sbostic #include <ufs/mfs/mfsnode.h> 2951476Sbostic #include <ufs/mfs/mfs_extern.h> 3051476Sbostic 3139018Smckusick extern struct vnodeops mfs_vnodeops; 3239018Smckusick 3339018Smckusick /* 3439018Smckusick * mfs vfs operations. 3539018Smckusick */ 3639018Smckusick struct vfsops mfs_vfsops = { 3739018Smckusick mfs_mount, 3839018Smckusick mfs_start, 3951476Sbostic ffs_unmount, 4051571Smckusick ffs_root, 4141311Smckusick ufs_quotactl, 4239605Smckusick mfs_statfs, 4351476Sbostic ffs_sync, 4451571Smckusick ffs_fhtovp, 4551571Smckusick ffs_vptofh, 4639439Smckusick mfs_init, 4739018Smckusick }; 4839018Smckusick 4939018Smckusick /* 5039018Smckusick * VFS Operations. 5139018Smckusick * 5239018Smckusick * mount system call 5339018Smckusick */ 5439389Smckusick /* ARGSUSED */ 5551476Sbostic int 5648040Smckusick mfs_mount(mp, path, data, ndp, p) 5740347Smckusick register struct mount *mp; 5839018Smckusick char *path; 5939018Smckusick caddr_t data; 6039018Smckusick struct nameidata *ndp; 6148040Smckusick struct proc *p; 6239018Smckusick { 6339018Smckusick struct vnode *devvp; 6439018Smckusick struct mfs_args args; 6539018Smckusick struct ufsmount *ump; 6639018Smckusick register struct fs *fs; 6739389Smckusick register struct mfsnode *mfsp; 6839018Smckusick static int mfs_minor; 6939018Smckusick u_int size; 7039018Smckusick int error; 7139018Smckusick 7241397Smckusick if (mp->mnt_flag & MNT_UPDATE) { 7339337Smckusick ump = VFSTOUFS(mp); 7439337Smckusick fs = ump->um_fs; 7541397Smckusick if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 7639337Smckusick fs->fs_ronly = 0; 7739337Smckusick return (0); 7839337Smckusick } 7939018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 8039018Smckusick return (error); 8139389Smckusick error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 8239389Smckusick if (error) 8339018Smckusick return (error); 8439389Smckusick devvp->v_type = VBLK; 8539616Smckusick if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 8639439Smckusick panic("mfs_mount: dup dev"); 87*51980Smckusick mfsp = (struct mfsnode *)malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); 88*51980Smckusick devvp->v_data = mfsp; 8939389Smckusick mfsp->mfs_baseoff = args.base; 9039389Smckusick mfsp->mfs_size = args.size; 9139389Smckusick mfsp->mfs_vnode = devvp; 9248040Smckusick mfsp->mfs_pid = p->p_pid; 9339389Smckusick mfsp->mfs_buflist = (struct buf *)0; 9451476Sbostic if (error = ffs_mountfs(devvp, mp, p)) { 9540877Smckusick mfsp->mfs_buflist = (struct buf *)-1; 9639018Smckusick vrele(devvp); 9739018Smckusick return (error); 9839018Smckusick } 9939018Smckusick ump = VFSTOUFS(mp); 10039018Smckusick fs = ump->um_fs; 10139018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 10239018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 10341397Smckusick bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 10441397Smckusick MNAMELEN); 10541397Smckusick (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 10640347Smckusick &size); 10741397Smckusick bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 10851476Sbostic (void) mfs_statfs(mp, &mp->mnt_stat, p); 10939018Smckusick return (0); 11039018Smckusick } 11139018Smckusick 11241111Skarels int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 11341111Skarels 11439018Smckusick /* 11539018Smckusick * Used to grab the process and keep it in the kernel to service 11639018Smckusick * memory filesystem I/O requests. 11739018Smckusick * 11839018Smckusick * Loop servicing I/O requests. 11939018Smckusick * Copy the requested data into or out of the memory filesystem 12039018Smckusick * address space. 12139018Smckusick */ 12239018Smckusick /* ARGSUSED */ 12351476Sbostic int 12448040Smckusick mfs_start(mp, flags, p) 12539018Smckusick struct mount *mp; 12639018Smckusick int flags; 12748040Smckusick struct proc *p; 12839018Smckusick { 12939018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 13039389Smckusick register struct mfsnode *mfsp = VTOMFS(vp); 13139018Smckusick register struct buf *bp; 13239018Smckusick register caddr_t base; 13341111Skarels int error = 0; 13439018Smckusick 13539389Smckusick base = mfsp->mfs_baseoff; 13639389Smckusick while (mfsp->mfs_buflist != (struct buf *)(-1)) { 13739389Smckusick while (bp = mfsp->mfs_buflist) { 13839389Smckusick mfsp->mfs_buflist = bp->av_forw; 13939357Smckusick mfs_doio(bp, base); 14039357Smckusick wakeup((caddr_t)bp); 14139357Smckusick } 14244331Skarels /* 14344331Skarels * If a non-ignored signal is received, try to unmount. 14444331Skarels * If that fails, clear the signal (it has been "processed"), 14544331Skarels * otherwise we will loop here, as tsleep will always return 14644331Skarels * EINTR/ERESTART. 14744331Skarels */ 14844331Skarels if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) 14948040Smckusick if (dounmount(mp, MNT_NOFORCE, p) != 0) 15044331Skarels CLRSIG(p, CURSIG(p)); 15139357Smckusick } 15241111Skarels return (error); 15339018Smckusick } 15439605Smckusick 15539605Smckusick /* 15639605Smckusick * Get file system statistics. 15739605Smckusick */ 15848040Smckusick mfs_statfs(mp, sbp, p) 15939605Smckusick struct mount *mp; 16039605Smckusick struct statfs *sbp; 16148040Smckusick struct proc *p; 16239605Smckusick { 16339605Smckusick int error; 16439605Smckusick 16551476Sbostic error = ffs_statfs(mp, sbp, p); 16639605Smckusick sbp->f_type = MOUNT_MFS; 16739605Smckusick return (error); 16839605Smckusick } 169