/* * This structure defines the control data for the memory * based file system. */ struct mfsnode { structvnode *mfs-vnode;/* vnode associated with this mfsnode */ caddr-tmfs-baseoff;/* base of file system in memory */ longmfs-size;/* size of memory file system */ pid-tmfs-pid;/* supporting process pid */ structbuf *mfs-buflist;/* list of I/O requests */ }; /* * Convert between mfsnode pointers and vnode pointers */ VTOMFS#defineVTOMFS(vp)((struct mfsnode *)(vp)->v-data) MFSTOV#defineMFSTOV(mfsp)((mfsp)->mfs-vnode) #defineMFS-EXIT(struct buf *)-1 /* * Arguments to mount MFS */ struct mfs-args { char*name;/* name to export for statfs */ caddr-tbase;/* base address of file system in memory */ u-longsize;/* size of file system */ }; /* * Mount an MFS filesystem. */ mfs_mountmfs-mount(mp, path, data) struct mount *mp; char *path; caddr-t data; { struct vnode *devvp; struct mfsnode *mfsp; struct buf *bp; struct mfs-args args; /* * Create a block device to represent the disk. */ devvp = getnewvnode(VT-MFS, VBLK, &mfs-vnodeops); mfsp = VTOMFS(devvp); /* * Save base address of the filesystem from the supporting process. */ copyin(data, &args, (sizeof mfs-args)); mfsp->mfs-baseoff = args.base; mfsp->mfs-size = args.size; /* * Record the process identifier of the supporting process. */ mfsp->mfs-pid = u.u-procp->p-pid; /* * Mount the filesystem. */ mfsp->mfs-buflist = NULL; mountfs(devvp, mp); /* * Loop processing I/O requests. */ while (mfsp->mfs-buflist != MFS-EXIT) { while (mfsp->mfs-buflist != NULL) { bp = mfsp->mfs-buflist; mfsp->mfs-buflist = bp->av-forw; offset = mfsp->mfs-baseoff + (bp->b-blkno * DEV-BSIZE); if (bp->b-flags & B-READ) copyin(offset, bp->b-un.b-addr, bp->b-bcount); else /* write-request */ copyout(bp->b-un.b-addr, offset, bp->b-bcount); biodone(bp); } sleep((caddr-t)devvp, PWAIT); } } /* * If the MFS process requests the I/O then we must do it directly. * Otherwise put the request on the list and request the MFS process * to be run. */ mfs_strategymfs-strategy(bp) struct buf *bp; { struct vnode *devvp; struct mfsnode *mfsp; off-t offset; devvp = bp->b-vp; mfsp = VTOMFS(devvp); if (mfsp->mfs-pid == u.u-procp->p-pid) { offset = mfsp->mfs-baseoff + (bp->b-blkno * DEV-BSIZE); if (bp->b-flags & B-READ) copyin(offset, bp->b-un.b-addr, bp->b-bcount); else /* write-request */ copyout(bp->b-un.b-addr, offset, bp->b-bcount); biodone(bp); } else { bp->av-forw = mfsp->mfs-buflist; mfsp->mfs-buflist = bp; wakeup((caddr-t)bp->b-vp); } } /* * The close routine is called by unmount after the filesystem * has been successfully unmounted. */ mfs_closemfs-close(devvp) struct vnode *devvp; { struct mfsnode *mfsp = VTOMFS(vp); struct buf *bp; /* * Finish any pending I/O requests. */ while (bp = mfsp->mfs-buflist) { mfsp->mfs-buflist = bp->av-forw; mfs-doio(bp, mfsp->mfs-baseoff); wakeup((caddr-t)bp); } /* * Send a request to the filesystem server to exit. */ mfsp->mfs-buflist = MFS-EXIT; wakeup((caddr-t)vp); }