-/* vm_swap.c 6.3 84/08/29 */
+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ * @(#)vm_swap.c 7.15 (Berkeley) %G%
+ */
#include "param.h"
#include "systm.h"
#include "buf.h"
#include "conf.h"
-#include "dir.h"
#include "user.h"
-#include "inode.h"
+#include "vnode.h"
+#include "specdev.h"
#include "map.h"
-#include "uio.h"
#include "file.h"
+#include "stat.h"
-struct buf rswbuf;
/*
* Indirect driver for multi-controller paging.
*/
swstrategy(bp)
register struct buf *bp;
{
- int sz, off, seg;
- dev_t dev;
+ int sz, off, seg, index;
+ register struct swdevt *sp;
#ifdef GENERIC
/*
sz = howmany(bp->b_bcount, DEV_BSIZE);
if (bp->b_blkno+sz > nswap) {
bp->b_flags |= B_ERROR;
- iodone(bp);
+ biodone(bp);
return;
}
if (nswdev > 1) {
off = bp->b_blkno % dmmax;
if (off+sz > dmmax) {
bp->b_flags |= B_ERROR;
- iodone(bp);
+ biodone(bp);
return;
}
seg = bp->b_blkno / dmmax;
- dev = swdevt[seg % nswdev].sw_dev;
+ index = seg % nswdev;
seg /= nswdev;
bp->b_blkno = seg*dmmax + off;
} else
- dev = swdevt[0].sw_dev;
- bp->b_dev = dev;
- if (dev == 0)
+ index = 0;
+ sp = &swdevt[index];
+#ifdef SECSIZE
+ bp->b_blkno <<= sp->sw_bshift;
+ bp->b_blksize = sp->sw_blksize;
+#endif SECSIZE
+ bp->b_dev = sp->sw_dev;
+ if (bp->b_dev == 0)
panic("swstrategy");
- (*bdevsw[major(dev)].d_strategy)(bp);
-}
-
-swread(dev, uio)
- dev_t dev;
- struct uio *uio;
-{
-
- return (physio(swstrategy, &rswbuf, dev, B_READ, minphys, uio));
-}
-
-swwrite(dev, uio)
- dev_t dev;
- struct uio *uio;
-{
-
- return (physio(swstrategy, &rswbuf, dev, B_WRITE, minphys, uio));
+ (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
}
/*
* which must be in the swdevsw. Return EBUSY
* if already swapping on this device.
*/
-swapon()
-{
- struct a {
+/* ARGSUSED */
+swapon(p, uap, retval)
+ struct proc *p;
+ struct args {
char *name;
- } *uap = (struct a *)u.u_ap;
- register struct inode *ip;
- dev_t dev;
+ } *uap;
+ int *retval;
+{
+ register struct vnode *vp;
register struct swdevt *sp;
register struct nameidata *ndp = &u.u_nd;
+ dev_t dev;
+ int error;
+ if (error = suser(u.u_cred, &u.u_acflag))
+ return (error);
ndp->ni_nameiop = LOOKUP | FOLLOW;
ndp->ni_segflg = UIO_USERSPACE;
ndp->ni_dirp = uap->name;
- ip = namei(ndp);
- if (ip == NULL)
- return;
- if ((ip->i_mode&IFMT) != IFBLK) {
- u.u_error = ENOTBLK;
- iput(ip);
- return;
+ if (error = namei(ndp))
+ return (error);
+ vp = ndp->ni_vp;
+ if (vp->v_type != VBLK) {
+ vrele(vp);
+ return (ENOTBLK);
}
- dev = (dev_t)ip->i_rdev;
- iput(ip);
+ dev = (dev_t)vp->v_rdev;
if (major(dev) >= nblkdev) {
- u.u_error = ENXIO;
- return;
+ vrele(vp);
+ return (ENXIO);
}
- /*
- * Search starting at second table entry,
- * since first (primary swap area) is freed at boot.
- */
- for (sp = &swdevt[1]; sp->sw_dev; sp++)
+ for (sp = &swdevt[0]; sp->sw_dev; sp++)
if (sp->sw_dev == dev) {
if (sp->sw_freed) {
- u.u_error = EBUSY;
- return;
+ vrele(vp);
+ return (EBUSY);
}
- swfree(sp - swdevt);
- return;
+ u.u_error = swfree(sp - swdevt);
+ return (0);
}
- u.u_error = ENODEV;
+ vrele(vp);
+ return (EINVAL);
}
+#ifdef SECSIZE
+long argdbsize; /* XXX */
+
+#endif SECSIZE
/*
* Swfree(index) frees the index'th portion of the swap map.
* Each of the nswdev devices provides 1/nswdev'th of the swap
swfree(index)
int index;
{
+ register struct swdevt *sp;
+ register struct swdevt *sp;
register swblk_t vsbase;
register long blk;
- dev_t dev;
+ struct vnode *vp;
register swblk_t dvbase;
register int nblks;
+ int error;
+ int error;
- dev = swdevt[index].sw_dev;
- (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE);
- swdevt[index].sw_freed = 1;
- nblks = swdevt[index].sw_nblks;
+ sp = &swdevt[index];
+ dev = sp->sw_dev;
+ if (error = (*bdevsw[major(dev)].d_open)(dev, FREAD|FWRITE, S_IFBLK))
+ return (error);
+ sp->sw_freed = 1;
+ nblks = sp->sw_nblks;
for (dvbase = 0; dvbase < nblks; dvbase += dmmax) {
blk = nblks - dvbase;
if ((vsbase = index*dmmax + dvbase*nswdev) >= nswap)
if (blk > dmmax)
blk = dmmax;
if (vsbase == 0) {
- /*
- * Can't free a block starting at 0 in the swapmap
- * but need some space for argmap so use 1/2 this
- * hunk which needs special treatment anyways.
- */
- argdev = swdevt[0].sw_dev;
- rminit(argmap, (long)(blk/2-ctod(CLSIZE)),
- (long)ctod(CLSIZE), "argmap", ARGMAPSIZE);
/*
* First of all chunks... initialize the swapmap
* the second half of the hunk.
*/
- rminit(swapmap, (long)blk/2, (long)blk/2,
+ rminit(swapmap, (long)(blk/2), (long)(blk/2),
"swap", nswapmap);
+ } else if (dvbase == 0) {
+ /*
+ * Don't use the first cluster of the device
+ * in case it starts with a label or boot block.
+ */
+ rmfree(swapmap, blk - ctod(CLSIZE),
+ vsbase + ctod(CLSIZE));
+ } else if (dvbase == 0) {
+ /*
+ * Don't use the first cluster of the device
+ * in case it starts with a label or boot block.
+ */
+ rmfree(swapmap, blk - ctod(CLSIZE),
+ vsbase + ctod(CLSIZE));
} else
rmfree(swapmap, blk, vsbase);
}
+ return (0);
+ return (0);
}