Fixed bmap run-length brokeness.
Use bmap run-length extension when doing clustered paging. Submitted by: John Dyson
This commit is contained in:
parent
2700d33c07
commit
efc68ce10f
sys
fs
miscfs
nfs
nfsclient
ufs/mfs
vm
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)fifo_vnops.c 8.2 (Berkeley) 1/4/94
|
||||
* $Id: fifo_vnops.c,v 1.5 1994/09/22 19:38:07 wollman Exp $
|
||||
* $Id: fifo_vnops.c,v 1.6 1994/10/02 17:48:00 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -356,6 +356,8 @@ fifo_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_vnops.c 8.6 (Berkeley) 2/7/94
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.6 1994/09/24 17:01:05 davidg Exp $
|
||||
* $Id: procfs_vnops.c,v 1.7 1994/10/10 07:55:40 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -187,6 +187,8 @@ procfs_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)spec_vnops.c 8.6 (Berkeley) 4/9/94
|
||||
* $Id: spec_vnops.c,v 1.8 1994/10/28 12:41:59 jkh Exp $
|
||||
* $Id: spec_vnops.c,v 1.9 1994/11/14 13:22:52 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -512,6 +512,8 @@ spec_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)fifo_vnops.c 8.2 (Berkeley) 1/4/94
|
||||
* $Id: fifo_vnops.c,v 1.5 1994/09/22 19:38:07 wollman Exp $
|
||||
* $Id: fifo_vnops.c,v 1.6 1994/10/02 17:48:00 phk Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -356,6 +356,8 @@ fifo_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_vnops.c 8.6 (Berkeley) 2/7/94
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.6 1994/09/24 17:01:05 davidg Exp $
|
||||
* $Id: procfs_vnops.c,v 1.7 1994/10/10 07:55:40 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -187,6 +187,8 @@ procfs_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)spec_vnops.c 8.6 (Berkeley) 4/9/94
|
||||
* $Id: spec_vnops.c,v 1.8 1994/10/28 12:41:59 jkh Exp $
|
||||
* $Id: spec_vnops.c,v 1.9 1994/11/14 13:22:52 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -512,6 +512,8 @@ spec_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
|
||||
* $Id: nfs_vnops.c,v 1.10 1994/10/17 17:47:41 phk Exp $
|
||||
* $Id: nfs_vnops.c,v 1.11 1995/01/09 16:05:09 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2068,6 +2068,8 @@ nfs_bmap(ap)
|
||||
*ap->a_vpp = vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize);
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
|
||||
* $Id: nfs_vnops.c,v 1.10 1994/10/17 17:47:41 phk Exp $
|
||||
* $Id: nfs_vnops.c,v 1.11 1995/01/09 16:05:09 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -2068,6 +2068,8 @@ nfs_bmap(ap)
|
||||
*ap->a_vpp = vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize);
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)mfs_vnops.c 8.3 (Berkeley) 9/21/93
|
||||
* $Id: mfs_vnops.c,v 1.6 1994/09/25 22:31:08 davidg Exp $
|
||||
* $Id: mfs_vnops.c,v 1.7 1994/10/09 07:35:12 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -230,6 +230,8 @@ mfs_bmap(ap)
|
||||
*ap->a_vpp = ap->a_vp;
|
||||
if (ap->a_bnp != NULL)
|
||||
*ap->a_bnp = ap->a_bn;
|
||||
if (ap->a_runp != NULL)
|
||||
*ap->a_runp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
|
||||
* $Id: vnode_pager.c,v 1.20 1995/01/11 20:00:10 davidg Exp $
|
||||
* $Id: vnode_pager.c,v 1.21 1995/01/24 10:14:09 davidg Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -491,9 +491,10 @@ vnode_pager_freepage(m)
|
||||
* file address
|
||||
*/
|
||||
vm_offset_t
|
||||
vnode_pager_addr(vp, address)
|
||||
vnode_pager_addr(vp, address, run)
|
||||
struct vnode *vp;
|
||||
vm_offset_t address;
|
||||
int *run;
|
||||
{
|
||||
int rtaddress;
|
||||
int bsize;
|
||||
@ -509,12 +510,18 @@ vnode_pager_addr(vp, address)
|
||||
vblock = address / bsize;
|
||||
voffset = address % bsize;
|
||||
|
||||
err = VOP_BMAP(vp, vblock, &rtvp, &block, 0);
|
||||
err = VOP_BMAP(vp, vblock, &rtvp, &block, run);
|
||||
|
||||
if (err)
|
||||
if (err || (block == -1))
|
||||
rtaddress = -1;
|
||||
else
|
||||
else {
|
||||
rtaddress = block * DEV_BSIZE + voffset;
|
||||
if( run) {
|
||||
*run += 1;
|
||||
*run *= bsize/PAGE_SIZE;
|
||||
*run -= voffset/PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return rtaddress;
|
||||
}
|
||||
@ -596,7 +603,7 @@ vnode_pager_input_smlfs(vnp, m)
|
||||
if ((vm_page_bits(m->offset + i * bsize, bsize) & m->valid))
|
||||
continue;
|
||||
|
||||
fileaddr = vnode_pager_addr(vp, m->offset + i * bsize);
|
||||
fileaddr = vnode_pager_addr(vp, m->offset + i * bsize, (int *)0);
|
||||
if (fileaddr != -1) {
|
||||
bp = getpbuf();
|
||||
|
||||
@ -727,8 +734,10 @@ vnode_pager_input(vnp, m, count, reqpage)
|
||||
int bsize;
|
||||
|
||||
int first, last;
|
||||
int reqaddr, firstaddr;
|
||||
int firstaddr;
|
||||
int block, offset;
|
||||
int runpg;
|
||||
int runend;
|
||||
|
||||
struct buf *bp, *bpa;
|
||||
int counta;
|
||||
@ -797,55 +806,45 @@ vnode_pager_input(vnp, m, count, reqpage)
|
||||
* here on direct device I/O
|
||||
*/
|
||||
|
||||
reqaddr = vnode_pager_addr(vp, foff);
|
||||
if (reqaddr == -1 && foff < vnp->vnp_size) {
|
||||
printf("reqaddr: %d, foff: %d, vnp_size: %d\n",
|
||||
reqaddr, foff, vnp->vnp_size);
|
||||
Debugger("");
|
||||
}
|
||||
s = splbio();
|
||||
|
||||
firstaddr = -1;
|
||||
/*
|
||||
* Make sure that our I/O request is contiguous. Scan backward and
|
||||
* stop for the first discontiguous entry or stop for a page being in
|
||||
* buffer cache.
|
||||
* calculate the run that includes the required page
|
||||
*/
|
||||
failflag = 0;
|
||||
first = reqpage;
|
||||
for (i = reqpage - 1; i >= 0; --i) {
|
||||
if (failflag ||
|
||||
(vnode_pager_addr(vp, m[i]->offset))
|
||||
!= reqaddr + (i - reqpage) * PAGE_SIZE) {
|
||||
for(first = 0, i = 0; i < count; i = runend) {
|
||||
firstaddr = vnode_pager_addr(vp, m[i]->offset, &runpg);
|
||||
if (firstaddr == -1) {
|
||||
if( i == reqpage && foff < vnp->vnp_size) {
|
||||
printf("vnode_pager_input: unexpected missing page: firstaddr: %d, foff: %d, vnp_size: %d\n",
|
||||
firstaddr, foff, vnp->vnp_size);
|
||||
panic("vnode_pager_input:...");
|
||||
}
|
||||
vnode_pager_freepage(m[i]);
|
||||
failflag = 1;
|
||||
} else {
|
||||
first = i;
|
||||
runend = i + 1;
|
||||
first = runend;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan forward and stop for the first non-contiguous entry or stop
|
||||
* for a page being in buffer cache.
|
||||
*/
|
||||
failflag = 0;
|
||||
last = reqpage + 1;
|
||||
for (i = reqpage + 1; i < count; i++) {
|
||||
if (failflag ||
|
||||
(vnode_pager_addr(vp, m[i]->offset))
|
||||
!= reqaddr + (i - reqpage) * PAGE_SIZE) {
|
||||
vnode_pager_freepage(m[i]);
|
||||
failflag = 1;
|
||||
runend = i + runpg;
|
||||
if( runend <= reqpage) {
|
||||
int j;
|
||||
for(j = i; j < runend; j++) {
|
||||
vnode_pager_freepage(m[j]);
|
||||
}
|
||||
} else {
|
||||
last = i + 1;
|
||||
if( runpg < (count - first)) {
|
||||
for(i=first + runpg; i < count; i++)
|
||||
vnode_pager_freepage(m[i]);
|
||||
count = first + runpg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
first = runend;
|
||||
}
|
||||
splx(s);
|
||||
|
||||
/*
|
||||
* the first and last page have been calculated now, move input pages
|
||||
* to be zero based...
|
||||
*/
|
||||
count = last;
|
||||
if (first != 0) {
|
||||
for (i = first; i < count; i++) {
|
||||
m[i - first] = m[i];
|
||||
@ -853,15 +852,16 @@ vnode_pager_input(vnp, m, count, reqpage)
|
||||
count -= first;
|
||||
reqpage -= first;
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate the file virtual address for the transfer
|
||||
*/
|
||||
foff = m[0]->offset;
|
||||
|
||||
/*
|
||||
* and get the disk physical address (in bytes)
|
||||
*/
|
||||
firstaddr = vnode_pager_addr(vp, foff);
|
||||
#if 0
|
||||
printf("foff: 0x%lx, firstaddr: 0x%lx\n",
|
||||
foff, firstaddr);
|
||||
DELAY(6000000);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* calculate the size of the transfer
|
||||
@ -1085,7 +1085,7 @@ vnode_pager_output_smlfs(vnp, m)
|
||||
/*
|
||||
* calculate logical block and offset
|
||||
*/
|
||||
fileaddr = vnode_pager_addr(vp, m->offset + i * bsize);
|
||||
fileaddr = vnode_pager_addr(vp, m->offset + i * bsize, (int *)0);
|
||||
if (fileaddr != -1) {
|
||||
|
||||
bp = getpbuf();
|
||||
@ -1158,6 +1158,7 @@ vnode_pager_output(vnp, m, count, rtvals)
|
||||
int s;
|
||||
daddr_t block;
|
||||
struct timeval tv;
|
||||
int runpg;
|
||||
|
||||
int error = 0;
|
||||
|
||||
@ -1229,19 +1230,9 @@ retryoutput:
|
||||
return rtvals[0];
|
||||
}
|
||||
foff = m[0]->offset;
|
||||
reqaddr = vnode_pager_addr(vp, foff);
|
||||
|
||||
/*
|
||||
* Scan forward and stop for the first non-contiguous entry or stop
|
||||
* for a page being in buffer cache.
|
||||
*/
|
||||
for (i = 1; i < count; i++) {
|
||||
if (vnode_pager_addr(vp, m[i]->offset)
|
||||
!= reqaddr + i * PAGE_SIZE) {
|
||||
count = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reqaddr = vnode_pager_addr(vp, foff, &runpg);
|
||||
if( runpg < count)
|
||||
count = runpg;
|
||||
|
||||
/*
|
||||
* calculate the size of the transfer
|
||||
|
Loading…
x
Reference in New Issue
Block a user