X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/da7c5cc62d0962b5d290c48159695646218b130b..d5d81d04f815ca58d2e538a1f802294d09225609:/usr/src/sys/vm/vm_swap.c diff --git a/usr/src/sys/vm/vm_swap.c b/usr/src/sys/vm/vm_swap.c index af0f53b0d5..213d7bab20 100644 --- a/usr/src/sys/vm/vm_swap.c +++ b/usr/src/sys/vm/vm_swap.c @@ -1,31 +1,31 @@ /* - * Copyright (c) 1982 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * All rights reserved. * - * @(#)vm_swap.c 6.6 (Berkeley) %G% + * %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 /* @@ -41,42 +41,31 @@ swstrategy(bp) 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); } /* @@ -84,47 +73,54 @@ swwrite(dev, uio) * 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 (!suser()) - return; + 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); } 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 = EINVAL; + 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 @@ -134,16 +130,22 @@ swapon() 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) @@ -151,21 +153,29 @@ swfree(index) 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); }