diff options
author | dg <dg@FreeBSD.org> | 1995-05-14 03:00:10 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-05-14 03:00:10 +0000 |
commit | b649d7b9c7fc4e854447610d77a8f589d6d879df (patch) | |
tree | e3f8adb9c567dce966929b13f5ef9bc8016008d6 /sys/vm/vm_swap.c | |
parent | 8f5311b61712fdd904658b7a56c5832f71bffcab (diff) | |
download | FreeBSD-src-b649d7b9c7fc4e854447610d77a8f589d6d879df.zip FreeBSD-src-b649d7b9c7fc4e854447610d77a8f589d6d879df.tar.gz |
Changed swap partition handling/allocation so that it doesn't
require specific partitions be mentioned in the kernel config
file ("swap on foo" is now obsolete).
From Poul-Henning:
The visible effect is this:
As default, unless
options "NSWAPDEV=23"
is in your config, you will have four swap-devices.
You can swapon(2) any block device you feel like, it doesn't have
to be in the kernel config.
There is a performance/resource win available by getting the NSWAPDEV right
(but only if you have just one swap-device ??), but using that as default
would be too restrictive.
The invisible effect is that:
Swap-handling disappears from the $arch part of the kernel.
It gets a lot simpler (-145 lines) and cleaner.
Reviewed by: John Dyson, David Greenman
Submitted by: Poul-Henning Kamp, with minor changes by me.
Diffstat (limited to 'sys/vm/vm_swap.c')
-rw-r--r-- | sys/vm/vm_swap.c | 194 |
1 files changed, 77 insertions, 117 deletions
diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index 4f8f483..682d11a 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vm_swap.c 8.5 (Berkeley) 2/17/94 - * $Id: vm_swap.c,v 1.15 1995/03/16 18:17:33 bde Exp $ + * $Id: vm_swap.c,v 1.16 1995/05/12 03:54:59 phk Exp $ */ #include <sys/param.h> @@ -53,72 +53,17 @@ * Indirect driver for multi-controller paging. */ -int nswap, nswdev; +#ifndef NSWAPDEV +#define NSWAPDEV 4 +#endif +static struct swdevt should_be_malloced[NSWAPDEV]; +struct swdevt *swdevt = should_be_malloced; +int nswap; +int nswdev = NSWAPDEV; int vm_swap_size; int bswneeded; vm_offset_t swapbkva; /* swap buffers kva */ -/* - * Set up swap devices. - * Initialize linked list of free swap - * headers. These do not actually point - * to buffers, but rather to pages that - * are being swapped in and out. - */ -void -swapinit() -{ - register struct proc *p = &proc0; /* XXX */ - struct swdevt *swp; - int error; - - /* - * Count swap devices, and adjust total swap space available. Some of - * the space will not be countable until later (dynamically - * configurable devices) and some of the counted space will not be - * available until a swapon() system call is issued, both usually - * happen when the system goes multi-user. - * - * If using NFS for swap, swdevt[0] will already be bdevvp'd. XXX - */ - nswdev = 0; - nswap = 0; - for (swp = swdevt; swp->sw_dev != NODEV || swp->sw_vp != NULL; swp++) { - nswdev++; - if (swp->sw_nblks > nswap) - nswap = swp->sw_nblks; - } - if (nswdev == 0) - panic("swapinit"); - if (nswdev > 1) - nswap = ((nswap + dmmax - 1) / dmmax) * dmmax; - nswap *= nswdev; - if (swdevt[0].sw_vp == NULL && - bdevvp(swdevt[0].sw_dev, &swdevt[0].sw_vp)) - panic("swapvp"); - /* - * If there is no swap configured, tell the user. We don't - * automatically activate any swapspaces in the kernel; the user must - * explicitly use swapon to enable swaping on a device. - */ - if (nswap == 0) - printf("WARNING: no swap space found\n"); - for (swp = swdevt;; swp++) { - if (swp->sw_dev == NODEV) { - if (swp->sw_vp == NULL) - break; - - /* We DO enable NFS swapspaces */ - error = swfree(p, swp - swdevt); - if (error) { - printf( - "Couldn't enable swapspace %d, error = %d", - swp - swdevt, error); - } - } - } -} - void swstrategy(bp) register struct buf *bp; @@ -194,43 +139,53 @@ swapon(p, uap, retval) register struct vnode *vp; register struct swdevt *sp; dev_t dev; - int error; + int error,i; struct nameidata nd; + struct vattr attr; error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); + NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->name, p); error = namei(&nd); if (error) return (error); + vp = nd.ni_vp; - if (vp->v_type != VBLK) { - vrele(vp); - return (ENOTBLK); - } - dev = (dev_t) vp->v_rdev; - if (major(dev) >= nblkdev) { - vrele(vp); - return (ENXIO); - } - for (sp = &swdevt[0]; sp->sw_dev != NODEV; sp++) { - if (sp->sw_dev == dev) { - if (sp->sw_flags & SW_FREED) { - vrele(vp); - return (EBUSY); - } - sp->sw_vp = vp; - error = swfree(p, sp - swdevt); - if (error) { - vrele(vp); - return (error); - } - return (0); + + switch (vp->v_type) { + case VBLK: + dev = (dev_t) vp->v_rdev; + if (major(dev) >= nblkdev) { + error = ENXIO; + break; } + error = swaponvp(p, vp, dev, 0); + break; + case VCHR: + /* + * For now, we disallow swapping to regular files. + * It requires logical->physcal block translation + * support in the swap pager before it will work. + */ + error = ENOTBLK; + break; +#if 0 + error = VOP_GETATTR(vp, &attr, p->p_ucred, p); + if (!error) + error = swaponvp(p, vp, NODEV, attr.va_size / DEV_BSIZE); + break; +#endif + default: + error = EINVAL; + break; } - vrele(vp); - return (EINVAL); + + if (error) + vrele(vp); + + return (error); } /* @@ -240,49 +195,54 @@ swapon(p, uap, retval) * among the devices. */ int -swfree(p, index) +swaponvp(p, vp, dev, nblks) struct proc *p; - int index; + struct vnode *vp; + dev_t dev; + u_long nblks; { + int index; register struct swdevt *sp; register swblk_t vsbase; register long blk; - struct vnode *vp; - register swblk_t dvbase; - register int nblks; + swblk_t dvbase; + struct swdevt *swp; int error; + int perdev; + + for (sp = swdevt, index = 0 ; index < nswdev; index++, sp++) { + if (sp->sw_vp == vp) + return EBUSY; + if (!sp->sw_vp) + goto found; + + } + return EINVAL; + found: + if (dev != NODEV && (major(dev) >= nblkdev)) + return (ENXIO); - sp = &swdevt[index]; - vp = sp->sw_vp; error = VOP_OPEN(vp, FREAD | FWRITE, p->p_ucred, p); if (error) return (error); - sp->sw_flags |= SW_FREED; - nblks = sp->sw_nblks; - /* - * Some devices may not exist til after boot time. If so, their nblk - * count will be 0. - */ - if (nblks <= 0) { - int perdev; - dev_t dev = sp->sw_dev; - - if (bdevsw[major(dev)].d_psize == 0 || - (nblks = (*bdevsw[major(dev)].d_psize) (dev)) == -1) { - (void) VOP_CLOSE(vp, FREAD | FWRITE, p->p_ucred, p); - sp->sw_flags &= ~SW_FREED; - return (ENXIO); - } - perdev = nswap / nswdev; - if (nblks > perdev) - nblks = perdev; - sp->sw_nblks = nblks; + + if (nblks == 0 && (bdevsw[major(dev)].d_psize == 0 || + (nblks = (*bdevsw[major(dev)].d_psize) (dev)) == -1)) { + (void) VOP_CLOSE(vp, FREAD | FWRITE, p->p_ucred, p); + return (ENXIO); } if (nblks == 0) { (void) VOP_CLOSE(vp, FREAD | FWRITE, p->p_ucred, p); - sp->sw_flags &= ~SW_FREED; - return (0); /* XXX error? */ + return (ENXIO); } + sp->sw_vp = vp; + sp->sw_dev = dev; + sp->sw_flags |= SW_FREED; + sp->sw_nblks = nblks; + + if (nblks * nswdev > nswap) + nswap = nblks * nswdev; + for (dvbase = dmmax; dvbase < nblks; dvbase += dmmax) { blk = nblks - dvbase; |