Changeset View
Changeset View
Standalone View
Standalone View
vm/vnode_pager.c
Show First 20 Lines • Show All 424 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Lets the VM system know about a change in size for a file. | * Lets the VM system know about a change in size for a file. | ||||
* We adjust our own internal size and flush any cached pages in | * We adjust our own internal size and flush any cached pages in | ||||
* the associated object that are affected by the size change. | * the associated object that are affected by the size change. | ||||
* | * | ||||
* Note: this routine may be invoked as a result of a pager put | * Note: this routine may be invoked as a result of a pager put | ||||
* operation (possibly at object termination time), so we must be careful. | * operation (possibly at object termination time), so we must be careful. | ||||
* If can_sleep == false, this function can be called while a mutex or rw | |||||
* lock is held. In this case, EWOULDBLOCK will be returned if the operation | |||||
* cannot be completed. | |||||
* Otherwise, a return of 0 indicates success. | |||||
*/ | */ | ||||
void | int | ||||
vnode_pager_setsize(struct vnode *vp, vm_ooffset_t nsize) | vnode_pager_setsize_mightsleep(struct vnode *vp, vm_ooffset_t nsize, | ||||
bool can_sleep) | |||||
{ | { | ||||
vm_object_t object; | vm_object_t object; | ||||
vm_page_t m; | vm_page_t m; | ||||
vm_pindex_t nobjsize; | vm_pindex_t nobjsize; | ||||
if ((object = vp->v_object) == NULL) | if ((object = vp->v_object) == NULL) | ||||
return; | return (0); | ||||
/* ASSERT_VOP_ELOCKED(vp, "vnode_pager_setsize and not locked vnode"); */ | /* ASSERT_VOP_ELOCKED(vp, "vnode_pager_setsize and not locked vnode"); */ | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
if (object->type == OBJT_DEAD) { | if (object->type == OBJT_DEAD) { | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return; | return (0); | ||||
} | } | ||||
KASSERT(object->type == OBJT_VNODE, | KASSERT(object->type == OBJT_VNODE, | ||||
("not vnode-backed object %p", object)); | ("not vnode-backed object %p", object)); | ||||
if (nsize == object->un_pager.vnp.vnp_size) { | if (nsize == object->un_pager.vnp.vnp_size) { | ||||
/* | /* | ||||
* Hasn't changed size | * Hasn't changed size | ||||
*/ | */ | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return; | return (0); | ||||
} | } | ||||
nobjsize = OFF_TO_IDX(nsize + PAGE_MASK); | nobjsize = OFF_TO_IDX(nsize + PAGE_MASK); | ||||
if (nsize < object->un_pager.vnp.vnp_size) { | if (nsize < object->un_pager.vnp.vnp_size) { | ||||
/* If can_sleep == false, return EWOULDBLOCK. */ | |||||
if (!can_sleep) { | |||||
VM_OBJECT_WUNLOCK(object); | |||||
return (EWOULDBLOCK); | |||||
} | |||||
/* | /* | ||||
* File has shrunk. Toss any cached pages beyond the new EOF. | * File has shrunk. Toss any cached pages beyond the new EOF. | ||||
*/ | */ | ||||
if (nobjsize < object->size) | if (nobjsize < object->size) | ||||
vm_object_page_remove(object, nobjsize, object->size, | vm_object_page_remove(object, nobjsize, object->size, | ||||
0); | 0); | ||||
/* | /* | ||||
* this gets rid of garbage at the end of a page that is now | * this gets rid of garbage at the end of a page that is now | ||||
Show All 37 Lines | if ((nsize & PAGE_MASK) && | ||||
* replacement from working properly. | * replacement from working properly. | ||||
*/ | */ | ||||
vm_page_clear_dirty(m, base, PAGE_SIZE - base); | vm_page_clear_dirty(m, base, PAGE_SIZE - base); | ||||
} | } | ||||
} | } | ||||
object->un_pager.vnp.vnp_size = nsize; | object->un_pager.vnp.vnp_size = nsize; | ||||
object->size = nobjsize; | object->size = nobjsize; | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return (0); | |||||
} | } | ||||
/* | /* | ||||
* calculate the linear (byte) disk address of specified virtual | * calculate the linear (byte) disk address of specified virtual | ||||
* file address | * file address | ||||
*/ | */ | ||||
static int | static int | ||||
vnode_pager_addr(struct vnode *vp, vm_ooffset_t address, daddr_t *rtaddress, | vnode_pager_addr(struct vnode *vp, vm_ooffset_t address, daddr_t *rtaddress, | ||||
▲ Show 20 Lines • Show All 1,066 Lines • Show Last 20 Lines |