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*53043Sralph * @(#)mfs_vfsops.c 7.23 (Berkeley) 03/22/92 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> 1851980Smckusick #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 31*53043Sralph caddr_t mfs_rootbase; /* address of mini-root in kernel virtual memory */ 32*53043Sralph u_long mfs_rootsize; /* size of mini-root in bytes */ 33*53043Sralph 3439018Smckusick extern struct vnodeops mfs_vnodeops; 3539018Smckusick 3639018Smckusick /* 3739018Smckusick * mfs vfs operations. 3839018Smckusick */ 3939018Smckusick struct vfsops mfs_vfsops = { 4039018Smckusick mfs_mount, 4139018Smckusick mfs_start, 4251476Sbostic ffs_unmount, 4351571Smckusick ffs_root, 4441311Smckusick ufs_quotactl, 4539605Smckusick mfs_statfs, 4651476Sbostic ffs_sync, 4751571Smckusick ffs_fhtovp, 4851571Smckusick ffs_vptofh, 4939439Smckusick mfs_init, 5039018Smckusick }; 5139018Smckusick 5239018Smckusick /* 53*53043Sralph * Called by main() when mfs is going to be mounted as root. 54*53043Sralph * 55*53043Sralph * Name is updated by mount(8) after booting. 56*53043Sralph */ 57*53043Sralph #define ROOTNAME "root_device" 58*53043Sralph 59*53043Sralph mfs_mountroot() 60*53043Sralph { 61*53043Sralph extern struct vnode *rootvp; 62*53043Sralph register struct fs *fs; 63*53043Sralph register struct mount *mp; 64*53043Sralph struct proc *p = curproc; /* XXX */ 65*53043Sralph struct ufsmount *ump; 66*53043Sralph struct mfsnode *mfsp; 67*53043Sralph u_int size; 68*53043Sralph int error; 69*53043Sralph 70*53043Sralph mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); 71*53043Sralph mp->mnt_op = &mfs_vfsops; 72*53043Sralph mp->mnt_flag = MNT_RDONLY; 73*53043Sralph mp->mnt_mounth = NULLVP; 74*53043Sralph mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); 75*53043Sralph rootvp->v_data = mfsp; 76*53043Sralph rootvp->v_op = &mfs_vnodeops; 77*53043Sralph mfsp->mfs_baseoff = mfs_rootbase; 78*53043Sralph mfsp->mfs_size = mfs_rootsize; 79*53043Sralph mfsp->mfs_vnode = rootvp; 80*53043Sralph mfsp->mfs_pid = p->p_pid; 81*53043Sralph mfsp->mfs_buflist = (struct buf *)0; 82*53043Sralph if (error = ffs_mountfs(rootvp, mp, p)) { 83*53043Sralph free(mp, M_MOUNT); 84*53043Sralph free(mfsp, M_MFSNODE); 85*53043Sralph return (error); 86*53043Sralph } 87*53043Sralph if (error = vfs_lock(mp)) { 88*53043Sralph (void)ffs_unmount(mp, 0, p); 89*53043Sralph free(mp, M_MOUNT); 90*53043Sralph free(mfsp, M_MFSNODE); 91*53043Sralph return (error); 92*53043Sralph } 93*53043Sralph rootfs = mp; 94*53043Sralph mp->mnt_next = mp; 95*53043Sralph mp->mnt_prev = mp; 96*53043Sralph mp->mnt_vnodecovered = NULLVP; 97*53043Sralph ump = VFSTOUFS(mp); 98*53043Sralph fs = ump->um_fs; 99*53043Sralph bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); 100*53043Sralph fs->fs_fsmnt[0] = '/'; 101*53043Sralph bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 102*53043Sralph MNAMELEN); 103*53043Sralph (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 104*53043Sralph &size); 105*53043Sralph bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 106*53043Sralph (void)ffs_statfs(mp, &mp->mnt_stat, p); 107*53043Sralph vfs_unlock(mp); 108*53043Sralph inittodr((time_t)0); 109*53043Sralph return (0); 110*53043Sralph } 111*53043Sralph 112*53043Sralph /* 113*53043Sralph * This is called early in boot to set the base address and size 114*53043Sralph * of the mini-root. 115*53043Sralph */ 116*53043Sralph mfs_initminiroot(base) 117*53043Sralph caddr_t base; 118*53043Sralph { 119*53043Sralph struct fs *fs = (struct fs *)(base + SBOFF); 120*53043Sralph extern int (*mountroot)(); 121*53043Sralph 122*53043Sralph /* check for valid super block */ 123*53043Sralph if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 124*53043Sralph fs->fs_bsize < sizeof(struct fs)) 125*53043Sralph return (0); 126*53043Sralph mountroot = mfs_mountroot; 127*53043Sralph mfs_rootbase = base; 128*53043Sralph mfs_rootsize = fs->fs_fsize * fs->fs_size; 129*53043Sralph return (mfs_rootsize); 130*53043Sralph } 131*53043Sralph 132*53043Sralph /* 13339018Smckusick * VFS Operations. 13439018Smckusick * 13539018Smckusick * mount system call 13639018Smckusick */ 13739389Smckusick /* ARGSUSED */ 13851476Sbostic int 13948040Smckusick mfs_mount(mp, path, data, ndp, p) 14040347Smckusick register struct mount *mp; 14139018Smckusick char *path; 14239018Smckusick caddr_t data; 14339018Smckusick struct nameidata *ndp; 14448040Smckusick struct proc *p; 14539018Smckusick { 14639018Smckusick struct vnode *devvp; 14739018Smckusick struct mfs_args args; 14839018Smckusick struct ufsmount *ump; 14939018Smckusick register struct fs *fs; 15039389Smckusick register struct mfsnode *mfsp; 15139018Smckusick static int mfs_minor; 15239018Smckusick u_int size; 15339018Smckusick int error; 15439018Smckusick 15541397Smckusick if (mp->mnt_flag & MNT_UPDATE) { 15639337Smckusick ump = VFSTOUFS(mp); 15739337Smckusick fs = ump->um_fs; 15841397Smckusick if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 15939337Smckusick fs->fs_ronly = 0; 16039337Smckusick return (0); 16139337Smckusick } 16239018Smckusick if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 16339018Smckusick return (error); 16439389Smckusick error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 16539389Smckusick if (error) 16639018Smckusick return (error); 16739389Smckusick devvp->v_type = VBLK; 16839616Smckusick if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 16939439Smckusick panic("mfs_mount: dup dev"); 17051980Smckusick mfsp = (struct mfsnode *)malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK); 17151980Smckusick devvp->v_data = mfsp; 17239389Smckusick mfsp->mfs_baseoff = args.base; 17339389Smckusick mfsp->mfs_size = args.size; 17439389Smckusick mfsp->mfs_vnode = devvp; 17548040Smckusick mfsp->mfs_pid = p->p_pid; 17639389Smckusick mfsp->mfs_buflist = (struct buf *)0; 17751476Sbostic if (error = ffs_mountfs(devvp, mp, p)) { 17840877Smckusick mfsp->mfs_buflist = (struct buf *)-1; 17939018Smckusick vrele(devvp); 18039018Smckusick return (error); 18139018Smckusick } 18239018Smckusick ump = VFSTOUFS(mp); 18339018Smckusick fs = ump->um_fs; 18439018Smckusick (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 18539018Smckusick bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 18641397Smckusick bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 18741397Smckusick MNAMELEN); 18841397Smckusick (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 18940347Smckusick &size); 19041397Smckusick bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 19151476Sbostic (void) mfs_statfs(mp, &mp->mnt_stat, p); 19239018Smckusick return (0); 19339018Smckusick } 19439018Smckusick 19541111Skarels int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 19641111Skarels 19739018Smckusick /* 19839018Smckusick * Used to grab the process and keep it in the kernel to service 19939018Smckusick * memory filesystem I/O requests. 20039018Smckusick * 20139018Smckusick * Loop servicing I/O requests. 20239018Smckusick * Copy the requested data into or out of the memory filesystem 20339018Smckusick * address space. 20439018Smckusick */ 20539018Smckusick /* ARGSUSED */ 20651476Sbostic int 20748040Smckusick mfs_start(mp, flags, p) 20839018Smckusick struct mount *mp; 20939018Smckusick int flags; 21048040Smckusick struct proc *p; 21139018Smckusick { 21239018Smckusick register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 21339389Smckusick register struct mfsnode *mfsp = VTOMFS(vp); 21439018Smckusick register struct buf *bp; 21539018Smckusick register caddr_t base; 21641111Skarels int error = 0; 21739018Smckusick 21839389Smckusick base = mfsp->mfs_baseoff; 21939389Smckusick while (mfsp->mfs_buflist != (struct buf *)(-1)) { 22039389Smckusick while (bp = mfsp->mfs_buflist) { 22139389Smckusick mfsp->mfs_buflist = bp->av_forw; 22239357Smckusick mfs_doio(bp, base); 22339357Smckusick wakeup((caddr_t)bp); 22439357Smckusick } 22544331Skarels /* 22644331Skarels * If a non-ignored signal is received, try to unmount. 22744331Skarels * If that fails, clear the signal (it has been "processed"), 22844331Skarels * otherwise we will loop here, as tsleep will always return 22944331Skarels * EINTR/ERESTART. 23044331Skarels */ 23144331Skarels if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) 23248040Smckusick if (dounmount(mp, MNT_NOFORCE, p) != 0) 23344331Skarels CLRSIG(p, CURSIG(p)); 23439357Smckusick } 23541111Skarels return (error); 23639018Smckusick } 23739605Smckusick 23839605Smckusick /* 23939605Smckusick * Get file system statistics. 24039605Smckusick */ 24148040Smckusick mfs_statfs(mp, sbp, p) 24239605Smckusick struct mount *mp; 24339605Smckusick struct statfs *sbp; 24448040Smckusick struct proc *p; 24539605Smckusick { 24639605Smckusick int error; 24739605Smckusick 24851476Sbostic error = ffs_statfs(mp, sbp, p); 24939605Smckusick sbp->f_type = MOUNT_MFS; 25039605Smckusick return (error); 25139605Smckusick } 252