diff options
author | alc <alc@FreeBSD.org> | 2003-06-18 04:27:18 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-06-18 04:27:18 +0000 |
commit | cacc52e8aa28d836df641ea037690d2b04cb4dcc (patch) | |
tree | e7e7f5015a9cc484acf363887e325f7b9498d795 /sys/vm | |
parent | b466954d4e6ffa78f98b19458bcf1560d8d8c776 (diff) | |
download | FreeBSD-src-cacc52e8aa28d836df641ea037690d2b04cb4dcc.zip FreeBSD-src-cacc52e8aa28d836df641ea037690d2b04cb4dcc.tar.gz |
Lock the vm object when freeing a vm page.
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vnode_pager.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 993725d..bfc255d 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -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"); } |