|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 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: * @(#)vm_swap.c 7.18 (Berkeley) 5/6/91 ! 34: */ ! 35: ! 36: #include "param.h" ! 37: #include "systm.h" ! 38: #include "buf.h" ! 39: #include "conf.h" ! 40: #include "proc.h" ! 41: #include "namei.h" ! 42: #include "dmap.h" /* XXX */ ! 43: #include "vnode.h" ! 44: #include "specdev.h" ! 45: #include "map.h" ! 46: #include "file.h" ! 47: ! 48: /* ! 49: * Indirect driver for multi-controller paging. ! 50: */ ! 51: ! 52: int nswap, nswdev; ! 53: ! 54: /* ! 55: * Set up swap devices. ! 56: * Initialize linked list of free swap ! 57: * headers. These do not actually point ! 58: * to buffers, but rather to pages that ! 59: * are being swapped in and out. ! 60: */ ! 61: swapinit() ! 62: { ! 63: register int i; ! 64: register struct buf *sp = swbuf; ! 65: struct swdevt *swp; ! 66: int error; ! 67: ! 68: /* ! 69: * Count swap devices, and adjust total swap space available. ! 70: * Some of this space will not be available until a swapon() ! 71: * system is issued, usually when the system goes multi-user. ! 72: */ ! 73: nswdev = 0; ! 74: nswap = 0; ! 75: for (swp = swdevt; swp->sw_dev; swp++) { ! 76: nswdev++; ! 77: if (swp->sw_nblks > nswap) ! 78: nswap = swp->sw_nblks; ! 79: } ! 80: if (nswdev == 0) ! 81: panic("swapinit"); ! 82: if (nswdev > 1) ! 83: nswap = ((nswap + dmmax - 1) / dmmax) * dmmax; ! 84: nswap *= nswdev; ! 85: if (bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp)) ! 86: panic("swapvp"); ! 87: if (error = swfree(&proc0, 0)) { ! 88: printf("swfree errno %d\n", error); /* XXX */ ! 89: panic("swapinit swfree 0"); ! 90: } ! 91: ! 92: /* ! 93: * Now set up swap buffer headers. ! 94: */ ! 95: bswlist.av_forw = sp; ! 96: for (i = 0; i < nswbuf - 1; i++, sp++) ! 97: sp->av_forw = sp + 1; ! 98: sp->av_forw = NULL; ! 99: } ! 100: ! 101: swstrategy(bp) ! 102: register struct buf *bp; ! 103: { ! 104: int sz, off, seg, index; ! 105: register struct swdevt *sp; ! 106: struct vnode *vp; ! 107: ! 108: #ifdef GENERIC ! 109: /* ! 110: * A mini-root gets copied into the front of the swap ! 111: * and we run over top of the swap area just long ! 112: * enough for us to do a mkfs and restor of the real ! 113: * root (sure beats rewriting standalone restor). ! 114: */ ! 115: #define MINIROOTSIZE 4096 ! 116: if (rootdev == dumpdev) ! 117: bp->b_blkno += MINIROOTSIZE; ! 118: #endif ! 119: sz = howmany(bp->b_bcount, DEV_BSIZE); ! 120: if (bp->b_blkno + sz > nswap) { ! 121: bp->b_flags |= B_ERROR; ! 122: biodone(bp); ! 123: return; ! 124: } ! 125: if (nswdev > 1) { ! 126: off = bp->b_blkno % dmmax; ! 127: if (off+sz > dmmax) { ! 128: bp->b_flags |= B_ERROR; ! 129: biodone(bp); ! 130: return; ! 131: } ! 132: seg = bp->b_blkno / dmmax; ! 133: index = seg % nswdev; ! 134: seg /= nswdev; ! 135: bp->b_blkno = seg*dmmax + off; ! 136: } else ! 137: index = 0; ! 138: sp = &swdevt[index]; ! 139: if ((bp->b_dev = sp->sw_dev) == 0) ! 140: panic("swstrategy"); ! 141: if (sp->sw_vp == NULL) { ! 142: bp->b_error |= B_ERROR; ! 143: biodone(bp); ! 144: return; ! 145: } ! 146: VHOLD(sp->sw_vp); ! 147: if ((bp->b_flags & B_READ) == 0) { ! 148: if (vp = bp->b_vp) { ! 149: vp->v_numoutput--; ! 150: if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) { ! 151: vp->v_flag &= ~VBWAIT; ! 152: wakeup((caddr_t)&vp->v_numoutput); ! 153: } ! 154: } ! 155: sp->sw_vp->v_numoutput++; ! 156: } ! 157: if (bp->b_vp != NULL) ! 158: brelvp(bp); ! 159: bp->b_vp = sp->sw_vp; ! 160: VOP_STRATEGY(bp); ! 161: } ! 162: ! 163: /* ! 164: * System call swapon(name) enables swapping on device name, ! 165: * which must be in the swdevsw. Return EBUSY ! 166: * if already swapping on this device. ! 167: */ ! 168: /* ARGSUSED */ ! 169: swapon(p, uap, retval) ! 170: struct proc *p; ! 171: struct args { ! 172: char *name; ! 173: } *uap; ! 174: int *retval; ! 175: { ! 176: register struct vnode *vp; ! 177: register struct swdevt *sp; ! 178: register struct nameidata *ndp; ! 179: dev_t dev; ! 180: int error; ! 181: struct nameidata nd; ! 182: ! 183: if (error = suser(p->p_ucred, &p->p_acflag)) ! 184: return (error); ! 185: ndp = &nd; ! 186: ndp->ni_nameiop = LOOKUP | FOLLOW; ! 187: ndp->ni_segflg = UIO_USERSPACE; ! 188: ndp->ni_dirp = uap->name; ! 189: if (error = namei(ndp, p)) ! 190: return (error); ! 191: vp = ndp->ni_vp; ! 192: if (vp->v_type != VBLK) { ! 193: vrele(vp); ! 194: return (ENOTBLK); ! 195: } ! 196: dev = (dev_t)vp->v_rdev; ! 197: if (major(dev) >= nblkdev) { ! 198: vrele(vp); ! 199: return (ENXIO); ! 200: } ! 201: for (sp = &swdevt[0]; sp->sw_dev; sp++) ! 202: if (sp->sw_dev == dev) { ! 203: if (sp->sw_freed) { ! 204: vrele(vp); ! 205: return (EBUSY); ! 206: } ! 207: sp->sw_vp = vp; ! 208: if (error = swfree(p, sp - swdevt)) { ! 209: vrele(vp); ! 210: return (error); ! 211: } ! 212: return (0); ! 213: } ! 214: vrele(vp); ! 215: return (EINVAL); ! 216: } ! 217: ! 218: /* ! 219: * Swfree(index) frees the index'th portion of the swap map. ! 220: * Each of the nswdev devices provides 1/nswdev'th of the swap ! 221: * space, which is laid out with blocks of dmmax pages circularly ! 222: * among the devices. ! 223: */ ! 224: swfree(p, index) ! 225: struct proc *p; ! 226: int index; ! 227: { ! 228: register struct swdevt *sp; ! 229: register swblk_t vsbase; ! 230: register long blk; ! 231: struct vnode *vp; ! 232: register swblk_t dvbase; ! 233: register int nblks; ! 234: int error; ! 235: ! 236: sp = &swdevt[index]; ! 237: vp = sp->sw_vp; ! 238: if (error = VOP_OPEN(vp, FREAD|FWRITE, p->p_ucred, p)) ! 239: return (error); ! 240: sp->sw_freed = 1; ! 241: nblks = sp->sw_nblks; ! 242: for (dvbase = 0; dvbase < nblks; dvbase += dmmax) { ! 243: blk = nblks - dvbase; ! 244: if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap) ! 245: panic("swfree"); ! 246: if (blk > dmmax) ! 247: blk = dmmax; ! 248: if (vsbase == 0) { ! 249: /* ! 250: * First of all chunks... initialize the swapmap ! 251: * the second half of the hunk. ! 252: */ ! 253: rminit(swapmap, (long)(blk/2), (long)(blk/2), ! 254: "swap", nswapmap); ! 255: } else if (dvbase == 0) { ! 256: /* ! 257: * Don't use the first cluster of the device ! 258: * in case it starts with a label or boot block. ! 259: */ ! 260: rmfree(swapmap, blk - ctod(CLSIZE), ! 261: vsbase + ctod(CLSIZE)); ! 262: } else ! 263: rmfree(swapmap, blk, vsbase); ! 264: } ! 265: return (0); ! 266: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.