1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-12 14:29:28 +00:00

Lock the vm object when freeing a vm page.

This commit is contained in:
Alan Cox 2003-06-18 04:27:18 +00:00
parent da9f245470
commit 31953be936
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=116512

View File

@ -676,11 +676,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
* if we can't bmap, use old VOP code
*/
if (VOP_BMAP(vp, 0, &dp, 0, NULL, NULL)) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = 0; i < count; i++)
if (i != reqpage)
vm_page_free(m[i]);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
cnt.v_vnodein++;
cnt.v_vnodepgsin++;
return vnode_pager_input_old(object, m[reqpage]);
@ -692,11 +694,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
*/
} else if ((PAGE_SIZE / bsize) > 1 &&
(vp->v_mount->mnt_stat.f_type != nfs_mount_type)) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = 0; i < count; i++)
if (i != reqpage)
vm_page_free(m[i]);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
cnt.v_vnodein++;
cnt.v_vnodepgsin++;
return vnode_pager_input_smlfs(object, m[reqpage]);
@ -708,11 +712,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
* media.
*/
if (m[reqpage]->valid == VM_PAGE_BITS_ALL) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = 0; i < count; i++)
if (i != reqpage)
vm_page_free(m[i]);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
return VM_PAGER_OK;
}
m[reqpage]->valid = 0;
@ -729,6 +735,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
firstaddr = vnode_pager_addr(vp,
IDX_TO_OFF(m[i]->pindex), &runpg);
if (firstaddr == -1) {
VM_OBJECT_LOCK(object);
if (i == reqpage && foff < object->un_pager.vnp.vnp_size) {
panic("vnode_pager_getpages: unexpected missing page: firstaddr: %d, foff: 0x%jx%08jx, vnp_size: 0x%jx%08jx",
firstaddr, (uintmax_t)(foff >> 32),
@ -740,22 +747,27 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
vm_page_lock_queues();
vm_page_free(m[i]);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
runend = i + 1;
first = runend;
continue;
}
runend = i + runpg;
if (runend <= reqpage) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (j = i; j < runend; j++)
vm_page_free(m[j]);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
} else {
if (runpg < (count - first)) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = first + runpg; i < count; i++)
vm_page_free(m[i]);
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
count = first + runpg;
}
break;
@ -849,6 +861,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
*/
relpbuf(bp, &vnode_pbuf_freecnt);
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = 0, tfoff = foff; i < count; i++, tfoff = nextoff) {
vm_page_t mt;
@ -907,6 +920,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
}
}
vm_page_unlock_queues();
VM_OBJECT_UNLOCK(object);
if (error) {
printf("vnode_pager_getpages: I/O read error\n");
}