MFS - Fix mmap issues with files under MFS
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 31 Aug 2009 21:52:08 +0000 (14:52 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 31 Aug 2009 21:52:08 +0000 (14:52 -0700)
* MFS relied on specfs to supply a getpages function.  specfs no longer
  exists and MFS's constructed vnode did not point at devfs.

  Instead of synthesizing a vnode access the real devfs vnode associated
  with /dev/mfs%d.

* Remove the MFS vnops for its synthesized vnode.  MFS now uses a devfs
  vnode which uses the devfs vnops.

Reported-by: Thomas Nikolajsen <thomas.nikolajsen@mail.dk>:
sys/conf/files
sys/vfs/mfs/Makefile
sys/vfs/mfs/mfs_extern.h
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/mfs/mfs_vnops.c [deleted file]
sys/vfs/mfs/mfsnode.h

index 8205413..db260bd 100644 (file)
@@ -1379,7 +1379,6 @@ vfs/ufs/ffs_vnops.c               optional ffs
 vfs/ufs/ffs_vnops.c            optional mfs
 vfs/ufs/ffs_rawread.c          optional directio
 vfs/mfs/mfs_vfsops.c           optional mfs
-vfs/mfs/mfs_vnops.c            optional mfs
 vfs/ufs/ufs_bmap.c             standard
 vfs/ufs/ufs_ihash.c            standard
 vfs/ufs/ufs_inode.c            standard
index e4e5ba0..b6687e3 100644 (file)
@@ -2,6 +2,6 @@
 # $DragonFly: src/sys/vfs/mfs/Makefile,v 1.5 2006/05/11 08:23:20 swildner Exp $
 
 KMOD=  mfs
-SRCS=  mfs_vfsops.c mfs_vnops.c
+SRCS=  mfs_vfsops.c
 
 .include <bsd.kmod.mk>
index a8b07c8..7b32824 100644 (file)
@@ -44,7 +44,6 @@ struct mount;
 struct thread;
 struct vnode;
 
-void   mfs_doio (struct bio *bio, struct mfsnode *mfsnode);
 u_char *mfs_getimage (void);
 int    mfs_mountfs (struct vnode *, struct mount *, struct thread *);
 int    mfs_mountroot (void);
index 2284d67..0e367ec 100644 (file)
 #include <sys/signal2.h>
 #include <sys/vnode.h>
 #include <sys/malloc.h>
+#include <sys/sysproto.h>
+#include <sys/mman.h>
 #include <sys/linker.h>
 #include <sys/fcntl.h>
+#include <sys/nlookup.h>
+#include <sys/devfs.h>
 
 #include <vm/vm.h>
 #include <vm/vm_object.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pager.h>
 #include <vm/vnode_pager.h>
+#include <vm/vm_extern.h>
 
 #include <sys/buf2.h>
 #include <sys/thread2.h>
 
 MALLOC_DEFINE(M_MFSNODE, "MFS node", "MFS vnode private part");
 
-extern struct vop_ops *mfs_vnode_vops_p;
-
 static int     mfs_mount (struct mount *mp,
                        char *path, caddr_t data, struct ucred *td);
 static int     mfs_start (struct mount *mp, int flags);
 static int     mfs_statfs (struct mount *mp, struct statfs *sbp,
                        struct ucred *cred); 
 static int     mfs_init (struct vfsconf *);
+static void    mfs_doio(struct bio *bio, struct mfsnode *mfsp);
 
 d_open_t       mfsopen;
 d_close_t      mfsclose;
@@ -122,8 +126,10 @@ mfsopen(struct dev_open_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
 
+#if 0
        if (ap->a_oflags & FWRITE)
                return(EROFS);
+#endif
        if (dev->si_drv1)
                return(0);
        return(ENXIO);
@@ -132,6 +138,13 @@ mfsopen(struct dev_open_args *ap)
 int
 mfsclose(struct dev_close_args *ap)
 {
+       cdev_t dev = ap->a_head.a_dev;
+       struct mfsnode *mfsp;
+
+       if ((mfsp = dev->si_drv1) == NULL)
+               return(0);
+        mfsp->mfs_active = 0;
+        wakeup((caddr_t)mfsp);
        return(0);
 }
 
@@ -170,8 +183,12 @@ mfsstrategy(struct dev_strategy_args *ap)
        /*
         * Initiate I/O
         */
-       bioq_insert_tail(&mfsp->bio_queue, bio);
-       wakeup((caddr_t)mfsp);
+       if (mfsp->mfs_td == curthread) {
+               mfs_doio(bio, mfsp);
+       } else {
+               bioq_insert_tail(&mfsp->bio_queue, bio);
+               wakeup((caddr_t)mfsp);
+       }
        return(0);
 
        /*
@@ -232,9 +249,12 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
        struct ufsmount *ump;
        struct fs *fs;
        struct mfsnode *mfsp;
+       struct nlookupdata nd;
        size_t size;
-       int flags, err;
+       char devname[16];
+       int flags;
        int minnum;
+       int error;
        cdev_t dev;
 
        /*
@@ -251,6 +271,8 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                panic("mfs_mount: mount MFS as root: not configured!");
        }
 
+       mfsp = NULL;
+
        /*
         ***
         * Mounting non-root file system or updating a file system
@@ -258,7 +280,8 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
         */
 
        /* copy in user arguments*/
-       if ((err = copyin(data, (caddr_t)&args, sizeof (struct mfs_args))) != 0)
+       error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args));
+       if (error)
                goto error_1;
 
        /*
@@ -277,8 +300,8 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                        flags = WRITECLOSE;
                        if (mp->mnt_flag & MNT_FORCE)
                                flags |= FORCECLOSE;
-                       err = ffs_flushfiles(mp, flags);
-                       if (err)
+                       error = ffs_flushfiles(mp, flags);
+                       if (error)
                                goto error_1;
                }
                if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
@@ -291,46 +314,54 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                         * Process export requests.  Jumping to "success"
                         * will return the vfs_export() error code. 
                         */
-                       err = vfs_export(mp, &ump->um_export, &args.export);
+                       error = vfs_export(mp, &ump->um_export, &args.export);
                        goto success;
                }
 
                /* XXX MFS does not support name updating*/
                goto success;
        }
+
        /*
-        * Do the MALLOC before the getnewvnode since doing so afterward
+        * Do the MALLOC before the make_dev since doing so afterward
         * might cause a bogus v_data pointer to get dereferenced
         * elsewhere if MALLOC should block.
         */
-       MALLOC(mfsp, struct mfsnode *, sizeof *mfsp, M_MFSNODE, M_WAITOK);
-
-       err = getspecialvnode(VT_MFS, NULL, &mfs_vnode_vops_p, &devvp, 0, 0);
-       if (err) {
-               FREE(mfsp, M_MFSNODE);
-               goto error_1;
-       }
+       MALLOC(mfsp, struct mfsnode *, sizeof *mfsp, M_MFSNODE,
+              M_WAITOK|M_ZERO);
 
-       minnum = (curproc->p_pid & 0xFF) |
-               ((curproc->p_pid & ~0xFF) << 8);
+       minnum = (int)curproc->p_pid;
 
-       devvp->v_type = VCHR;
        dev = make_dev(&mfs_ops, minnum, UID_ROOT, GID_WHEEL, 0600,
-                      "MFS%d", minnum >> 16);
+                      "mfs%d", minnum);
        /* It is not clear that these will get initialized otherwise */
        dev->si_bsize_phys = DEV_BSIZE;
        dev->si_iosize_max = DFLTPHYS;
        dev->si_drv1 = mfsp;
-       addaliasu(devvp, mfs_ops.head.maj, minnum);
-       devvp->v_data = mfsp;
        mfsp->mfs_baseoff = args.base;
        mfsp->mfs_size = args.size;
-       mfsp->mfs_vnode = devvp;
-       mfsp->mfs_dev = reference_dev(dev);
+       mfsp->mfs_dev = dev;
        mfsp->mfs_td = curthread;
        mfsp->mfs_active = 1;
        bioq_init(&mfsp->bio_queue);
 
+       devfs_config(); /* sync devfs work */
+       ksnprintf(devname, sizeof(devname), "/dev/mfs%d", minnum);
+       nlookup_init(&nd, devname, UIO_SYSSPACE, 0);
+       devvp = NULL;
+       error = nlookup(&nd);
+       if (error == 0) {
+               devvp = nd.nl_nch.ncp->nc_vp;
+               if (devvp == NULL)
+                       error = ENOENT;
+               error = vget(devvp, LK_SHARED);
+       }
+       nlookup_done(&nd);
+
+       if (error)
+               goto error_1;
+       vn_unlock(devvp);
+
        /*
         * Our 'block' device must be backed by a VM object.  Theoretically
         * we could use the anonymous memory VM object supplied by userland,
@@ -342,19 +373,18 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
         * being referenced externally.  We have to undo the refs for
         * the self reference between vnode and object.
         */
-       vnode_pager_alloc(devvp, args.size, 0, 0);
-       vrele(devvp);
-       --devvp->v_object->ref_count;
+       vnode_pager_setsize(devvp, args.size);
 
        /* Save "mounted from" info for mount point (NULL pad)*/
-       copyinstr(      args.fspec,                     /* device name*/
-                       mp->mnt_stat.f_mntfromname,     /* save area*/
-                       MNAMELEN - 1,                   /* max size*/
-                       &size);                         /* real size*/
-       bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
-
-       vx_unlock(devvp);
-       if ((err = ffs_mountfs(devvp, mp, M_MFSNODE)) != 0) { 
+       copyinstr(args.fspec,                   /* device name*/
+                 mp->mnt_stat.f_mntfromname,   /* save area*/
+                 MNAMELEN - 1,                 /* max size*/
+                 &size);                       /* real size*/
+       bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+       /* vref is eaten by mount? */
+
+       error = ffs_mountfs(devvp, mp, M_MFSNODE);
+       if (error) {
                mfsp->mfs_active = 0;
                goto error_2;
        }
@@ -370,14 +400,19 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
        goto success;
 
 error_2:       /* error with devvp held*/
-
-       /* release devvp before failing*/
        vrele(devvp);
 
 error_1:       /* no state to back out*/
+       if (mfsp) {
+               if (mfsp->mfs_dev) {
+                       destroy_dev(mfsp->mfs_dev);
+                       mfsp->mfs_dev = NULL;
+               }
+               FREE(mfsp, M_MFSNODE);
+       }
 
 success:
-       return( err);
+       return(error);
 }
 
 /*
@@ -393,7 +428,7 @@ static int
 mfs_start(struct mount *mp, int flags)
 {
        struct vnode *vp = VFSTOUFS(mp)->um_devvp;
-       struct mfsnode *mfsp = VTOMFS(vp);
+       struct mfsnode *mfsp = vp->v_rdev->si_drv1;
        struct bio *bio;
        struct buf *bp;
        int gotsig = 0, sig;
@@ -449,8 +484,11 @@ mfs_start(struct mount *mp, int flags)
                        gotsig++;       /* try to unmount in next pass */
        }
        PRELE(curproc);
-       v_release_rdev(vp);     /* hack because we do not implement CLOSE */
-       /* XXX destroy/release devvp */
+        if (mfsp->mfs_dev) {
+                destroy_dev(mfsp->mfs_dev);
+                mfsp->mfs_dev = NULL;
+        }
+       FREE(mfsp, M_MFSNODE);
        return (0);
 }
 
@@ -475,3 +513,71 @@ mfs_init(struct vfsconf *vfsp)
 {
        return (0);
 }
+
+/*
+ * Memory file system I/O.
+ *
+ * Trivial on the HP since buffer has already been mapping into KVA space.
+ *
+ * Read and Write are handled with a simple copyin and copyout.
+ *
+ * We also partially support VOP_FREEBLKS().  We can't implement
+ * completely -- for example, on fragments or inode metadata, but we can
+ * implement it for page-aligned requests.
+ */
+static void
+mfs_doio(struct bio *bio, struct mfsnode *mfsp)
+{
+       struct buf *bp = bio->bio_buf;
+       caddr_t base = mfsp->mfs_baseoff + bio->bio_offset;
+       int bytes;
+
+       switch(bp->b_cmd) {
+       case BUF_CMD_FREEBLKS:
+               /*
+                * Implement FREEBLKS, which allows the filesystem to tell
+                * a block device when blocks are no longer needed (like when
+                * a file is deleted).  We use the hook to MADV_FREE the VM.
+                * This makes an MFS filesystem work as well or better then
+                * a sun-style swap-mounted filesystem.
+                */
+               bytes = bp->b_bcount;
+
+               if ((vm_offset_t)base & PAGE_MASK) {
+                       int n = PAGE_SIZE - ((vm_offset_t)base & PAGE_MASK);
+                       bytes -= n;
+                       base += n;
+               }
+                if (bytes > 0) {
+                        struct madvise_args uap;
+
+                       bytes &= ~PAGE_MASK;
+                       if (bytes != 0) {
+                               bzero(&uap, sizeof(uap));
+                               uap.addr  = base;
+                               uap.len   = bytes;
+                               uap.behav = MADV_FREE;
+                               sys_madvise(&uap);
+                       }
+                }
+               bp->b_error = 0;
+               break;
+       case BUF_CMD_READ:
+               /*
+                * Read data from our 'memory' disk
+                */
+               bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
+               break;
+       case BUF_CMD_WRITE:
+               /*
+                * Write data to our 'memory' disk
+                */
+               bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
+               break;
+       default:
+               panic("mfs: bad b_cmd %d\n", bp->b_cmd);
+       }
+       if (bp->b_error)
+               bp->b_flags |= B_ERROR;
+       biodone(bio);
+}
diff --git a/sys/vfs/mfs/mfs_vnops.c b/sys/vfs/mfs/mfs_vnops.c
deleted file mode 100644 (file)
index 62935e8..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (c) 1989, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *     @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95
- * $FreeBSD: src/sys/ufs/mfs/mfs_vnops.c,v 1.47.2.1 2001/05/22 02:06:43 bp Exp $
- * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.37 2007/08/13 17:31:56 dillon Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/sysproto.h>
-#include <sys/mman.h>
-#include <sys/conf.h>
-
-#include <vm/vm.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pager.h>
-#include <vm/vnode_pager.h>
-
-#include <sys/buf2.h>
-#include <sys/thread2.h>
-
-#include "mfsnode.h"
-#include "mfs_extern.h"
-
-static int     mfs_badop (struct vop_generic_args *);
-static int     mfs_bmap (struct vop_bmap_args *);
-static int     mfs_close (struct vop_close_args *);
-static int     mfs_fsync (struct vop_fsync_args *);
-static int     mfs_freeblks (struct vop_freeblks_args *);
-static int     mfs_inactive (struct vop_inactive_args *); /* XXX */
-static int     mfs_open (struct vop_open_args *);
-static int     mfs_reclaim (struct vop_reclaim_args *); /* XXX */
-static int     mfs_print (struct vop_print_args *); /* XXX */
-static int     mfs_strategy (struct vop_strategy_args *); /* XXX */
-/*
- * mfs vnode operations.  Note: the vops here are used for the MFS block
- * device, not for operations on files (MFS calls the ffs mount code for that)
- */
-static struct vop_ops mfs_vnode_vops = {
-       .vop_default =          mfs_badop,
-       .vop_bmap =             mfs_bmap,
-       .vop_close =            mfs_close,
-       .vop_freeblks =         mfs_freeblks,
-       .vop_fsync =            mfs_fsync,
-       .vop_inactive =         mfs_inactive,
-       .vop_ioctl =            (void *)vop_enotty,
-       .vop_open =             mfs_open,
-       .vop_print =            mfs_print,
-       .vop_reclaim =          mfs_reclaim,
-       .vop_strategy =         mfs_strategy,
-};
-
-struct vop_ops *mfs_vnode_vops_p = &mfs_vnode_vops;
-
-VNODEOP_SET(mfs_vnode_vops);
-
-/*
- * Vnode Operations.
- *
- * Open called to allow memory filesystem to initialize and
- * validate before actual IO. Record our process identifier
- * so we can tell when we are doing I/O to ourself.
- *
- * NOTE: new device sequencing.  mounts check the device reference count
- * before calling open, so we must associate the device in open and 
- * disassociate it in close rather then faking it when we created the vnode.
- *
- * mfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
- *         struct file *a_fp)
- */
-/* ARGSUSED */
-static int
-mfs_open(struct vop_open_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-       struct mfsnode *mfsp = VTOMFS(vp);
-
-       if (vp->v_type != VCHR)
-               panic("mfs_open not VCHR");
-       if (vp->v_rdev == NULL)
-               v_associate_rdev(vp, mfsp->mfs_dev);
-       return (vop_stdopen(ap));
-}
-
-static int
-mfs_fsync(struct vop_fsync_args *ap)
-{
-       return (0);
-}
-
-/*
- * mfs_freeblks() - hook to allow us to free physical memory.
- *
- *     We implement the BUF_CMD_FREEBLKS strategy.  We can't just madvise()
- *     here because we have to do it in the correct order vs other bio
- *     requests, so we queue it.
- *
- *     Note: geteblk() sets B_INVAL.  We leave it set to guarentee buffer
- *     throw-away on brelse()? XXX
- *
- * mfs_freeblks(struct vnode *a_vp, daddr_t a_addr, daddr_t a_length)
- */
-static int
-mfs_freeblks(struct vop_freeblks_args *ap)
-{       
-       struct buf *bp;
-       struct vnode *vp = ap->a_vp;
-
-       bp = geteblk(ap->a_length);
-       bp->b_cmd = BUF_CMD_FREEBLKS;
-       bp->b_bio1.bio_offset = ap->a_offset;
-       bp->b_bcount = ap->a_length;
-       BUF_KERNPROC(bp);
-       vn_strategy(vp, &bp->b_bio1);
-       return(0);
-}
-
-/*
- * Pass I/O requests to the memory filesystem process.
- *
- * mfs_strategy(struct vnode *a_vp, struct bio *a_bio)
- */
-static int
-mfs_strategy(struct vop_strategy_args *ap)
-{
-       struct bio *bio = ap->a_bio;
-       struct buf *bp = bio->bio_buf;
-       struct mfsnode *mfsp;
-       struct thread *td = curthread;          /* XXX */
-
-       mfsp = ap->a_vp->v_rdev->si_drv1;
-       if (mfsp == NULL) {
-               bp->b_error = ENXIO;
-               bp->b_flags |= B_ERROR;
-               biodone(bio);
-               return(0);
-       }
-
-       /*
-        * splbio required for queueing/dequeueing, in case of forwarded
-        * BPs from bio interrupts (?).  It may not be necessary.
-        */
-
-       crit_enter();
-
-       if (mfsp->mfs_td == NULL) {
-               /*
-                * mini-root.  Note: BUF_CMD_FREEBLKS not supported at the
-                * moment, since we do not know what kind of dataspace
-                * b_data is in.
-                */
-               caddr_t base;
-
-               base = mfsp->mfs_baseoff + bio->bio_offset;
-               switch(bp->b_cmd) {
-               case BUF_CMD_FREEBLKS:
-                       break;
-               case BUF_CMD_READ:
-                       bcopy(base, bp->b_data, bp->b_bcount);
-                       break;
-               case BUF_CMD_WRITE:
-                       bcopy(bp->b_data, base, bp->b_bcount);
-                       break;
-               default:
-                       panic("mfs: bad b_cmd %d\n", bp->b_cmd);
-               }
-               biodone(bio);
-       } else if (mfsp->mfs_td == td) {
-               /*
-                * VOP to self
-                */
-               crit_exit();
-               mfs_doio(bio, mfsp);
-               crit_enter();
-       } else {
-               /*
-                * VOP from some other process, queue to MFS process and
-                * wake it up.
-                */
-               bioq_insert_tail(&mfsp->bio_queue, bio);
-               wakeup((caddr_t)mfsp);
-       }
-       crit_exit();
-       return (0);
-}
-
-/*
- * Memory file system I/O.
- *
- * Trivial on the HP since buffer has already been mapping into KVA space.
- *
- * Read and Write are handled with a simple copyin and copyout.    
- *
- * We also partially support VOP_FREEBLKS().  We can't implement
- * completely -- for example, on fragments or inode metadata, but we can
- * implement it for page-aligned requests.
- */
-void
-mfs_doio(struct bio *bio, struct mfsnode *mfsp)
-{
-       struct buf *bp = bio->bio_buf;
-       caddr_t base = mfsp->mfs_baseoff + bio->bio_offset;
-       int bytes;
-
-       switch(bp->b_cmd) {
-       case BUF_CMD_FREEBLKS:
-               /*
-                * Implement FREEBLKS, which allows the filesystem to tell
-                * a block device when blocks are no longer needed (like when
-                * a file is deleted).  We use the hook to MADV_FREE the VM.
-                * This makes an MFS filesystem work as well or better then
-                * a sun-style swap-mounted filesystem.
-                */
-               bytes = bp->b_bcount;
-
-               if ((vm_offset_t)base & PAGE_MASK) {
-                       int n = PAGE_SIZE - ((vm_offset_t)base & PAGE_MASK);
-                       bytes -= n;
-                       base += n;
-               }
-                if (bytes > 0) {
-                        struct madvise_args uap;
-
-                       bytes &= ~PAGE_MASK;
-                       if (bytes != 0) {
-                               bzero(&uap, sizeof(uap));
-                               uap.addr  = base;
-                               uap.len   = bytes;
-                               uap.behav = MADV_FREE;
-                               sys_madvise(&uap);
-                       }
-                }
-               bp->b_error = 0;
-               break;
-       case BUF_CMD_READ:
-               /*
-                * Read data from our 'memory' disk
-                */
-               bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
-               break;
-       case BUF_CMD_WRITE:
-               /*
-                * Write data to our 'memory' disk
-                */
-               bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
-               break;
-       default:
-               panic("mfs: bad b_cmd %d\n", bp->b_cmd);
-       }
-       if (bp->b_error)
-               bp->b_flags |= B_ERROR;
-       biodone(bio);
-}
-
-/*
- * This is a noop, simply returning what one has been given.
- *
- * mfs_bmap(struct vnode *a_vp, off_t a_loffset,
- *         off_t *a_doffsetp, int *a_runp, int *a_runb)
- */
-static int
-mfs_bmap(struct vop_bmap_args *ap)
-{
-       if (ap->a_doffsetp != NULL)
-               *ap->a_doffsetp = ap->a_loffset;
-       if (ap->a_runp != NULL)
-               *ap->a_runp = 0;
-       if (ap->a_runb != NULL)
-               *ap->a_runb = 0;
-       return (0);
-}
-
-/*
- * Memory filesystem close routine
- *
- * mfs_close(struct vnode *a_vp, int a_fflag)
- */
-/* ARGSUSED */
-static int
-mfs_close(struct vop_close_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-       struct mfsnode *mfsp = VTOMFS(vp);
-       struct bio *bio;
-       int error = 0;
-
-       /*
-        * Finish any pending I/O requests.
-        */
-       while ((bio = bioq_first(&mfsp->bio_queue)) != NULL) {
-               bioq_remove(&mfsp->bio_queue, bio);
-               mfs_doio(bio, mfsp);
-               wakeup((caddr_t)bio->bio_buf);
-       }
-
-       /*
-        * We really only care about the last close
-        */
-       if (vp->v_opencount > 1)
-               goto done;
-
-       /*
-        * Synchronize any remaining buffers and then destroy them.
-        */
-       if ((error = vinvalbuf(vp, V_SAVE, 0, 0)) != 0)
-               goto done;
-
-       /*
-        * Get rid of the pseudo-backing object.  Since the object is
-        * not directly memory mapped, we don't have to worry about 
-        * synchronizing it.
-        */
-       if (vp->v_object)
-               vm_pager_deallocate(vp->v_object);
-
-       /*
-        * There should be no way to have any more uses of this
-        * vnode, so if we find any other uses, it is a panic.
-        */
-       if (vp->v_sysref.refcnt > 1)
-               kprintf("mfs_close: ref count %d > 1\n", vp->v_sysref.refcnt);
-       if (vp->v_sysref.refcnt > 1 || (bioq_first(&mfsp->bio_queue) != NULL))
-               panic("mfs_close");
-       /*
-        * Send a request to the filesystem server to exit.
-        */
-       mfsp->mfs_active = 0;
-       v_release_rdev(vp);
-       if (mfsp->mfs_dev) {
-               destroy_dev(mfsp->mfs_dev);
-               mfsp->mfs_dev = NULL;
-       }
-       wakeup((caddr_t)mfsp);
-done:
-       vop_stdclose(ap);
-       return (error);
-}
-
-/*
- * Memory filesystem inactive routine
- *
- * mfs_inactive(struct vnode *a_vp)
- */
-/* ARGSUSED */
-static int
-mfs_inactive(struct vop_inactive_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-       struct mfsnode *mfsp = VTOMFS(vp);
-
-       if (bioq_first(&mfsp->bio_queue) != NULL)
-               panic("mfs_inactive: not inactive (next buffer %p)",
-                       bioq_first(&mfsp->bio_queue));
-       return (0);
-}
-
-/*
- * Reclaim a memory filesystem devvp so that it can be reused.
- *
- * mfs_reclaim(struct vnode *a_vp)
- */
-static int
-mfs_reclaim(struct vop_reclaim_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-
-       FREE(vp->v_data, M_MFSNODE);
-       vp->v_data = NULL;
-       return (0);
-}
-
-/*
- * Print out the contents of an mfsnode.
- *
- * mfs_print(struct vnode *a_vp)
- */
-static int
-mfs_print(struct vop_print_args *ap)
-{
-       struct mfsnode *mfsp = VTOMFS(ap->a_vp);
-
-       kprintf("tag VT_MFS, td %p, base %p, size %ld\n",
-           mfsp->mfs_td, (void *)mfsp->mfs_baseoff, mfsp->mfs_size);
-       return (0);
-}
-
-/*
- * Block device bad operation
- */
-static int
-mfs_badop(struct vop_generic_args *ap)
-{
-       int i;
-
-       kprintf("mfs_badop[%s]\n", ap->a_desc->sd_name);
-       i = vop_defaultop(ap);
-       kprintf("mfs_badop[%s] = %d\n", ap->a_desc->sd_name, i);
-       return (i);
-}
-
index 742a206..53a9a51 100644 (file)
@@ -43,7 +43,6 @@
  */
 
 struct mfsnode {
-       struct  vnode *mfs_vnode;       /* vnode associated with this mfsnode */
        caddr_t mfs_baseoff;            /* base of file system in memory */
        long    mfs_size;               /* size of memory file system */
        struct thread *mfs_td;          /* supporting thread */
@@ -53,12 +52,6 @@ struct mfsnode {
        long    mfs_spare[1];
 };
 
-/*
- * Convert between mfsnode pointers and vnode pointers
- */
-#define VTOMFS(vp)     ((struct mfsnode *)(vp)->v_data)
-#define MFSTOV(mfsp)   ((mfsp)->mfs_vnode)
-
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_MFSNODE);
 #endif