summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1996-09-14 04:40:33 +0000
committerdyson <dyson@FreeBSD.org>1996-09-14 04:40:33 +0000
commite775010c52cf95a3ac8809efca52d8019675f8cd (patch)
tree44c3c2b892127b2b5d43b6ae937317952b964c0f /sys/kern/vfs_bio.c
parente0185c45da38614044b4599ba3d9c8b8b8d96eb1 (diff)
downloadFreeBSD-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.c18
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);
OpenPOWER on IntegriCloud