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