These changes fix a bug in the clustering code that I made worse when adding

support for EXT2FS.  Note that the Sig-11 problems appear to be caused by
this, but there is still probably an underlying VM problem that let this
clustering bug cause vnode objects to appear to be corrupted.

The direct manifestation of this bug would have been severely mis-read
files.  It is possible that processes would Sig-11 on very damaged
input files and might explain the mysterious differences in system
behaviour when phk's malloc is being used.
This commit is contained in:
John Dyson 1995-09-23 21:12:45 +00:00
parent 0c4276b066
commit 164fd96f34
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10978
2 changed files with 71 additions and 10 deletions

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.62 1995/09/04 00:20:13 dyson Exp $
* $Id: vfs_bio.c,v 1.63 1995/09/09 18:10:14 davidg Exp $
*/
/*
@ -485,10 +485,23 @@ brelse(struct buf * bp)
m->flags &= ~PG_WANTED;
}
vm_page_test_dirty(m);
if ((m->dirty & m->valid) == 0 &&
/*
* if page isn't valid, no sense in keeping it around
*/
if (m->valid == 0) {
pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE);
vm_page_free(m);
/*
* if page isn't dirty and hasn't been referenced by
* a process, then cache it
*/
} else if ((m->dirty & m->valid) == 0 &&
(m->flags & PG_REFERENCED) == 0 &&
!pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
vm_page_cache(m);
/*
* otherwise activate it
*/
} else if ((m->flags & PG_ACTIVE) == 0) {
vm_page_activate(m);
m->act_count = 0;
@ -871,11 +884,50 @@ getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo)
}
bp->b_flags |= B_BUSY | B_CACHE;
bremfree(bp);
/*
* check for size inconsistancies
* check for size inconsistancies (note that they shouldn't happen
* but do when filesystems don't handle the size changes correctly.)
* We are conservative on metadata and don't just extend the buffer
* but write and re-constitute it.
*/
if (bp->b_bcount != size) {
allocbuf(bp, size);
if (bp->b_flags & B_VMIO) {
allocbuf(bp, size);
} else {
bp->b_flags |= B_NOCACHE;
VOP_BWRITE(bp);
goto loop;
}
}
/*
* make sure that all pages in the buffer are valid, if they
* aren't, clear the cache flag.
* ASSUMPTION:
* if the buffer is greater than 1 page in size, it is assumed
* that the buffer address starts on a page boundary...
*/
if (bp->b_flags & B_VMIO) {
int szleft, i;
szleft = size;
for (i=0;i<bp->b_npages;i++) {
if (szleft > PAGE_SIZE) {
if ((bp->b_pages[i]->valid & VM_PAGE_BITS_ALL) !=
VM_PAGE_BITS_ALL) {
bp->b_flags &= ~B_CACHE;
break;
}
szleft -= PAGE_SIZE;
} else {
if (!vm_page_is_valid(bp->b_pages[i],
(((vm_offset_t) bp->b_data) & PAGE_MASK),
szleft)) {
bp->b_flags &= ~B_CACHE;
break;
}
szleft = 0;
}
}
}
splx(s);
return (bp);

View File

@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
* $Id: vfs_cluster.c,v 1.19 1995/09/03 20:32:52 dyson Exp $
* $Id: vfs_cluster.c,v 1.20 1995/09/04 00:20:15 dyson Exp $
*/
#include <sys/param.h>
@ -290,7 +290,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
panic("cluster_rbuild: size %d != filesize %d\n",
size, vp->v_mount->mnt_stat.f_iosize);
#endif
if (size * (lbn + run + 1) > filesize)
if (size * (lbn + run) > filesize)
--run;
tbp = getblk(vp, lbn, size, 0, 0);
@ -313,8 +313,8 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
bp->b_lblkno = lbn;
pbgetvp(vp, bp);
b_save = malloc(sizeof(struct buf *) * run + sizeof(struct cluster_save),
M_SEGMENT, M_WAITOK);
b_save = malloc(sizeof(struct buf *) * run +
sizeof(struct cluster_save), M_SEGMENT, M_WAITOK);
b_save->bs_nchildren = 0;
b_save->bs_children = (struct buf **) (b_save + 1);
bp->b_saveaddr = b_save;
@ -328,6 +328,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
if (i != 0) {
if ((bp->b_npages * PAGE_SIZE) + size > MAXPHYS)
break;
if (incore(vp, lbn + i))
break;
tbp = getblk(vp, lbn + i, size, 0, 0);
@ -345,6 +346,10 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
}
if (j != tbp->b_npages) {
/*
* force buffer to be re-constituted later
*/
tbp->b_flags |= B_RELBUF;
brelse(tbp);
break;
}
@ -364,13 +369,17 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
m = tbp->b_pages[j];
++m->busy;
++m->object->paging_in_progress;
if (m->valid == VM_PAGE_BITS_ALL) {
if ((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) {
m = bogus_page;
}
if ((bp->b_npages == 0) ||
(bp->b_pages[bp->b_npages - 1] != m)) {
(bp->b_bufsize & PAGE_MASK) == 0) {
bp->b_pages[bp->b_npages] = m;
bp->b_npages++;
} else {
if ( tbp->b_npages > 1) {
panic("cluster_rbuild: page unaligned filesystems not supported");
}
}
}
bp->b_bcount += tbp->b_bcount;