home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / ufs / mfs_vnops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-15  |  8.5 KB  |  363 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)mfs_vnops.c    7.22 (Berkeley) 4/16/91
  34.  */
  35.  
  36. #include "param.h"
  37. #include "systm.h"
  38. #include "time.h"
  39. #include "kernel.h"
  40. #include "proc.h"
  41. #include "buf.h"
  42. #include "map.h"
  43. #include "vnode.h"
  44.  
  45. #include "mfsnode.h"
  46. #include "mfsiom.h"
  47.  
  48. #include "machine/vmparam.h"
  49. #include "machine/mtpr.h"
  50.  
  51. #if !defined(hp300) && !defined(i386)
  52. static int mfsmap_want;        /* 1 => need kernel I/O resources */
  53. struct map mfsmap[MFS_MAPSIZE];
  54. extern char mfsiobuf[];
  55. #endif
  56.  
  57. /*
  58.  * mfs vnode operations.
  59.  */
  60. struct vnodeops mfs_vnodeops = {
  61.     mfs_lookup,        /* lookup */
  62.     mfs_create,        /* create */
  63.     mfs_mknod,        /* mknod */
  64.     mfs_open,        /* open */
  65.     mfs_close,        /* close */
  66.     mfs_access,        /* access */
  67.     mfs_getattr,        /* getattr */
  68.     mfs_setattr,        /* setattr */
  69.     mfs_read,        /* read */
  70.     mfs_write,        /* write */
  71.     mfs_ioctl,        /* ioctl */
  72.     mfs_select,        /* select */
  73.     mfs_mmap,        /* mmap */
  74.     mfs_fsync,        /* fsync */
  75.     mfs_seek,        /* seek */
  76.     mfs_remove,        /* remove */
  77.     mfs_link,        /* link */
  78.     mfs_rename,        /* rename */
  79.     mfs_mkdir,        /* mkdir */
  80.     mfs_rmdir,        /* rmdir */
  81.     mfs_symlink,        /* symlink */
  82.     mfs_readdir,        /* readdir */
  83.     mfs_readlink,        /* readlink */
  84.     mfs_abortop,        /* abortop */
  85.     mfs_inactive,        /* inactive */
  86.     mfs_reclaim,        /* reclaim */
  87.     mfs_lock,        /* lock */
  88.     mfs_unlock,        /* unlock */
  89.     mfs_bmap,        /* bmap */
  90.     mfs_strategy,        /* strategy */
  91.     mfs_print,        /* print */
  92.     mfs_islocked,        /* islocked */
  93.     mfs_advlock,        /* advlock */
  94. };
  95.  
  96. /*
  97.  * Vnode Operations.
  98.  *
  99.  * Open called to allow memory filesystem to initialize and
  100.  * validate before actual IO. Record our process identifier
  101.  * so we can tell when we are doing I/O to ourself.
  102.  */
  103. /* ARGSUSED */
  104. mfs_open(vp, mode, cred, p)
  105.     register struct vnode *vp;
  106.     int mode;
  107.     struct ucred *cred;
  108.     struct proc *p;
  109. {
  110.  
  111.     if (vp->v_type != VBLK) {
  112.         panic("mfs_ioctl not VBLK");
  113.         /* NOTREACHED */
  114.     }
  115.     return (0);
  116. }
  117.  
  118. /*
  119.  * Ioctl operation.
  120.  */
  121. /* ARGSUSED */
  122. mfs_ioctl(vp, com, data, fflag, cred, p)
  123.     struct vnode *vp;
  124.     int com;
  125.     caddr_t data;
  126.     int fflag;
  127.     struct ucred *cred;
  128.     struct proc *p;
  129. {
  130.  
  131.     return (-1);
  132. }
  133.  
  134. /*
  135.  * Pass I/O requests to the memory filesystem process.
  136.  */
  137. mfs_strategy(bp)
  138.     register struct buf *bp;
  139. {
  140.     register struct mfsnode *mfsp;
  141.     struct vnode *vp;
  142.     struct proc *p = curproc;        /* XXX */
  143.  
  144.     if (vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0)
  145.         panic("mfs_strategy: bad dev");
  146.     mfsp = VTOMFS(vp);
  147.     if (mfsp->mfs_pid == p->p_pid) {
  148.         mfs_doio(bp, mfsp->mfs_baseoff);
  149.     } else {
  150.         bp->av_forw = mfsp->mfs_buflist;
  151.         mfsp->mfs_buflist = bp;
  152.         wakeup((caddr_t)vp);
  153.     }
  154.     return (0);
  155. }
  156.  
  157. #if defined(vax) || defined(tahoe)
  158. /*
  159.  * Memory file system I/O.
  160.  *
  161.  * Essentially play ubasetup() and disk interrupt service routine by
  162.  * doing the copies to or from the memfs process. If doing physio
  163.  * (i.e. pagein), we must map the I/O through the kernel virtual
  164.  * address space.
  165.  */
  166. mfs_doio(bp, base)
  167.     register struct buf *bp;
  168.     caddr_t base;
  169. {
  170.     register struct pte *pte, *ppte;
  171.     register caddr_t vaddr;
  172.     int off, npf, npf2, reg;
  173.     caddr_t kernaddr, offset;
  174.  
  175.     /*
  176.      * For phys I/O, map the b_addr into kernel virtual space using
  177.      * the Mfsiomap pte's.
  178.      */
  179.     if ((bp->b_flags & B_PHYS) == 0) {
  180.         kernaddr = bp->b_un.b_addr;
  181.     } else {
  182.         if (bp->b_flags & (B_PAGET | B_UAREA | B_DIRTY))
  183.             panic("swap on memfs?");
  184.         off = (int)bp->b_un.b_addr & PGOFSET;
  185.         npf = btoc(bp->b_bcount + off);
  186.         /*
  187.          * Get some mapping page table entries
  188.          */
  189.         while ((reg = rmalloc(mfsmap, (long)npf)) == 0) {
  190.             mfsmap_want++;
  191.             sleep((caddr_t)&mfsmap_want, PZERO-1);
  192.         }
  193.         reg--;
  194.         pte = vtopte(bp->b_proc, btop(bp->b_un.b_addr));
  195.         /*
  196.          * Do vmaccess() but with the Mfsiomap page table.
  197.          */
  198.         ppte = &Mfsiomap[reg];
  199.         vaddr = &mfsiobuf[reg * NBPG];
  200.         kernaddr = vaddr + off;
  201.         for (npf2 = npf; npf2; npf2--) {
  202.             mapin(ppte, (u_int)vaddr, pte->pg_pfnum,
  203.                 (int)(PG_V|PG_KW));
  204. #if defined(tahoe)
  205.             if ((bp->b_flags & B_READ) == 0)
  206.                 mtpr(P1DC, vaddr);
  207. #endif
  208.             ppte++;
  209.             pte++;
  210.             vaddr += NBPG;
  211.         }
  212.     }
  213.     offset = base + (bp->b_blkno << DEV_BSHIFT);
  214.     if (bp->b_flags & B_READ)
  215.         bp->b_error = copyin(offset, kernaddr, bp->b_bcount);
  216.     else
  217.         bp->b_error = copyout(kernaddr, offset, bp->b_bcount);
  218.     if (bp->b_error)
  219.         bp->b_flags |= B_ERROR;
  220.     /*
  221.      * Release pte's used by physical I/O.
  222.      */
  223.     if (bp->b_flags & B_PHYS) {
  224.         rmfree(mfsmap, (long)npf, (long)++reg);
  225.         if (mfsmap_want) {
  226.             mfsmap_want = 0;
  227.             wakeup((caddr_t)&mfsmap_want);
  228.         }
  229.     }
  230.     biodone(bp);
  231. }
  232. #endif    /* vax || tahoe */
  233.  
  234. #if defined(hp300) || defined(i386)
  235. /*
  236.  * Memory file system I/O.
  237.  *
  238.  * Trivial on the HP since buffer has already been mapping into KVA space.
  239.  */
  240. mfs_doio(bp, base)
  241.     register struct buf *bp;
  242.     caddr_t base;
  243. {
  244.     base += (bp->b_blkno << DEV_BSHIFT);
  245.     if (bp->b_flags & B_READ)
  246.         bp->b_error = copyin(base, bp->b_un.b_addr, bp->b_bcount);
  247.     else
  248.         bp->b_error = copyout(bp->b_un.b_addr, base, bp->b_bcount);
  249.     if (bp->b_error)
  250.         bp->b_flags |= B_ERROR;
  251.     biodone(bp);
  252. }
  253. #endif
  254.  
  255. /*
  256.  * This is a noop, simply returning what one has been given.
  257.  */
  258. mfs_bmap(vp, bn, vpp, bnp)
  259.     struct vnode *vp;
  260.     daddr_t bn;
  261.     struct vnode **vpp;
  262.     daddr_t *bnp;
  263. {
  264.  
  265.     if (vpp != NULL)
  266.         *vpp = vp;
  267.     if (bnp != NULL)
  268.         *bnp = bn;
  269.     return (0);
  270. }
  271.  
  272. /*
  273.  * Memory filesystem close routine
  274.  */
  275. /* ARGSUSED */
  276. mfs_close(vp, flag, cred, p)
  277.     register struct vnode *vp;
  278.     int flag;
  279.     struct ucred *cred;
  280.     struct proc *p;
  281. {
  282.     register struct mfsnode *mfsp = VTOMFS(vp);
  283.     register struct buf *bp;
  284.  
  285.     /*
  286.      * Finish any pending I/O requests.
  287.      */
  288.     while (bp = mfsp->mfs_buflist) {
  289.         mfsp->mfs_buflist = bp->av_forw;
  290.         mfs_doio(bp, mfsp->mfs_baseoff);
  291.         wakeup((caddr_t)bp);
  292.     }
  293.     /*
  294.      * On last close of a memory filesystem
  295.      * we must invalidate any in core blocks, so that
  296.      * we can, free up its vnode.
  297.      */
  298.     vflushbuf(vp, 0);
  299.     if (vinvalbuf(vp, 1))
  300.         return (0);
  301.     /*
  302.      * There should be no way to have any more uses of this
  303.      * vnode, so if we find any other uses, it is a panic.
  304.      */
  305.     if (vp->v_usecount > 1)
  306.         printf("mfs_close: ref count %d > 1\n", vp->v_usecount);
  307.     if (vp->v_usecount > 1 || mfsp->mfs_buflist)
  308.         panic("mfs_close");
  309.     /*
  310.      * Send a request to the filesystem server to exit.
  311.      */
  312.     mfsp->mfs_buflist = (struct buf *)(-1);
  313.     wakeup((caddr_t)vp);
  314.     return (0);
  315. }
  316.  
  317. /*
  318.  * Memory filesystem inactive routine
  319.  */
  320. /* ARGSUSED */
  321. mfs_inactive(vp, p)
  322.     struct vnode *vp;
  323.     struct proc *p;
  324. {
  325.  
  326.     if (VTOMFS(vp)->mfs_buflist != (struct buf *)(-1))
  327.         panic("mfs_inactive: not inactive");
  328.     return (0);
  329. }
  330.  
  331. /*
  332.  * Print out the contents of an mfsnode.
  333.  */
  334. mfs_print(vp)
  335.     struct vnode *vp;
  336. {
  337.     register struct mfsnode *mfsp = VTOMFS(vp);
  338.  
  339.     printf("tag VT_MFS, pid %d, base %d, size %d\n", mfsp->mfs_pid,
  340.         mfsp->mfs_baseoff, mfsp->mfs_size);
  341. }
  342.  
  343. /*
  344.  * Block device bad operation
  345.  */
  346. mfs_badop()
  347. {
  348.  
  349.     panic("mfs_badop called\n");
  350.     /* NOTREACHED */
  351. }
  352.  
  353. /*
  354.  * Memory based filesystem initialization.
  355.  */
  356. mfs_init()
  357. {
  358.  
  359. #if !defined(hp300) && !defined(i386)
  360.     rminit(mfsmap, (long)MFS_MAPREG, (long)1, "mfs mapreg", MFS_MAPSIZE);
  361. #endif
  362. }
  363.