Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Show First 20 Lines • Show All 406 Lines • ▼ Show 20 Lines | page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes) | ||||
*/ | */ | ||||
end = rounddown2(off + nbytes, DEV_BSIZE); | end = rounddown2(off + nbytes, DEV_BSIZE); | ||||
off = roundup2(off, DEV_BSIZE); | off = roundup2(off, DEV_BSIZE); | ||||
nbytes = end - off; | nbytes = end - off; | ||||
obj = vp->v_object; | obj = vp->v_object; | ||||
zfs_vmobject_assert_wlocked(obj); | zfs_vmobject_assert_wlocked(obj); | ||||
for (;;) { | pp = vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_VALID | | ||||
if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && | VM_ALLOC_SBUSY | VM_ALLOC_NORMAL | VM_ALLOC_IGN_SBUSY); | ||||
pp->valid) { | |||||
if (vm_page_xbusied(pp)) { | |||||
/* | |||||
* Reference the page before unlocking and | |||||
* sleeping so that the page daemon is less | |||||
* likely to reclaim it. | |||||
*/ | |||||
vm_page_reference(pp); | |||||
zfs_vmobject_wunlock(obj); | |||||
vm_page_busy_sleep(pp, "zfsmwb", true); | |||||
zfs_vmobject_wlock(obj); | |||||
continue; | |||||
} | |||||
vm_page_sbusy(pp); | |||||
} else if (pp != NULL) { | |||||
ASSERT(!pp->valid); | |||||
pp = NULL; | |||||
} | |||||
if (pp != NULL) { | if (pp != NULL) { | ||||
ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL); | ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL); | ||||
vm_object_pip_add(obj, 1); | vm_object_pip_add(obj, 1); | ||||
pmap_remove_write(pp); | pmap_remove_write(pp); | ||||
if (nbytes != 0) | if (nbytes != 0) | ||||
vm_page_clear_dirty(pp, off, nbytes); | vm_page_clear_dirty(pp, off, nbytes); | ||||
} | } | ||||
break; | |||||
} | |||||
return (pp); | return (pp); | ||||
} | } | ||||
static void | static void | ||||
page_unbusy(vm_page_t pp) | page_unbusy(vm_page_t pp) | ||||
{ | { | ||||
vm_page_sunbusy(pp); | vm_page_sunbusy(pp); | ||||
vm_object_pip_wakeup(pp->object); | vm_object_pip_wakeup(pp->object); | ||||
} | } | ||||
static vm_page_t | static vm_page_t | ||||
page_wire(vnode_t *vp, int64_t start) | page_wire(vnode_t *vp, int64_t start) | ||||
{ | { | ||||
vm_object_t obj; | vm_object_t obj; | ||||
vm_page_t pp; | |||||
obj = vp->v_object; | obj = vp->v_object; | ||||
zfs_vmobject_assert_wlocked(obj); | zfs_vmobject_assert_wlocked(obj); | ||||
for (;;) { | return (vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_VALID | | ||||
if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && | VM_ALLOC_WIRED | VM_ALLOC_IGN_SBUSY | VM_ALLOC_NOBUSY)); | ||||
pp->valid) { | |||||
if (vm_page_xbusied(pp)) { | |||||
/* | |||||
* Reference the page before unlocking and | |||||
* sleeping so that the page daemon is less | |||||
* likely to reclaim it. | |||||
*/ | |||||
vm_page_reference(pp); | |||||
zfs_vmobject_wunlock(obj); | |||||
vm_page_busy_sleep(pp, "zfsmwb", true); | |||||
zfs_vmobject_wlock(obj); | |||||
continue; | |||||
} | |||||
ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL); | |||||
vm_page_lock(pp); | |||||
vm_page_wire(pp); | |||||
vm_page_unlock(pp); | |||||
} else | |||||
pp = NULL; | |||||
break; | |||||
} | |||||
return (pp); | |||||
} | } | ||||
static void | static void | ||||
page_unwire(vm_page_t pp) | page_unwire(vm_page_t pp) | ||||
{ | { | ||||
vm_page_lock(pp); | vm_page_lock(pp); | ||||
vm_page_unwire(pp, PQ_ACTIVE); | vm_page_unwire(pp, PQ_ACTIVE); | ||||
▲ Show 20 Lines • Show All 5,571 Lines • Show Last 20 Lines |