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.
This commit is contained in:
David Greenman 1995-05-14 03:00:10 +00:00
parent af9fe6e59d
commit a401ebbe32
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=8504
18 changed files with 118 additions and 302 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $Id: autoconf.c,v 1.29 1995/05/11 19:26:07 rgrimes Exp $
* $Id: autoconf.c,v 1.30 1995/05/12 19:17:11 wollman Exp $
*/
/*
@ -57,7 +57,6 @@
#include <machine/md_var.h>
#include <machine/pte.h>
static void swapconf(void);
static void setroot(void);
/*
@ -209,43 +208,9 @@ configure()
* parameter based on device(s) used.
*/
setconf();
swapconf();
cold = 0;
}
/*
* Configure swap space and related parameters.
*/
static void
swapconf()
{
register struct swdevt *swp;
register int nblks;
for (swp = swdevt; swp->sw_dev > 0; swp++)
{
unsigned d = major(swp->sw_dev);
if (d > nblkdev) break;
if (bdevsw[d].d_psize) {
nblks = (*bdevsw[d].d_psize)(swp->sw_dev);
if (nblks > 0 &&
(swp->sw_nblks == 0 || swp->sw_nblks > nblks))
swp->sw_nblks = nblks;
else
swp->sw_nblks = 0;
}
swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
}
if (dumpdev != NODEV) {
if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) -
Maxmem*NBPG/512;
if (dumplo < 0)
dumplo = 0;
}
}
int
setdumpdev(dev_t dev)
{
@ -267,7 +232,6 @@ setdumpdev(dev_t dev)
/*NOTREACHED*/
}
#define DOSWAP /* change swdevt and dumpdev */
u_long bootdev = 0; /* should be dev_t, but not until 32 bits */
static char devname[][2] = {
@ -325,25 +289,4 @@ setroot()
devname[majdev][0], devname[majdev][1],
mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT),
part + 'a');
#ifdef DOSWAP
mindev &= ~PARTITIONMASK;
for (swp = swdevt; swp->sw_dev; swp++) {
if (majdev == major(swp->sw_dev) &&
mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
temp = swdevt[0].sw_dev;
swdevt[0].sw_dev = swp->sw_dev;
swp->sw_dev = temp;
break;
}
}
if (swp->sw_dev == 0)
return;
/*
* If dumpdev was the same as the old primary swap
* device, move it to the new primary swap device.
*/
if (temp == dumpdev)
dumpdev = swdevt[0].sw_dev;
#endif
}

View File

@ -1,7 +1,7 @@
#
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
#
# $Id: GENERIC,v 1.43 1995/04/24 05:33:58 phk Exp $
# $Id: GENERIC,v 1.44 1995/05/02 04:40:06 phk Exp $
#
machine "i386"
@ -23,7 +23,7 @@ options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
options BOUNCE_BUFFERS #include support for DMA bounce buffers
options UCONSOLE #Allow users to grab the console
config kernel root on wd0 swap on wd0 and wd1 and wd2 and wd3 and sd0 and sd1 and vn0 dumps on wd0
config kernel root on wd0
controller isa0
controller pci0

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.179 1995/05/11 02:15:37 jkh Exp $
# $Id: LINT,v 1.180 1995/05/12 15:17:55 ache Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -58,7 +58,7 @@ options MATH_EMULATE #Support for x87 emulation
# - The kernel can swap on wd0b and sd0b, defaulting to the former
# - Crash dumps will be written to wd0b, if possible
#
config kernel root on wd0 swap on wd0 and sd0 dumps on wd0
config kernel root on wd0
#####################################################################
@ -251,7 +251,9 @@ options UNION #Union filesystem
# of kilobytes to reserve for the filesystem.
options "MFS_ROOT=10"
#
# Allow this many swap-devices.
options "NSWAPDEV=20"
# Disk quotas are supported when this option is enabled. If you
# change the value of this option, you must do a `make clean' in your
# kernel compile directory in order to get a working kernel.

View File

@ -1,7 +1,7 @@
#
# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
#
# $Id: GENERIC,v 1.43 1995/04/24 05:33:58 phk Exp $
# $Id: GENERIC,v 1.44 1995/05/02 04:40:06 phk Exp $
#
machine "i386"
@ -23,7 +23,7 @@ options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
options BOUNCE_BUFFERS #include support for DMA bounce buffers
options UCONSOLE #Allow users to grab the console
config kernel root on wd0 swap on wd0 and wd1 and wd2 and wd3 and sd0 and sd1 and vn0 dumps on wd0
config kernel root on wd0
controller isa0
controller pci0

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.179 1995/05/11 02:15:37 jkh Exp $
# $Id: LINT,v 1.180 1995/05/12 15:17:55 ache Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -58,7 +58,7 @@ options MATH_EMULATE #Support for x87 emulation
# - The kernel can swap on wd0b and sd0b, defaulting to the former
# - Crash dumps will be written to wd0b, if possible
#
config kernel root on wd0 swap on wd0 and sd0 dumps on wd0
config kernel root on wd0
#####################################################################
@ -251,7 +251,9 @@ options UNION #Union filesystem
# of kilobytes to reserve for the filesystem.
options "MFS_ROOT=10"
#
# Allow this many swap-devices.
options "NSWAPDEV=20"
# Disk quotas are supported when this option is enabled. If you
# change the value of this option, you must do a `make clean' in your
# kernel compile directory in order to get a working kernel.

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.179 1995/05/11 02:15:37 jkh Exp $
# $Id: LINT,v 1.180 1995/05/12 15:17:55 ache Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -58,7 +58,7 @@ options MATH_EMULATE #Support for x87 emulation
# - The kernel can swap on wd0b and sd0b, defaulting to the former
# - Crash dumps will be written to wd0b, if possible
#
config kernel root on wd0 swap on wd0 and sd0 dumps on wd0
config kernel root on wd0
#####################################################################
@ -251,7 +251,9 @@ options UNION #Union filesystem
# of kilobytes to reserve for the filesystem.
options "MFS_ROOT=10"
#
# Allow this many swap-devices.
options "NSWAPDEV=20"
# Disk quotas are supported when this option is enabled. If you
# change the value of this option, you must do a `make clean' in your
# kernel compile directory in order to get a working kernel.

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $Id: autoconf.c,v 1.29 1995/05/11 19:26:07 rgrimes Exp $
* $Id: autoconf.c,v 1.30 1995/05/12 19:17:11 wollman Exp $
*/
/*
@ -57,7 +57,6 @@
#include <machine/md_var.h>
#include <machine/pte.h>
static void swapconf(void);
static void setroot(void);
/*
@ -209,43 +208,9 @@ configure()
* parameter based on device(s) used.
*/
setconf();
swapconf();
cold = 0;
}
/*
* Configure swap space and related parameters.
*/
static void
swapconf()
{
register struct swdevt *swp;
register int nblks;
for (swp = swdevt; swp->sw_dev > 0; swp++)
{
unsigned d = major(swp->sw_dev);
if (d > nblkdev) break;
if (bdevsw[d].d_psize) {
nblks = (*bdevsw[d].d_psize)(swp->sw_dev);
if (nblks > 0 &&
(swp->sw_nblks == 0 || swp->sw_nblks > nblks))
swp->sw_nblks = nblks;
else
swp->sw_nblks = 0;
}
swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
}
if (dumpdev != NODEV) {
if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) -
Maxmem*NBPG/512;
if (dumplo < 0)
dumplo = 0;
}
}
int
setdumpdev(dev_t dev)
{
@ -267,7 +232,6 @@ setdumpdev(dev_t dev)
/*NOTREACHED*/
}
#define DOSWAP /* change swdevt and dumpdev */
u_long bootdev = 0; /* should be dev_t, but not until 32 bits */
static char devname[][2] = {
@ -325,25 +289,4 @@ setroot()
devname[majdev][0], devname[majdev][1],
mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT),
part + 'a');
#ifdef DOSWAP
mindev &= ~PARTITIONMASK;
for (swp = swdevt; swp->sw_dev; swp++) {
if (majdev == major(swp->sw_dev) &&
mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
temp = swdevt[0].sw_dev;
swdevt[0].sw_dev = swp->sw_dev;
swp->sw_dev = temp;
break;
}
}
if (swp->sw_dev == 0)
return;
/*
* If dumpdev was the same as the old primary swap
* device, move it to the new primary swap device.
*/
if (temp == dumpdev)
dumpdev = swdevt[0].sw_dev;
#endif
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
* $Id: init_main.c,v 1.22 1995/04/23 04:13:51 phk Exp $
* $Id: init_main.c,v 1.23 1995/05/04 08:21:24 davidg Exp $
*/
#include <sys/param.h>
@ -294,7 +294,6 @@ main(framep)
VREF(fdp->fd_fd.fd_cdir);
VOP_UNLOCK(rootvnode);
fdp->fd_fd.fd_rdir = NULL;
swapinit();
/*
* Now can look at time, having had a chance to verify the time

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_vfsops.c,v 1.11 1995/03/16 18:15:40 bde Exp $
* $Id: nfs_vfsops.c,v 1.12 1995/03/16 20:23:46 wollman Exp $
*/
#include <sys/param.h>
@ -273,32 +273,15 @@ nfs_mountroot()
(void) nfs_mountdiskless(buf, "/swap", 0,
&nd->swap_saddr, &nd->swap_args, &vp);
for (i=0;swdevt[i].sw_dev != NODEV;i++) ;
/*
* Since the swap file is not the root dir of a file system,
* hack it to a regular file.
*/
vp->v_type = VREG;
vp->v_flag = 0;
swapdev_vp = vp;
VREF(vp);
swdevt[i].sw_vp = vp;
swdevt[i].sw_nblks = nd->swap_nblks*2;
if (!swdevt[i].sw_nblks) {
swdevt[i].sw_nblks = 2048;
printf("defaulting to %d kbyte.\n",
swdevt[i].sw_nblks/2);
} else
printf("using %d kbyte.\n",swdevt[i].sw_nblks/2);
} else {
/*
* No NFS swap space was specified, try using local disk
*/
if (bdevvp(swapdev, &swapdev_vp))
panic("nfs_mountroot: can't setup bdevvp for swap");
}
swaponvp(p, vp, NODEV, nd->swap_nblks * 2);
}
/*
* Create the rootfs mount point.

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94
* $Id: nfs_vfsops.c,v 1.11 1995/03/16 18:15:40 bde Exp $
* $Id: nfs_vfsops.c,v 1.12 1995/03/16 20:23:46 wollman Exp $
*/
#include <sys/param.h>
@ -273,32 +273,15 @@ nfs_mountroot()
(void) nfs_mountdiskless(buf, "/swap", 0,
&nd->swap_saddr, &nd->swap_args, &vp);
for (i=0;swdevt[i].sw_dev != NODEV;i++) ;
/*
* Since the swap file is not the root dir of a file system,
* hack it to a regular file.
*/
vp->v_type = VREG;
vp->v_flag = 0;
swapdev_vp = vp;
VREF(vp);
swdevt[i].sw_vp = vp;
swdevt[i].sw_nblks = nd->swap_nblks*2;
if (!swdevt[i].sw_nblks) {
swdevt[i].sw_nblks = 2048;
printf("defaulting to %d kbyte.\n",
swdevt[i].sw_nblks/2);
} else
printf("using %d kbyte.\n",swdevt[i].sw_nblks/2);
} else {
/*
* No NFS swap space was specified, try using local disk
*/
if (bdevvp(swapdev, &swapdev_vp))
panic("nfs_mountroot: can't setup bdevvp for swap");
}
swaponvp(p, vp, NODEV, nd->swap_nblks * 2);
}
/*
* Create the rootfs mount point.

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)conf.h 8.3 (Berkeley) 1/21/94
* $Id: conf.h,v 1.12 1995/04/23 09:36:59 bde Exp $
* $Id: conf.h,v 1.13 1995/05/12 19:17:24 wollman Exp $
*/
#ifndef _SYS_CONF_H_
@ -138,7 +138,6 @@ struct swdevt {
#define sw_freed sw_flags /* XXX compat */
#ifdef KERNEL
extern struct swdevt swdevt[];
extern int setdumpdev __P((dev_t));
dev_t chrtoblk __P((dev_t dev));

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)gmon.h 8.2 (Berkeley) 1/4/94
* $Id: gmon.h,v 1.3 1995/01/29 06:23:34 bde Exp $
* $Id: gmon.h,v 1.4 1995/03/16 18:16:17 bde Exp $
*/
#ifndef _SYS_GMON_H_
@ -124,8 +124,8 @@ struct rawarc {
/*
* general rounding functions.
*/
#define ROUNDDOWN(x,y) (((x)/(y))*(y))
#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
#define ROUNDDOWN(x,y) rounddown(x,y)
#define ROUNDUP(x,y) roundup(x,y)
/*
* The profiling data structures are housed in this structure.

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)conf.h 8.3 (Berkeley) 1/21/94
* $Id: conf.h,v 1.12 1995/04/23 09:36:59 bde Exp $
* $Id: conf.h,v 1.13 1995/05/12 19:17:24 wollman Exp $
*/
#ifndef _SYS_CONF_H_
@ -138,7 +138,6 @@ struct swdevt {
#define sw_freed sw_flags /* XXX compat */
#ifdef KERNEL
extern struct swdevt swdevt[];
extern int setdumpdev __P((dev_t));
dev_t chrtoblk __P((dev_t dev));

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)param.h 8.2 (Berkeley) 1/21/94
* $Id: param.h,v 1.6 1995/01/09 16:05:13 davidg Exp $
* $Id: param.h,v 1.7 1995/02/07 03:33:05 davidg Exp $
*/
#ifndef _SYS_PARAM_H_
@ -180,6 +180,7 @@
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
#define rounddown(x, y) (((x)/(y))*(y))
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
#define powerof2(x) ((((x)-1)&(x))==0)

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)systm.h 8.4 (Berkeley) 2/23/94
* $Id: systm.h,v 1.19 1995/04/04 02:02:28 davidg Exp $
* $Id: systm.h,v 1.20 1995/05/02 05:35:07 davidg Exp $
*/
#ifndef _SYS_SYSTM_H_
@ -81,6 +81,7 @@ extern char copyright[]; /* system copyright */
extern int nblkdev; /* number of entries in bdevsw */
extern int nchrdev; /* number of entries in cdevsw */
extern struct swdevt *swdevt; /* swap-device information */
extern int nswdev; /* number of swap devices */
extern int nswap; /* size of swap space */

View File

@ -39,7 +39,7 @@
* from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
*
* @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
* $Id: swap_pager.c,v 1.37 1995/05/07 06:36:59 dyson Exp $
* $Id: swap_pager.c,v 1.38 1995/05/10 18:56:02 davidg Exp $
*/
/*
@ -103,7 +103,7 @@ struct swpagerclean {
#define SWB_EMPTY (-1)
struct swpclean swap_pager_done; /* list of compileted page cleans */
struct swpclean swap_pager_done; /* list of completed page cleans */
struct swpclean swap_pager_inuse; /* list of pending page cleans */
struct swpclean swap_pager_free; /* list of free pager clean structs */
struct pagerlst swap_pager_list; /* list of "named" anon regions */

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
* $Id: vm_extern.h,v 1.13 1995/03/16 18:17:08 bde Exp $
* $Id: vm_extern.h,v 1.14 1995/05/10 18:56:04 davidg Exp $
*/
#ifndef _VM_EXTERN_H_
@ -98,10 +98,9 @@ void loadav __P((struct loadavg *));
void munmapfd __P((struct proc *, int));
int pager_cache __P((vm_object_t, boolean_t));
void sched __P((void));
void swapinit __P((void));
int swaponvp __P((struct proc *, struct vnode *, dev_t , u_long ));
void swapout __P((struct proc *));
void swapout_threads __P((void));
int swfree __P((struct proc *, int));
void swstrategy __P((struct buf *));
void thread_block __P((char *));
void thread_sleep __P((int, simple_lock_t, boolean_t));

View File

@ -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;