The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ufs/mfs/mfs_vnops.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: mfs_vnops.c,v 1.36 2004/01/26 10:02:31 hannken Exp $   */
    2 
    3 /*
    4  * Copyright (c) 1989, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __KERNEL_RCSID(0, "$NetBSD: mfs_vnops.c,v 1.36 2004/01/26 10:02:31 hannken Exp $");
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/time.h>
   40 #include <sys/kernel.h>
   41 #include <sys/proc.h>
   42 #include <sys/buf.h>
   43 #include <sys/vnode.h>
   44 #include <sys/malloc.h>
   45 
   46 #include <miscfs/genfs/genfs.h>
   47 #include <miscfs/specfs/specdev.h>
   48 
   49 #include <machine/vmparam.h>
   50 
   51 #include <ufs/mfs/mfsnode.h>
   52 #include <ufs/mfs/mfs_extern.h>
   53 
   54 /*
   55  * mfs vnode operations.
   56  */
   57 int (**mfs_vnodeop_p) __P((void *));
   58 const struct vnodeopv_entry_desc mfs_vnodeop_entries[] = {
   59         { &vop_default_desc, vn_default_error },
   60         { &vop_lookup_desc, mfs_lookup },               /* lookup */
   61         { &vop_create_desc, mfs_create },               /* create */
   62         { &vop_mknod_desc, mfs_mknod },                 /* mknod */
   63         { &vop_open_desc, mfs_open },                   /* open */
   64         { &vop_close_desc, mfs_close },                 /* close */
   65         { &vop_access_desc, mfs_access },               /* access */
   66         { &vop_getattr_desc, mfs_getattr },             /* getattr */
   67         { &vop_setattr_desc, mfs_setattr },             /* setattr */
   68         { &vop_read_desc, mfs_read },                   /* read */
   69         { &vop_write_desc, mfs_write },                 /* write */
   70         { &vop_ioctl_desc, mfs_ioctl },                 /* ioctl */
   71         { &vop_poll_desc, mfs_poll },                   /* poll */
   72         { &vop_revoke_desc, mfs_revoke },               /* revoke */
   73         { &vop_mmap_desc, mfs_mmap },                   /* mmap */
   74         { &vop_fsync_desc, spec_fsync },                /* fsync */
   75         { &vop_seek_desc, mfs_seek },                   /* seek */
   76         { &vop_remove_desc, mfs_remove },               /* remove */
   77         { &vop_link_desc, mfs_link },                   /* link */
   78         { &vop_rename_desc, mfs_rename },               /* rename */
   79         { &vop_mkdir_desc, mfs_mkdir },                 /* mkdir */
   80         { &vop_rmdir_desc, mfs_rmdir },                 /* rmdir */
   81         { &vop_symlink_desc, mfs_symlink },             /* symlink */
   82         { &vop_readdir_desc, mfs_readdir },             /* readdir */
   83         { &vop_readlink_desc, mfs_readlink },           /* readlink */
   84         { &vop_abortop_desc, mfs_abortop },             /* abortop */
   85         { &vop_inactive_desc, mfs_inactive },           /* inactive */
   86         { &vop_reclaim_desc, mfs_reclaim },             /* reclaim */
   87         { &vop_lock_desc, mfs_lock },                   /* lock */
   88         { &vop_unlock_desc, mfs_unlock },               /* unlock */
   89         { &vop_bmap_desc, mfs_bmap },                   /* bmap */
   90         { &vop_strategy_desc, mfs_strategy },           /* strategy */
   91         { &vop_print_desc, mfs_print },                 /* print */
   92         { &vop_islocked_desc, mfs_islocked },           /* islocked */
   93         { &vop_pathconf_desc, mfs_pathconf },           /* pathconf */
   94         { &vop_advlock_desc, mfs_advlock },             /* advlock */
   95         { &vop_blkatoff_desc, mfs_blkatoff },           /* blkatoff */
   96         { &vop_valloc_desc, mfs_valloc },               /* valloc */
   97         { &vop_vfree_desc, mfs_vfree },                 /* vfree */
   98         { &vop_truncate_desc, mfs_truncate },           /* truncate */
   99         { &vop_update_desc, mfs_update },               /* update */
  100         { &vop_bwrite_desc, mfs_bwrite },               /* bwrite */
  101         { &vop_putpages_desc, mfs_putpages },           /* putpages */
  102         { NULL, NULL }
  103 };
  104 const struct vnodeopv_desc mfs_vnodeop_opv_desc =
  105         { &mfs_vnodeop_p, mfs_vnodeop_entries };
  106 
  107 /*
  108  * Vnode Operations.
  109  *
  110  * Open called to allow memory filesystem to initialize and
  111  * validate before actual IO. Record our process identifier
  112  * so we can tell when we are doing I/O to ourself.
  113  */
  114 /* ARGSUSED */
  115 int
  116 mfs_open(v)
  117         void *v;
  118 {
  119         struct vop_open_args /* {
  120                 struct vnode *a_vp;
  121                 int  a_mode;
  122                 struct ucred *a_cred;
  123                 struct proc *a_p;
  124         } */ *ap = v;
  125 
  126         if (ap->a_vp->v_type != VBLK) {
  127                 panic("mfs_ioctl not VBLK");
  128                 /* NOTREACHED */
  129         }
  130         return (0);
  131 }
  132 
  133 /*
  134  * Pass I/O requests to the memory filesystem process.
  135  */
  136 int
  137 mfs_strategy(v)
  138         void *v;
  139 {
  140         struct vop_strategy_args /* {
  141                 struct vnode *a_vp;
  142                 struct buf *a_bp;
  143         } */ *ap = v;
  144         struct vnode *vp = ap->a_vp;
  145         struct buf *bp = ap->a_bp;
  146         struct mfsnode *mfsp;
  147         struct proc *p = curproc;               /* XXX */
  148 
  149         if (vp->v_type != VBLK || vp->v_usecount == 0)
  150                 panic("mfs_strategy: bad dev");
  151         mfsp = VTOMFS(vp);
  152         /* check for mini-root access */
  153         if (mfsp->mfs_proc == NULL) {
  154                 caddr_t base;
  155 
  156                 base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT);
  157                 if (bp->b_flags & B_READ)
  158                         memcpy(bp->b_data, base, bp->b_bcount);
  159                 else
  160                         memcpy(base, bp->b_data, bp->b_bcount);
  161                 bp->b_resid = 0;
  162                 biodone(bp);
  163         } else if (mfsp->mfs_proc == p) {
  164                 mfs_doio(bp, mfsp->mfs_baseoff);
  165         } else if (doing_shutdown) {
  166                 /* 
  167                  * bitbucket I/O during shutdown.
  168                  * Note that reads should *not* happen here, but..
  169                  */
  170                 if (bp->b_flags & B_READ)
  171                         printf("warning: mfs read during shutdown\n");
  172                 bp->b_resid = 0;
  173                 biodone(bp);
  174         } else {
  175                 BUFQ_PUT(&mfsp->mfs_buflist, bp);
  176                 wakeup((caddr_t)vp);
  177         }
  178         return (0);
  179 }
  180 
  181 /*
  182  * Memory file system I/O.
  183  *
  184  * Trivial on the HP since buffer has already been mapping into KVA space.
  185  */
  186 void
  187 mfs_doio(bp, base)
  188         struct buf *bp;
  189         caddr_t base;
  190 {
  191         base += (bp->b_blkno << DEV_BSHIFT);
  192         if (bp->b_flags & B_READ)
  193                 bp->b_error = copyin(base, bp->b_data, bp->b_bcount);
  194         else
  195                 bp->b_error = copyout(bp->b_data, base, bp->b_bcount);
  196         if (bp->b_error)
  197                 bp->b_flags |= B_ERROR;
  198         else
  199                 bp->b_resid = 0;
  200         biodone(bp);
  201 }
  202 
  203 /*
  204  * This is a noop, simply returning what one has been given.
  205  */
  206 int
  207 mfs_bmap(v)
  208         void *v;
  209 {
  210         struct vop_bmap_args /* {
  211                 struct vnode *a_vp;
  212                 daddr_t  a_bn;
  213                 struct vnode **a_vpp;
  214                 daddr_t *a_bnp;
  215                 int *a_runp;
  216         } */ *ap = v;
  217 
  218         if (ap->a_vpp != NULL)
  219                 *ap->a_vpp = ap->a_vp;
  220         if (ap->a_bnp != NULL)
  221                 *ap->a_bnp = ap->a_bn;
  222         if (ap->a_runp != NULL)
  223                  *ap->a_runp = 0;
  224         return (0);
  225 }
  226 
  227 /*
  228  * Memory filesystem close routine
  229  */
  230 /* ARGSUSED */
  231 int
  232 mfs_close(v)
  233         void *v;
  234 {
  235         struct vop_close_args /* {
  236                 struct vnode *a_vp;
  237                 int  a_fflag;
  238                 struct ucred *a_cred;
  239                 struct proc *a_p;
  240         } */ *ap = v;
  241         struct vnode *vp = ap->a_vp;
  242         struct mfsnode *mfsp = VTOMFS(vp);
  243         struct buf *bp;
  244         int error;
  245 
  246         /*
  247          * Finish any pending I/O requests.
  248          */
  249         while ((bp = BUFQ_GET(&mfsp->mfs_buflist)) != NULL) {
  250                 mfs_doio(bp, mfsp->mfs_baseoff);
  251                 wakeup((caddr_t)bp);
  252         }
  253         /*
  254          * On last close of a memory filesystem
  255          * we must invalidate any in core blocks, so that
  256          * we can, free up its vnode.
  257          */
  258         if ((error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 0, 0)) != 0)
  259                 return (error);
  260         /*
  261          * There should be no way to have any more uses of this
  262          * vnode, so if we find any other uses, it is a panic.
  263          */
  264         if (vp->v_usecount > 1)
  265                 printf("mfs_close: ref count %d > 1\n", vp->v_usecount);
  266         if (vp->v_usecount > 1 || BUFQ_PEEK(&mfsp->mfs_buflist) != NULL)
  267                 panic("mfs_close");
  268         /*
  269          * Send a request to the filesystem server to exit.
  270          */
  271         mfsp->mfs_shutdown = 1;
  272         wakeup((caddr_t)vp);
  273         return (0);
  274 }
  275 
  276 /*
  277  * Memory filesystem inactive routine
  278  */
  279 /* ARGSUSED */
  280 int
  281 mfs_inactive(v)
  282         void *v;
  283 {
  284         struct vop_inactive_args /* {
  285                 struct vnode *a_vp;
  286                 struct proc *a_p;
  287         } */ *ap = v;
  288         struct vnode *vp = ap->a_vp;
  289         struct mfsnode *mfsp = VTOMFS(vp);
  290 
  291         if (BUFQ_PEEK(&mfsp->mfs_buflist) != NULL)
  292                 panic("mfs_inactive: not inactive (mfs_buflist %p)",
  293                         BUFQ_PEEK(&mfsp->mfs_buflist));
  294         VOP_UNLOCK(vp, 0);
  295         return (0);
  296 }
  297 
  298 /*
  299  * Reclaim a memory filesystem devvp so that it can be reused.
  300  */
  301 int
  302 mfs_reclaim(v)
  303         void *v;
  304 {
  305         struct vop_reclaim_args /* {
  306                 struct vnode *a_vp;
  307         } */ *ap = v;
  308         struct vnode *vp = ap->a_vp;
  309 
  310         FREE(vp->v_data, M_MFSNODE);
  311         vp->v_data = NULL;
  312         return (0);
  313 }
  314 
  315 /*
  316  * Print out the contents of an mfsnode.
  317  */
  318 int
  319 mfs_print(v)
  320         void *v;
  321 {
  322         struct vop_print_args /* {
  323                 struct vnode *a_vp;
  324         } */ *ap = v;
  325         struct mfsnode *mfsp = VTOMFS(ap->a_vp);
  326 
  327         printf("tag VT_MFS, pid %d, base %p, size %ld\n",
  328             (mfsp->mfs_proc != NULL) ? mfsp->mfs_proc->p_pid : 0,
  329             mfsp->mfs_baseoff, mfsp->mfs_size);
  330         return (0);
  331 }

Cache object: 7ac146ea0065c6d5d1e51b1ab8672c73


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.