summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2009-05-09 08:30:44 +0000
committeralc <alc@FreeBSD.org>2009-05-09 08:30:44 +0000
commit2902f54fb4ea28264b15fd28d0d6c81fd524cebe (patch)
treefd771168b6dc023886bb944cc8f9f58bba502563 /sys/vm
parentc2d44ad8f8ba6650acee0ef9f2be29c218e4a591 (diff)
downloadFreeBSD-src-2902f54fb4ea28264b15fd28d0d6c81fd524cebe.zip
FreeBSD-src-2902f54fb4ea28264b15fd28d0d6c81fd524cebe.tar.gz
Fix a race involving vnode_pager_input_smlfs(). Specifically, in the case
that vnode_pager_input_smlfs() zeroes the page, it should not mark the page as valid until after the page is zeroed. Otherwise, the page could be mapped for read access (e.g., by vm_map_pmap_enter()) before the page is zeroed. Reviewed by: tegge Eliminate gratuitous clearing of the page's dirty mask by vnode_pager_input_smlfs(). Instead, assert that the page is clean. Reviewed by: tegge Eliminate some blank lines. Eliminate pointless calls to pmap_clear_modify() and vm_page_undirty() from vnode_pager_input_old(). The page is not mapped. Therefore, it cannot have any page table entries that are modified. Eliminate an incorrect comment from vnode_pager_generic_getpages().
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vnode_pager.c33
1 files changed, 10 insertions, 23 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 19c2c33..3d6909b 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -476,7 +476,7 @@ vnode_pager_input_smlfs(object, m)
vm_object_t object;
vm_page_t m;
{
- int i;
+ int bits, i;
struct vnode *vp;
struct bufobj *bo;
struct buf *bp;
@@ -498,7 +498,8 @@ vnode_pager_input_smlfs(object, m)
for (i = 0; i < PAGE_SIZE / bsize; i++) {
vm_ooffset_t address;
- if (vm_page_bits(i * bsize, bsize) & m->valid)
+ bits = vm_page_bits(i * bsize, bsize);
+ if (m->valid & bits)
continue;
address = IDX_TO_OFF(m->pindex) + i * bsize;
@@ -543,30 +544,21 @@ vnode_pager_input_smlfs(object, m)
relpbuf(bp, &vnode_pbuf_freecnt);
if (error)
break;
-
- VM_OBJECT_LOCK(object);
- vm_page_lock_queues();
- vm_page_set_validclean(m, (i * bsize) & PAGE_MASK, bsize);
- vm_page_unlock_queues();
- VM_OBJECT_UNLOCK(object);
- } else {
- VM_OBJECT_LOCK(object);
- vm_page_lock_queues();
- vm_page_set_validclean(m, (i * bsize) & PAGE_MASK, bsize);
- vm_page_unlock_queues();
- VM_OBJECT_UNLOCK(object);
+ } else
bzero((caddr_t)sf_buf_kva(sf) + i * bsize, bsize);
- }
+ KASSERT((m->dirty & bits) == 0,
+ ("vnode_pager_input_smlfs: page %p is dirty", m));
+ VM_OBJECT_LOCK(object);
+ m->valid |= bits;
+ VM_OBJECT_UNLOCK(object);
}
sf_buf_free(sf);
if (error) {
return VM_PAGER_ERROR;
}
return VM_PAGER_OK;
-
}
-
/*
* old style vnode pager input routine
*/
@@ -627,10 +619,7 @@ vnode_pager_input_old(object, m)
VM_OBJECT_LOCK(object);
}
- vm_page_lock_queues();
- pmap_clear_modify(m);
- vm_page_undirty(m);
- vm_page_unlock_queues();
+ KASSERT(m->dirty == 0, ("vnode_pager_input_old: page %p is dirty", m));
if (!error)
m->valid = VM_PAGE_BITS_ALL;
return error ? VM_PAGER_ERROR : VM_PAGER_OK;
@@ -960,8 +949,6 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
*/
vm_page_set_validclean(mt, 0,
object->un_pager.vnp.vnp_size - tfoff);
- /* handled by vm_fault now */
- /* vm_page_zero_invalid(mt, FALSE); */
}
if (i != reqpage) {
OpenPOWER on IntegriCloud