|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.