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().
This commit is contained in:
parent
126b14f7e8
commit
0d53a17bde
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=191935
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user