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