Fix the swap backed vn case - this was broken by my rev 1.128 to

swap_pager.c and related commits.

Essentially swap_pager.c is backed out to before the changes, but
swapdev_vp is converted into a real vnode with just VOP_STRATEGY().
It no longer abuses specfs vnops and no longer needs a dev_t and
/dev/drum (or /dev/swapdev) for the intermediate layer.

This essentially restores the vnode interface as the interface to the
bottom of the swap pager, and vm_swap.c provides a clean vnode interface.

This will need to be revisited when we swap to files (vnodes) - which
is the other reason for keeping the vnode interface between the swap pager
and the swap devices.

OK'ed by:	dillon
This commit is contained in:
peter 1999-12-28 07:30:55 +00:00
parent 94ce1a985e
commit 6e0007fa82
2 changed files with 50 additions and 22 deletions

View File

@ -120,7 +120,7 @@ static struct swblock **swhash;
static int swhash_mask;
static int swap_async_max = 4; /* maximum in-progress async I/O's */
static struct vnode *swapdev_vp; /* XXX: This is not quite a real vnode */
extern struct vnode *swapdev_vp; /* from vm_swap.c */
SYSCTL_INT(_vm, OID_AUTO, swap_async_max,
CTLFLAG_RW, &swap_async_max, 0, "Maximum running async swap ops");
@ -328,11 +328,6 @@ swap_pager_swap_init()
bzero(swhash, sizeof(struct swblock *) * n);
swhash_mask = n - 1;
n = getnewvnode(VT_NON, NULL, spec_vnodeop_p, &swapdev_vp);
if (n)
panic("Cannot get vnode for swapdev");
swapdev_vp->v_type = VBLK;
}
/*
@ -1136,11 +1131,11 @@ swap_pager_getpages(object, m, count, reqpage)
* The other pages in our m[] array are also released on completion,
* so we cannot assume they are valid anymore either.
*
* NOTE: b_blkno is destroyed by the call to swstrategy()
* NOTE: b_blkno is destroyed by the call to VOP_STRATEGY
*/
BUF_KERNPROC(bp);
swstrategy(bp);
VOP_STRATEGY(bp->b_vp, bp);
/*
* wait for the page we want to complete. PG_SWAPINPROG is always
@ -1193,7 +1188,7 @@ swap_pager_getpages(object, m, count, reqpage)
* We support both OBJT_DEFAULT and OBJT_SWAP objects. DEFAULT objects
* are automatically converted to SWAP objects.
*
* In a low memory situation we may block in swstrategy(), but the new
* In a low memory situation we may block in VOP_STRATEGY(), but the new
* vm_page reservation system coupled with properly written VFS devices
* should ensure that no low-memory deadlock occurs. This is an area
* which needs work.
@ -1387,13 +1382,13 @@ swap_pager_putpages(object, m, count, sync, rtvals)
/*
* asynchronous
*
* NOTE: b_blkno is destroyed by the call to swstrategy()
* NOTE: b_blkno is destroyed by the call to VOP_STRATEGY
*/
if (sync == FALSE) {
bp->b_iodone = swp_pager_async_iodone;
BUF_KERNPROC(bp);
swstrategy(bp);
VOP_STRATEGY(bp->b_vp, bp);
for (j = 0; j < n; ++j)
rtvals[i+j] = VM_PAGER_PEND;
@ -1403,11 +1398,11 @@ swap_pager_putpages(object, m, count, sync, rtvals)
/*
* synchronous
*
* NOTE: b_blkno is destroyed by the call to swstrategy()
* NOTE: b_blkno is destroyed by the call to VOP_STRATEGY
*/
bp->b_iodone = swp_pager_sync_iodone;
swstrategy(bp);
VOP_STRATEGY(bp->b_vp, bp);
/*
* Wait for the sync I/O to complete, then update rtvals.

View File

@ -68,36 +68,45 @@ static int nswap; /* first block after the interleaved devs */
static int nswdev = NSWAPDEV;
int vm_swap_size;
static int swapdev_strategy __P((struct vop_strategy_args *ap));
struct vnode *swapdev_vp;
/*
* swstrategy:
* swapdev_strategy:
*
* Perform swap strategy interleave device selection
* VOP_STRATEGY() for swapdev_vp.
* Perform swap strategy interleave device selection.
*
* The bp is expected to be locked and *not* B_DONE on call.
*/
void
swstrategy(bp)
register struct buf *bp;
static int
swapdev_strategy(ap)
struct vop_strategy_args /* {
struct vnode *a_vp;
struct buf *a_bp;
} */ *ap;
{
int s, sz, off, seg, index;
register struct swdevt *sp;
struct vnode *vp;
struct buf *bp;
bp = ap->a_bp;
sz = howmany(bp->b_bcount, PAGE_SIZE);
/*
* Convert interleaved swap into per-device swap. Note that
* the block size is left in PAGE_SIZE'd chunks (for the newswap)
* here.
*/
if (nswdev > 1) {
off = bp->b_blkno % dmmax;
if (off + sz > dmmax) {
bp->b_error = EINVAL;
bp->b_flags |= B_ERROR;
biodone(bp);
return;
return 0;
}
seg = bp->b_blkno / dmmax;
index = seg % nswdev;
@ -111,14 +120,14 @@ swstrategy(bp)
bp->b_error = EINVAL;
bp->b_flags |= B_ERROR;
biodone(bp);
return;
return 0;
}
bp->b_dev = sp->sw_device;
if (sp->sw_vp == NULL) {
bp->b_error = ENODEV;
bp->b_flags |= B_ERROR;
biodone(bp);
return;
return 0;
}
/*
@ -142,8 +151,24 @@ swstrategy(bp)
pbreassignbuf(bp, sp->sw_vp);
splx(s);
VOP_STRATEGY(bp->b_vp, bp);
return 0;
}
/*
* Create a special vnode op vector for swapdev_vp - we only use
* VOP_STRATEGY(), everything else returns an error.
*/
vop_t **swapdev_vnodeop_p;
static struct vnodeopv_entry_desc swapdev_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *) vop_defaultop },
{ &vop_strategy_desc, (vop_t *) swapdev_strategy },
{ NULL, NULL }
};
static struct vnodeopv_desc swapdev_vnodeop_opv_desc =
{ &swapdev_vnodeop_p, swapdev_vnodeop_entries };
VNODEOP_SET(swapdev_vnodeop_opv_desc);
/*
* System call swapon(name) enables swapping on device name,
* which must be in the swdevsw. Return EBUSY
@ -186,6 +211,14 @@ swapon(p, uap)
if (error)
vrele(vp);
if (!swapdev_vp) {
error = getnewvnode(VT_NON, NULL, swapdev_vnodeop_p,
&swapdev_vp);
if (error)
panic("Cannot get vnode for swapdev");
swapdev_vp->v_type = VNON; /* Untyped */
}
return (error);
}