Fixed broken offset use in vfs_unbusy_pages() which resulted in several

different types of panics/inconsistencies with NFS clients.
Cleared PG_WANTED where appropriate.
Added checks for buffer busy in allocbuf and biodone.

Reviewed by:	John Dyson
This commit is contained in:
dg 1995-07-25 05:03:06 +00:00
parent 0594919895
commit 107327f072

View File

@ -18,7 +18,7 @@
* 5. Modifications may be freely made to this file if the above conditions
* are met.
*
* $Id: vfs_bio.c,v 1.52 1995/07/23 19:37:52 davidg Exp $
* $Id: vfs_bio.c,v 1.53 1995/07/24 03:16:41 davidg Exp $
*/
/*
@ -932,6 +932,9 @@ allocbuf(struct buf * bp, int size)
int newbsize, mbsize;
int i;
if (!(bp->b_flags & B_BUSY))
panic("allocbuf: buffer not busy");
if ((bp->b_flags & B_VMIO) == 0) {
/*
* Just get anonymous memory from the kernel
@ -1129,6 +1132,9 @@ biodone(register struct buf * bp)
int s;
s = splbio();
if (!(bp->b_flags & B_BUSY))
panic("biodone: buffer not busy");
if (bp->b_flags & B_DONE) {
splx(s);
printf("biodone: buffer already done\n");
@ -1224,8 +1230,10 @@ biodone(register struct buf * bp)
panic("biodone: page busy < 0\n");
}
--m->busy;
if( (m->busy == 0) && (m->flags & PG_WANTED))
if ((m->busy == 0) && (m->flags & PG_WANTED)) {
m->flags &= ~PG_WANTED;
wakeup((caddr_t) m);
}
--obj->paging_in_progress;
foff += resid;
iosize -= resid;
@ -1294,13 +1302,13 @@ vfs_unbusy_pages(struct buf * bp)
vm_object_t obj = vp->v_object;
vm_offset_t foff;
foff = vp->v_mount->mnt_stat.f_iosize * bp->b_lblkno;
foff = trunc_page(vp->v_mount->mnt_stat.f_iosize * bp->b_lblkno);
for (i = 0; i < bp->b_npages; i++) {
vm_page_t m = bp->b_pages[i];
if (m == bogus_page) {
m = vm_page_lookup(obj, foff);
m = vm_page_lookup(obj, foff + i * PAGE_SIZE);
if (!m) {
panic("vfs_unbusy_pages: page missing\n");
}
@ -1309,8 +1317,10 @@ vfs_unbusy_pages(struct buf * bp)
}
--obj->paging_in_progress;
--m->busy;
if( (m->busy == 0) && (m->flags & PG_WANTED))
if ((m->busy == 0) && (m->flags & PG_WANTED)) {
m->flags &= ~PG_WANTED;
wakeup((caddr_t) m);
}
}
if (obj->paging_in_progress == 0 &&
(obj->flags & OBJ_PIPWNT)) {