|
|
1.1 ! root 1: /* ! 2: * indirect driver for swapping ! 3: */ ! 4: ! 5: #include "sys/param.h" ! 6: #include "sys/systm.h" ! 7: #include "sys/buf.h" ! 8: #include "sys/conf.h" ! 9: #include "sys/user.h" ! 10: #include "sys/inode.h" ! 11: #include "sys/map.h" ! 12: ! 13: struct buf rswbuf; ! 14: extern struct map swapmap[]; ! 15: extern int swmapcnt; ! 16: extern struct map argmap[]; ! 17: extern int argcnt; ! 18: ! 19: int swopen(), swstrategy(), swread(), swwrite(); ! 20: ! 21: struct bdevsw swbdev = bdinit(swopen, nulldev, swstrategy, 0); ! 22: ! 23: struct cdevsw swcdev = cdinit(swopen, nulldev, swread, swwrite, nodev); ! 24: ! 25: /* ! 26: * presumably called for the first time on boot ! 27: */ ! 28: swopen(dev, flag) ! 29: dev_t dev; ! 30: int flag; ! 31: { ! 32: static int opened; ! 33: ! 34: if (opened) ! 35: return; ! 36: opened++; ! 37: swfree(0); ! 38: } ! 39: ! 40: swstrategy(bp) ! 41: register struct buf *bp; ! 42: { ! 43: register clicks_t sz; ! 44: register daddr_t off; ! 45: register int seg; ! 46: dev_t dev; ! 47: ! 48: sz = btoc(bp->b_bcount); ! 49: off = bp->b_blkno % dmmax; ! 50: seg = bp->b_blkno / dmmax; ! 51: dev = swdevt[seg % nswdevt].sw_dev; ! 52: if (bdevsw[major(dev)] == 0) ! 53: panic("swstrategy"); ! 54: bp->b_blkno = seg / nswdevt; ! 55: bp->b_blkno *= dmmax; ! 56: bp->b_blkno += off; ! 57: bp->b_dev = dev; ! 58: if (bp->b_blkno+sz > swdevt[seg % nswdevt].sw_size ! 59: || off+sz > dmmax) { ! 60: bp->b_flags |= B_ERROR; ! 61: iodone(bp); ! 62: return; ! 63: } ! 64: (*bdevsw[major(dev)]->d_strategy)(bp); ! 65: } ! 66: ! 67: swread(dev) ! 68: { ! 69: ! 70: physio(swstrategy, &rswbuf, dev, B_READ, minphys); ! 71: } ! 72: ! 73: swwrite(dev) ! 74: { ! 75: ! 76: physio(swstrategy, &rswbuf, dev, B_WRITE, minphys); ! 77: } ! 78: ! 79: /* ! 80: * System call swapon(name) enables swapping on device name, ! 81: * which must be in the swdevsw. Return EBUSY ! 82: * if already swapping on this device. ! 83: * silly; this should just be an ioctl. ! 84: * ! 85: * -- assume swapping on a regular filesystem, ! 86: * so directly calling thought bdevsw is what we want. ! 87: * some day this will be unfortunate. ! 88: */ ! 89: vswapon() ! 90: { ! 91: struct a { ! 92: char *fname; ! 93: }; ! 94: register struct inode *ip; ! 95: dev_t dev; ! 96: register int i; ! 97: ! 98: ip = namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nilargnamei, 1); ! 99: if (ip == NULL) ! 100: return; ! 101: if ((ip->i_mode&IFMT) != IFBLK || ip->i_fstyp != 0) { ! 102: u.u_error = EINVAL; ! 103: iput(ip); ! 104: return; ! 105: } ! 106: dev = (dev_t)ip->i_un.i_rdev; ! 107: iput(ip); ! 108: for (i = 0; i < nswdevt; i++) { ! 109: if (swdevt[i].sw_dev != dev) ! 110: continue; ! 111: if (swdevt[i].sw_freed) { ! 112: u.u_error = EBUSY; ! 113: return; ! 114: } ! 115: swfree(i); ! 116: return; ! 117: } ! 118: u.u_error = ENODEV; ! 119: } ! 120: ! 121: /* ! 122: * Swfree(index) frees the index'th portion of the swap map. ! 123: * Each of the nswdevt devices provides 1/nswdev'th of the swap ! 124: * space, which is laid out with blocks of dmmax pages circularly ! 125: * among the devices. ! 126: * rmalloc starts at 1, so give the first dmmax/2 pages of the first device ! 127: * to the arg device. ! 128: * quietly opens the device, with no trace in inode table ! 129: * subsequently really opening and closing the device may cause trouble? ! 130: */ ! 131: swfree(index) ! 132: register int index; ! 133: { ! 134: register swblk_t bno; ! 135: register int nblk; ! 136: register int xsize; ! 137: extern int argcnt, swmapcnt; ! 138: ! 139: bdevopen(swdevt[index].sw_dev); ! 140: if (u.u_error) ! 141: return; ! 142: xsize = swdevt[index].sw_size * nswdevt; ! 143: xsize += index * dmmax; ! 144: xsize -= (nswdevt - 1) * (swdevt[index].sw_size % dmmax); ! 145: for (bno = dmmax * index; bno < xsize; bno += dmmax * nswdevt) { ! 146: nblk = xsize - bno; ! 147: if (nblk > dmmax) ! 148: nblk = dmmax; ! 149: if (bno) ! 150: rmfree(swapmap, nblk, (int)bno); ! 151: else { ! 152: argdev = swdevt[0].sw_dev; ! 153: rminit(argmap, argcnt, nblk/2-CLSIZE, CLSIZE); ! 154: rminit(swapmap, swmapcnt, nblk/2, nblk/2); ! 155: } ! 156: } ! 157: swdevt[index].sw_freed = 1; ! 158: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.