MCPcopy Create free account
hub / github.com/F-Stack/f-stack / vnode_pager_setsize

Function vnode_pager_setsize

freebsd/vm/vnode_pager.c:432–529  ·  view source on GitHub ↗

* 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 * the associated object that are affected by the size change. * * Note: this routine may be invoked as a result of a pager put * operation (possibly at object termination time), so we must be careful. */

Source from the content-addressed store, hash-verified

430 * operation (possibly at object termination time), so we must be careful.
431 */
432void
433vnode_pager_setsize(struct vnode *vp, vm_ooffset_t nsize)
434{
435 vm_object_t object;
436 vm_page_t m;
437 vm_pindex_t nobjsize;
438
439 if ((object = vp->v_object) == NULL)
440 return;
441#ifdef DEBUG_VFS_LOCKS
442 {
443 struct mount *mp;
444
445 mp = vp->v_mount;
446 if (mp != NULL && (mp->mnt_kern_flag & MNTK_VMSETSIZE_BUG) == 0)
447 assert_vop_elocked(vp,
448 "vnode_pager_setsize and not locked vnode");
449 }
450#endif
451 VM_OBJECT_WLOCK(object);
452 if (object->type == OBJT_DEAD) {
453 VM_OBJECT_WUNLOCK(object);
454 return;
455 }
456 KASSERT(object->type == OBJT_VNODE,
457 ("not vnode-backed object %p", object));
458 if (nsize == object->un_pager.vnp.vnp_size) {
459 /*
460 * Hasn't changed size
461 */
462 VM_OBJECT_WUNLOCK(object);
463 return;
464 }
465 nobjsize = OFF_TO_IDX(nsize + PAGE_MASK);
466 if (nsize < object->un_pager.vnp.vnp_size) {
467 /*
468 * File has shrunk. Toss any cached pages beyond the new EOF.
469 */
470 if (nobjsize < object->size)
471 vm_object_page_remove(object, nobjsize, object->size,
472 0);
473 /*
474 * this gets rid of garbage at the end of a page that is now
475 * only partially backed by the vnode.
476 *
477 * XXX for some reason (I don't know yet), if we take a
478 * completely invalid page and mark it partially valid
479 * it can screw up NFS reads, so we don't allow the case.
480 */
481 if (!(nsize & PAGE_MASK))
482 goto out;
483 m = vm_page_grab(object, OFF_TO_IDX(nsize), VM_ALLOC_NOCREAT);
484 if (m == NULL)
485 goto out;
486 if (!vm_page_none_valid(m)) {
487 int base = (int)nsize & PAGE_MASK;
488 int size = PAGE_SIZE - base;
489

Callers 6

zfs_rezgetFunction · 0.85
zfs_extendFunction · 0.85
zfs_free_rangeFunction · 0.85
zfs_truncFunction · 0.85
zfs_inode_updateFunction · 0.85
vtruncbufFunction · 0.85

Calls 8

assert_vop_elockedFunction · 0.85
vm_object_page_removeFunction · 0.85
vm_page_grabFunction · 0.85
vm_page_none_validFunction · 0.85
vm_page_set_valid_rangeFunction · 0.85
vm_page_clear_dirtyFunction · 0.85
atomic_store_64Function · 0.85
pmap_zero_page_areaFunction · 0.50

Tested by

no test coverage detected