1 /* 2 * Copyright (c) 1989, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)mfs_vfsops.c 7.17 (Berkeley) 06/28/90 8 */ 9 10 #include "param.h" 11 #include "time.h" 12 #include "kernel.h" 13 #include "user.h" 14 #include "proc.h" 15 #include "buf.h" 16 #include "mount.h" 17 #include "vnode.h" 18 #include "../ufs/quota.h" 19 #include "../ufs/inode.h" 20 #include "../ufs/ufsmount.h" 21 #include "../ufs/mfsnode.h" 22 #include "../ufs/fs.h" 23 24 extern struct vnodeops mfs_vnodeops; 25 26 /* 27 * mfs vfs operations. 28 */ 29 int mfs_mount(); 30 int mfs_start(); 31 int ufs_unmount(); 32 int ufs_root(); 33 int ufs_quotactl(); 34 int mfs_statfs(); 35 int ufs_sync(); 36 int ufs_fhtovp(); 37 int ufs_vptofh(); 38 int mfs_init(); 39 40 struct vfsops mfs_vfsops = { 41 mfs_mount, 42 mfs_start, 43 ufs_unmount, 44 ufs_root, 45 ufs_quotactl, 46 mfs_statfs, 47 ufs_sync, 48 ufs_fhtovp, 49 ufs_vptofh, 50 mfs_init, 51 }; 52 53 /* 54 * VFS Operations. 55 * 56 * mount system call 57 */ 58 /* ARGSUSED */ 59 mfs_mount(mp, path, data, ndp) 60 register struct mount *mp; 61 char *path; 62 caddr_t data; 63 struct nameidata *ndp; 64 { 65 struct vnode *devvp; 66 struct mfs_args args; 67 struct ufsmount *ump; 68 register struct fs *fs; 69 register struct mfsnode *mfsp; 70 static int mfs_minor; 71 u_int size; 72 int error; 73 74 if (mp->mnt_flag & MNT_UPDATE) { 75 ump = VFSTOUFS(mp); 76 fs = ump->um_fs; 77 if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 78 fs->fs_ronly = 0; 79 return (0); 80 } 81 if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 82 return (error); 83 error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 84 if (error) 85 return (error); 86 devvp->v_type = VBLK; 87 if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 88 panic("mfs_mount: dup dev"); 89 mfsp = VTOMFS(devvp); 90 mfsp->mfs_baseoff = args.base; 91 mfsp->mfs_size = args.size; 92 mfsp->mfs_vnode = devvp; 93 mfsp->mfs_pid = u.u_procp->p_pid; 94 mfsp->mfs_buflist = (struct buf *)0; 95 if (error = mountfs(devvp, mp)) { 96 mfsp->mfs_buflist = (struct buf *)-1; 97 vrele(devvp); 98 return (error); 99 } 100 ump = VFSTOUFS(mp); 101 fs = ump->um_fs; 102 (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 103 bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 104 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 105 MNAMELEN); 106 (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 107 &size); 108 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 109 (void) mfs_statfs(mp, &mp->mnt_stat); 110 return (0); 111 } 112 113 int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 114 115 /* 116 * Used to grab the process and keep it in the kernel to service 117 * memory filesystem I/O requests. 118 * 119 * Loop servicing I/O requests. 120 * Copy the requested data into or out of the memory filesystem 121 * address space. 122 */ 123 /* ARGSUSED */ 124 mfs_start(mp, flags) 125 struct mount *mp; 126 int flags; 127 { 128 register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 129 register struct mfsnode *mfsp = VTOMFS(vp); 130 register struct buf *bp; 131 register caddr_t base; 132 struct proc *p = u.u_procp; 133 int error = 0; 134 135 base = mfsp->mfs_baseoff; 136 while (mfsp->mfs_buflist != (struct buf *)(-1)) { 137 while (bp = mfsp->mfs_buflist) { 138 mfsp->mfs_buflist = bp->av_forw; 139 mfs_doio(bp, base); 140 wakeup((caddr_t)bp); 141 } 142 /* 143 * If a non-ignored signal is received, try to unmount. 144 * If that fails, clear the signal (it has been "processed"), 145 * otherwise we will loop here, as tsleep will always return 146 * EINTR/ERESTART. 147 */ 148 if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) 149 if (dounmount(mp, MNT_NOFORCE) != 0) 150 CLRSIG(p, CURSIG(p)); 151 } 152 return (error); 153 } 154 155 /* 156 * Get file system statistics. 157 */ 158 mfs_statfs(mp, sbp) 159 struct mount *mp; 160 struct statfs *sbp; 161 { 162 int error; 163 164 error = ufs_statfs(mp, sbp); 165 sbp->f_type = MOUNT_MFS; 166 return (error); 167 } 168