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