summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-08-23 18:11:53 +0000
committeralc <alc@FreeBSD.org>2003-08-23 18:11:53 +0000
commit5d6f66de90c5944b3c704c22790b24284fadb727 (patch)
tree084c9fdff8585e9dbaa7e37ded52003077afe6b7
parentcea9a5fcc59afc95f24c82f7c01f28cec4662a70 (diff)
downloadFreeBSD-src-5d6f66de90c5944b3c704c22790b24284fadb727.zip
FreeBSD-src-5d6f66de90c5944b3c704c22790b24284fadb727.tar.gz
Hold the page queues lock when performing vm_page_clear_dirty() and
vm_page_set_invalid().
-rw-r--r--sys/kern/vfs_bio.c2
-rw-r--r--sys/vm/vm_page.c5
-rw-r--r--sys/vm/vnode_pager.c2
3 files changed, 7 insertions, 2 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index e85a2d3..663a504 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1351,7 +1351,9 @@ brelse(struct buf * bp)
(PAGE_SIZE - poffset) : resid;
KASSERT(presid >= 0, ("brelse: extra page"));
+ vm_page_lock_queues();
vm_page_set_invalid(m, poffset, presid);
+ vm_page_unlock_queues();
if (had_bogus)
printf("avoided corruption bug in bogus_page/brelse code\n");
}
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 76a4280..7806077 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1596,7 +1596,8 @@ vm_page_set_dirty(vm_page_t m, int base, int size)
void
vm_page_clear_dirty(vm_page_t m, int base, int size)
{
- GIANT_REQUIRED;
+
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
m->dirty &= ~vm_page_bits(base, size);
}
@@ -1613,8 +1614,8 @@ vm_page_set_invalid(vm_page_t m, int base, int size)
{
int bits;
- GIANT_REQUIRED;
bits = vm_page_bits(base, size);
+ mtx_assert(&vm_page_queue_mtx, MA_OWNED);
m->valid &= ~bits;
m->dirty &= ~bits;
m->object->generation++;
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index a708aea..4ddc6bb 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -1021,8 +1021,10 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
maxsize = object->un_pager.vnp.vnp_size - poffset;
ncount = btoc(maxsize);
if ((pgoff = (int)maxsize & PAGE_MASK) != 0) {
+ vm_page_lock_queues();
vm_page_clear_dirty(m[ncount - 1], pgoff,
PAGE_SIZE - pgoff);
+ vm_page_unlock_queues();
}
} else {
maxsize = 0;
OpenPOWER on IntegriCloud