|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 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: * @(#)vm_sw.c 7.14 (Berkeley) 6/28/90 ! 21: */ ! 22: ! 23: #include "param.h" ! 24: #include "systm.h" ! 25: #include "buf.h" ! 26: #include "conf.h" ! 27: #include "user.h" ! 28: #include "vnode.h" ! 29: #include "specdev.h" ! 30: #include "map.h" ! 31: #include "file.h" ! 32: ! 33: /* ! 34: * Indirect driver for multi-controller paging. ! 35: */ ! 36: swstrategy(bp) ! 37: register struct buf *bp; ! 38: { ! 39: int sz, off, seg, index; ! 40: register struct swdevt *sp; ! 41: struct vnode *vp; ! 42: ! 43: #ifdef GENERIC ! 44: /* ! 45: * A mini-root gets copied into the front of the swap ! 46: * and we run over top of the swap area just long ! 47: * enough for us to do a mkfs and restor of the real ! 48: * root (sure beats rewriting standalone restor). ! 49: */ ! 50: #define MINIROOTSIZE 4096 ! 51: if (rootdev == dumpdev) ! 52: bp->b_blkno += MINIROOTSIZE; ! 53: #endif ! 54: sz = howmany(bp->b_bcount, DEV_BSIZE); ! 55: if (bp->b_blkno+sz > nswap) { ! 56: bp->b_flags |= B_ERROR; ! 57: biodone(bp); ! 58: return; ! 59: } ! 60: if (nswdev > 1) { ! 61: off = bp->b_blkno % dmmax; ! 62: if (off+sz > dmmax) { ! 63: bp->b_flags |= B_ERROR; ! 64: biodone(bp); ! 65: return; ! 66: } ! 67: seg = bp->b_blkno / dmmax; ! 68: index = seg % nswdev; ! 69: seg /= nswdev; ! 70: bp->b_blkno = seg*dmmax + off; ! 71: } else ! 72: index = 0; ! 73: sp = &swdevt[index]; ! 74: if ((bp->b_dev = sp->sw_dev) == 0) ! 75: panic("swstrategy"); ! 76: if (sp->sw_vp == NULL) { ! 77: bp->b_error |= B_ERROR; ! 78: biodone(bp); ! 79: return; ! 80: } ! 81: VHOLD(sp->sw_vp); ! 82: if ((bp->b_flags & B_READ) == 0) { ! 83: if (vp = bp->b_vp) { ! 84: vp->v_numoutput--; ! 85: if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) { ! 86: vp->v_flag &= ~VBWAIT; ! 87: wakeup((caddr_t)&vp->v_numoutput); ! 88: } ! 89: } ! 90: sp->sw_vp->v_numoutput++; ! 91: } ! 92: if (bp->b_vp != NULL) ! 93: brelvp(bp); ! 94: bp->b_vp = sp->sw_vp; ! 95: VOP_STRATEGY(bp); ! 96: } ! 97: ! 98: /* ! 99: * System call swapon(name) enables swapping on device name, ! 100: * which must be in the swdevsw. Return EBUSY ! 101: * if already swapping on this device. ! 102: */ ! 103: /* ARGSUSED */ ! 104: swapon(p, uap, retval) ! 105: struct proc *p; ! 106: struct args { ! 107: char *name; ! 108: } *uap; ! 109: int *retval; ! 110: { ! 111: register struct vnode *vp; ! 112: register struct swdevt *sp; ! 113: register struct nameidata *ndp = &u.u_nd; ! 114: dev_t dev; ! 115: int error; ! 116: ! 117: if (error = suser(u.u_cred, &u.u_acflag)) ! 118: return (error); ! 119: ndp->ni_nameiop = LOOKUP | FOLLOW; ! 120: ndp->ni_segflg = UIO_USERSPACE; ! 121: ndp->ni_dirp = uap->name; ! 122: if (error = namei(ndp)) ! 123: return (error); ! 124: vp = ndp->ni_vp; ! 125: if (vp->v_type != VBLK) { ! 126: vrele(vp); ! 127: return (ENOTBLK); ! 128: } ! 129: dev = (dev_t)vp->v_rdev; ! 130: if (major(dev) >= nblkdev) { ! 131: vrele(vp); ! 132: return (ENXIO); ! 133: } ! 134: for (sp = &swdevt[0]; sp->sw_dev; sp++) ! 135: if (sp->sw_dev == dev) { ! 136: if (sp->sw_freed) { ! 137: vrele(vp); ! 138: return (EBUSY); ! 139: } ! 140: sp->sw_vp = vp; ! 141: if (error = swfree(sp - swdevt)) { ! 142: vrele(vp); ! 143: return (error); ! 144: } ! 145: return (0); ! 146: } ! 147: vrele(vp); ! 148: return (EINVAL); ! 149: } ! 150: ! 151: /* ! 152: * Swfree(index) frees the index'th portion of the swap map. ! 153: * Each of the nswdev devices provides 1/nswdev'th of the swap ! 154: * space, which is laid out with blocks of dmmax pages circularly ! 155: * among the devices. ! 156: */ ! 157: swfree(index) ! 158: int index; ! 159: { ! 160: register struct swdevt *sp; ! 161: register swblk_t vsbase; ! 162: register long blk; ! 163: struct vnode *vp; ! 164: register swblk_t dvbase; ! 165: register int nblks; ! 166: int error; ! 167: ! 168: sp = &swdevt[index]; ! 169: vp = sp->sw_vp; ! 170: if (error = VOP_OPEN(vp, FREAD|FWRITE, u.u_cred)) ! 171: return (error); ! 172: sp->sw_freed = 1; ! 173: nblks = sp->sw_nblks; ! 174: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) { ! 175: blk = nblks - dvbase; ! 176: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap) ! 177: panic("swfree"); ! 178: if (blk > dmmax) ! 179: blk = dmmax; ! 180: if (vsbase == 0) { ! 181: /* ! 182: * Can't free a block starting at 0 in the swapmap ! 183: * but need some space for argmap so use 1/2 this ! 184: * hunk which needs special treatment anyways. ! 185: */ ! 186: argdev = sp->sw_dev; ! 187: if (argdev_vp) ! 188: vrele(argdev_vp); ! 189: VREF(vp); ! 190: argdev_vp = vp; ! 191: rminit(argmap, (long)(blk/2-ctod(CLSIZE)), ! 192: (long)ctod(CLSIZE), "argmap", ARGMAPSIZE); ! 193: /* ! 194: * First of all chunks... initialize the swapmap ! 195: * the second half of the hunk. ! 196: */ ! 197: rminit(swapmap, (long)(blk/2), (long)(blk/2), ! 198: "swap", nswapmap); ! 199: } else if (dvbase == 0) { ! 200: /* ! 201: * Don't use the first cluster of the device ! 202: * in case it starts with a label or boot block. ! 203: */ ! 204: rmfree(swapmap, blk - ctod(CLSIZE), ! 205: vsbase + ctod(CLSIZE)); ! 206: } else ! 207: rmfree(swapmap, blk, vsbase); ! 208: } ! 209: return (0); ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.