struct vm_map *map; int error, rv, flags, uvmflags;
vm_map_t map; int rv, flags, uvmflags;
sys_msync(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	struct sys_msync_args /* {		syscallarg(caddr_t) addr;		syscallarg(size_t) len;		syscallarg(int) flags;	} */ *uap = v;	vaddr_t addr;	vsize_t size, pageoff;	struct vm_map *map;	int error, rv, flags, uvmflags;	/*	 * extract syscall args from the uap	 */	addr = (vaddr_t)SCARG(uap, addr);	size = (vsize_t)SCARG(uap, len);	flags = SCARG(uap, flags);	/* sanity check flags */	if ((flags & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE)) != 0 ||			(flags & (MS_ASYNC | MS_SYNC | MS_INVALIDATE)) == 0 ||			(flags & (MS_ASYNC | MS_SYNC)) == (MS_ASYNC | MS_SYNC))	  return (EINVAL);	if ((flags & (MS_ASYNC | MS_SYNC)) == 0)	  flags |= MS_SYNC;	/*	 * align the address to a page boundary and adjust the size accordingly.	 */	pageoff = (addr & PAGE_MASK);	addr -= pageoff;	size += pageoff;	size = (vsize_t)round_page(size);	/* disallow wrap-around. */	if (addr + size < addr)		return (EINVAL);	/*	 * get map	 */	map = &p->p_vmspace->vm_map;	/*	 * XXXCDC: do we really need this semantic?	 *	 * XXX Gak!  If size is zero we are supposed to sync "all modified	 * pages with the region containing addr".  Unfortunately, we	 * don't really keep track of individual mmaps so we approximate	 * by flushing the range of the map entry containing addr.	 * This can be incorrect if the region splits or is coalesced	 * with a neighbor.	 */	if (size == 0) {		struct vm_map_entry *entry;		vm_map_lock_read(map);		rv = uvm_map_lookup_entry(map, addr, &entry);		if (rv == TRUE) {			addr = entry->start;			size = entry->end - entry->start;		}		vm_map_unlock_read(map);		if (rv == FALSE)			return (EINVAL);	}	/*	 * translate MS_ flags into PGO_ flags	 */	uvmflags = PGO_CLEANIT;	if (flags & MS_INVALIDATE)		uvmflags |= PGO_FREE;	if (flags & MS_SYNC)		uvmflags |= PGO_SYNCIO;	else		uvmflags |= PGO_SYNCIO;	 /* XXXCDC: force sync for now! */	error = uvm_map_clean(map, addr, addr+size, uvmflags);	return error;}