1 /* 2 * Copyright (c) 1989, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)mfs_vfsops.c 7.14 (Berkeley) 05/04/90 18 */ 19 20 #include "param.h" 21 #include "time.h" 22 #include "user.h" 23 #include "proc.h" 24 #include "buf.h" 25 #include "mount.h" 26 #include "vnode.h" 27 #include "../ufs/quota.h" 28 #include "../ufs/inode.h" 29 #include "../ufs/ufsmount.h" 30 #include "../ufs/mfsnode.h" 31 #include "../ufs/fs.h" 32 33 extern struct vnodeops mfs_vnodeops; 34 35 /* 36 * mfs vfs operations. 37 */ 38 int mfs_mount(); 39 int mfs_start(); 40 int ufs_unmount(); 41 int ufs_root(); 42 int ufs_quotactl(); 43 int mfs_statfs(); 44 int ufs_sync(); 45 int ufs_fhtovp(); 46 int ufs_vptofh(); 47 int mfs_init(); 48 49 struct vfsops mfs_vfsops = { 50 mfs_mount, 51 mfs_start, 52 ufs_unmount, 53 ufs_root, 54 ufs_quotactl, 55 mfs_statfs, 56 ufs_sync, 57 ufs_fhtovp, 58 ufs_vptofh, 59 mfs_init, 60 }; 61 62 /* 63 * VFS Operations. 64 * 65 * mount system call 66 */ 67 /* ARGSUSED */ 68 mfs_mount(mp, path, data, ndp) 69 register struct mount *mp; 70 char *path; 71 caddr_t data; 72 struct nameidata *ndp; 73 { 74 struct vnode *devvp; 75 struct mfs_args args; 76 struct ufsmount *ump; 77 register struct fs *fs; 78 register struct mfsnode *mfsp; 79 static int mfs_minor; 80 u_int size; 81 int error; 82 83 if (mp->mnt_flag & MNT_UPDATE) { 84 ump = VFSTOUFS(mp); 85 fs = ump->um_fs; 86 if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) 87 fs->fs_ronly = 0; 88 return (0); 89 } 90 if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) 91 return (error); 92 error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp); 93 if (error) 94 return (error); 95 devvp->v_type = VBLK; 96 if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0)) 97 panic("mfs_mount: dup dev"); 98 mfsp = VTOMFS(devvp); 99 mfsp->mfs_baseoff = args.base; 100 mfsp->mfs_size = args.size; 101 mfsp->mfs_vnode = devvp; 102 mfsp->mfs_pid = u.u_procp->p_pid; 103 mfsp->mfs_buflist = (struct buf *)0; 104 if (error = mountfs(devvp, mp)) { 105 mfsp->mfs_buflist = (struct buf *)-1; 106 vrele(devvp); 107 return (error); 108 } 109 ump = VFSTOUFS(mp); 110 fs = ump->um_fs; 111 (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 112 bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 113 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 114 MNAMELEN); 115 (void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 116 &size); 117 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 118 (void) mfs_statfs(mp, &mp->mnt_stat); 119 return (0); 120 } 121 122 int mfs_pri = PWAIT | PCATCH; /* XXX prob. temp */ 123 124 /* 125 * Used to grab the process and keep it in the kernel to service 126 * memory filesystem I/O requests. 127 * 128 * Loop servicing I/O requests. 129 * Copy the requested data into or out of the memory filesystem 130 * address space. 131 */ 132 /* ARGSUSED */ 133 mfs_start(mp, flags) 134 struct mount *mp; 135 int flags; 136 { 137 register struct vnode *vp = VFSTOUFS(mp)->um_devvp; 138 register struct mfsnode *mfsp = VTOMFS(vp); 139 register struct buf *bp; 140 register caddr_t base; 141 int error = 0; 142 143 base = mfsp->mfs_baseoff; 144 while (mfsp->mfs_buflist != (struct buf *)(-1)) { 145 while (bp = mfsp->mfs_buflist) { 146 mfsp->mfs_buflist = bp->av_forw; 147 mfs_doio(bp, base); 148 wakeup((caddr_t)bp); 149 } 150 if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) { 151 /* 152 * We have received a signal, so try to unmount. 153 */ 154 (void) dounmount(mp, MNT_NOFORCE); 155 } 156 } 157 return (error); 158 } 159 160 /* 161 * Get file system statistics. 162 */ 163 mfs_statfs(mp, sbp) 164 struct mount *mp; 165 struct statfs *sbp; 166 { 167 int error; 168 169 error = ufs_statfs(mp, sbp); 170 sbp->f_type = MOUNT_MFS; 171 return (error); 172 } 173