xref: /csrg-svn/sys/vm/vm_swap.c (revision 2788)
1*2788Swnj /*	vm_swap.c	4.3	02/28/81	*/
21404Sbill 
31404Sbill #include "../h/param.h"
41404Sbill #include "../h/systm.h"
51404Sbill #include "../h/buf.h"
61404Sbill #include "../h/conf.h"
71404Sbill #include "../h/dir.h"
81404Sbill #include "../h/user.h"
91404Sbill #include "../h/inode.h"
101404Sbill #include "../h/map.h"
111404Sbill 
121404Sbill struct	buf rswbuf;
131404Sbill /*
141404Sbill  * Indirect driver for multi-controller paging.
151404Sbill  */
161404Sbill swstrategy(bp)
171404Sbill 	register struct buf *bp;
181404Sbill {
191404Sbill 	int sz, off, seg;
201404Sbill 	dev_t dev;
211404Sbill 
221404Sbill 	sz = (bp->b_bcount+511)/512;
231404Sbill 	off = bp->b_blkno % DMMAX;
241404Sbill 	if (bp->b_blkno+sz > nswap || off+sz > DMMAX) {
251404Sbill 		bp->b_flags |= B_ERROR;
261404Sbill 		iodone(bp);
271404Sbill 		return;
281404Sbill 	}
291404Sbill 	seg = bp->b_blkno / DMMAX;
301404Sbill 	dev = swdevt[seg % nswdev].sw_dev;
311404Sbill 	seg /= nswdev;
321404Sbill 	bp->b_blkno = seg*DMMAX + off;
331404Sbill 	bp->b_dev = dev;
341404Sbill 	if (dev == 0)
351404Sbill 		panic("swstrategy");
361404Sbill 	(*bdevsw[major(dev)].d_strategy)(bp);
371404Sbill }
381404Sbill 
391404Sbill swread(dev)
401404Sbill {
411404Sbill 
421404Sbill 	physio(swstrategy, &rswbuf, dev, B_READ, minphys);
431404Sbill }
441404Sbill 
451404Sbill swwrite(dev)
461404Sbill {
471404Sbill 
481404Sbill 	physio(swstrategy, &rswbuf, dev, B_WRITE, minphys);
491404Sbill }
501404Sbill 
511404Sbill /*
521404Sbill  * System call swapon(name) enables swapping on device name,
531404Sbill  * which must be in the swdevsw.  Return EBUSY
541404Sbill  * if already swapping on this device.
551404Sbill  */
561404Sbill vswapon()
571404Sbill {
581404Sbill 	register struct inode *ip;
591404Sbill 	dev_t dev;
601404Sbill 	register struct swdevt *sp;
611404Sbill 
621404Sbill 	ip = namei(uchar, 0);
631404Sbill 	if (ip == NULL)
641404Sbill 		return;
651404Sbill 	if ((ip->i_mode&IFMT) != IFBLK) {
661404Sbill 		u.u_error = ENOTBLK;
671404Sbill 		iput(ip);
681404Sbill 		return;
691404Sbill 	}
701404Sbill 	dev = (dev_t)ip->i_un.i_rdev;
711404Sbill 	iput(ip);
721404Sbill 	if (major(dev) >= nblkdev) {
731404Sbill 		u.u_error = ENXIO;
741404Sbill 		return;
751404Sbill 	}
761404Sbill 	/*
771404Sbill 	 * Search starting at second table entry,
781404Sbill 	 * since first (primary swap area) is freed at boot.
791404Sbill 	 */
801404Sbill 	for (sp = &swdevt[1]; sp->sw_dev; sp++)
811404Sbill 		if (sp->sw_dev == dev) {
821404Sbill 			if (sp->sw_freed) {
831404Sbill 				u.u_error = EBUSY;
841404Sbill 				return;
851404Sbill 			}
861404Sbill 			swfree(sp - swdevt);
871404Sbill 			return;
881404Sbill 		}
891404Sbill 	u.u_error = ENODEV;
901404Sbill }
911404Sbill 
921404Sbill /*
931404Sbill  * Swfree(index) frees the index'th portion of the swap map.
941404Sbill  * Each of the nswdev devices provides 1/nswdev'th of the swap
951404Sbill  * space, which is laid out with blocks of DMMAX pages circularly
961404Sbill  * among the devices.
971404Sbill  */
981404Sbill swfree(index)
991404Sbill 	int index;
1001404Sbill {
1011404Sbill 	register swblk_t vsbase;
1021404Sbill 	register int blk;
1031404Sbill 
1041404Sbill 	swdevt[index].sw_freed = 1;
1051404Sbill 	for (vsbase = index*DMMAX; vsbase < nswap; vsbase += nswdev*DMMAX) {
1061404Sbill 		blk = nswap - vsbase;
1071404Sbill 		if (blk > DMMAX)
1081404Sbill 			blk = DMMAX;
1091404Sbill 		if (vsbase == 0) {
1101404Sbill 			/*
1111404Sbill 			 * Can't free a block starting at 0 in the swapmap
112*2788Swnj 			 * but need some space for argmap so use 1/2 this
1131404Sbill 			 * hunk which needs special treatment anyways.
1141404Sbill 			 */
1151404Sbill 			argdev = swdevt[0].sw_dev;
116*2788Swnj 			rminit(argmap, blk/2-CLSIZE, CLSIZE,
117*2788Swnj 			    "argmap", ARGMAPSIZE);
118*2788Swnj 			/*
119*2788Swnj 			 * First of all chunks... initialize the swapmap
120*2788Swnj 			 * the second half of the hunk.
121*2788Swnj 			 */
122*2788Swnj 			rminit(swapmap, blk/2, blk/2, "swap", nswapmap);
1231404Sbill 		} else
124*2788Swnj 			rmfree(swapmap, blk, vsbase);
1251404Sbill 	}
1261404Sbill }
127