diff options
author | dyson <dyson@FreeBSD.org> | 1996-09-14 04:40:33 +0000 |
---|---|---|
committer | dyson <dyson@FreeBSD.org> | 1996-09-14 04:40:33 +0000 |
commit | e775010c52cf95a3ac8809efca52d8019675f8cd (patch) | |
tree | 44c3c2b892127b2b5d43b6ae937317952b964c0f /sys/kern/vfs_bio.c | |
parent | e0185c45da38614044b4599ba3d9c8b8b8d96eb1 (diff) | |
download | FreeBSD-src-e775010c52cf95a3ac8809efca52d8019675f8cd.zip FreeBSD-src-e775010c52cf95a3ac8809efca52d8019675f8cd.tar.gz |
Clean up some more problems with freeing busy or wired pages. The
vfs_bio code was not waiting properly for page state until manipulating
it.
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index ed48a00..a72198a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -623,12 +623,20 @@ vfs_vmio_release(bp) for (i = 0; i < bp->b_npages; i++) { m = bp->b_pages[i]; bp->b_pages[i] = NULL; - if (m->flags & PG_WANTED) { - m->flags &= ~PG_WANTED; - wakeup(m); + while ((m->flags & PG_BUSY) || (m->busy != 0)) { + m->flags |= PG_WANTED; + tsleep(m, PVM, "vmiorl", 0); } + vm_page_unwire(m); - if (m->wire_count == 0 && (m->flags & PG_BUSY) == 0) { + + if (m->wire_count == 0) { + + if (m->flags & PG_WANTED) { + m->flags &= ~PG_WANTED; + wakeup(m); + } + if (m->valid) { if(m->dirty == 0) vm_page_test_dirty(m); @@ -639,14 +647,12 @@ vfs_vmio_release(bp) (cnt.v_free_count < cnt.v_free_min)) { if ((m->dirty == 0) && (m->hold_count == 0) && - (m->flags & PG_BUSY) == 0 && (m->busy == 0)) vm_page_cache(m); else vm_page_deactivate(m); } } else if ((m->hold_count == 0) && - ((m->flags & PG_BUSY) == 0) && (m->busy == 0)) { vm_page_protect(m, VM_PROT_NONE); vm_page_free(m); |