FALSE, TRUE);
FALSE, UVM_LK_ENTER);
uvm_mmap(map, addr, size, prot, maxprot, flags, handle, foff, locklimit)	vm_map_t map;	vaddr_t *addr;	vsize_t size;	vm_prot_t prot, maxprot;	int flags;	caddr_t handle;		/* XXX: VNODE? */	vaddr_t foff;	vsize_t locklimit;{	struct uvm_object *uobj;	struct vnode *vp;	int retval;	int advice = UVM_ADV_NORMAL;	uvm_flag_t uvmflag = 0;	/*	 * check params	 */	if (size == 0)		return(0);	if (foff & PAGE_MASK)		return(EINVAL);	if ((prot & maxprot) != prot)		return(EINVAL);	/*	 * for non-fixed mappings, round off the suggested address.	 * for fixed mappings, check alignment and zap old mappings.	 */	if ((flags & MAP_FIXED) == 0) {		*addr = round_page(*addr);	/* round */	} else {				if (*addr & PAGE_MASK)			return(EINVAL);		uvmflag |= UVM_FLAG_FIXED;		(void) uvm_unmap(map, *addr, *addr + size);	/* zap! */	}	/*	 * handle anon vs. non-anon mappings.   for non-anon mappings attach	 * to underlying vm object.	 */	if (flags & MAP_ANON) {		foff = UVM_UNKNOWN_OFFSET;		uobj = NULL;		if ((flags & MAP_SHARED) == 0)			/* XXX: defer amap create */			uvmflag |= UVM_FLAG_COPYONW;		else			/* shared: create amap now */			uvmflag |= UVM_FLAG_OVERLAY;	} else {		vp = (struct vnode *) handle;	/* get vnode */		if (vp->v_type != VCHR) {			uobj = uvn_attach((void *) vp, (flags & MAP_SHARED) ?			   maxprot : (maxprot & ~VM_PROT_WRITE));			/*			 * XXXCDC: hack from old code			 * don't allow vnodes which have been mapped			 * shared-writeable to persist [forces them to be			 * flushed out when last reference goes].			 * XXXCDC: interesting side effect: avoids a bug.			 * note that in WRITE [ufs_readwrite.c] that we			 * allocate buffer, uncache, and then do the write.			 * the problem with this is that if the uncache causes			 * VM data to be flushed to the same area of the file			 * we are writing to... in that case we've got the			 * buffer locked and our process goes to sleep forever.			 *			 * XXXCDC: checking maxprot protects us from the			 * "persistbug" program but this is not a long term			 * solution.			 * 			 * XXXCDC: we don't bother calling uncache with the vp			 * VOP_LOCKed since we know that we are already			 * holding a valid reference to the uvn (from the			 * uvn_attach above), and thus it is impossible for			 * the uncache to kill the uvn and trigger I/O.			 */			if (flags & MAP_SHARED) {				if ((prot & VM_PROT_WRITE) ||				    (maxprot & VM_PROT_WRITE)) {					uvm_vnp_uncache(vp);				}			}		} else {			uobj = udv_attach((void *) &vp->v_rdev,			    (flags & MAP_SHARED) ?			    maxprot : (maxprot & ~VM_PROT_WRITE), foff, size);			advice = UVM_ADV_RANDOM;		}				if (uobj == NULL)			return((vp->v_type == VREG) ? ENOMEM : EINVAL);		if ((flags & MAP_SHARED) == 0)			uvmflag |= UVM_FLAG_COPYONW;	}	/*	 * set up mapping flags	 */	uvmflag = UVM_MAPFLAG(prot, maxprot, 			(flags & MAP_SHARED) ? UVM_INH_SHARE : UVM_INH_COPY,			advice, uvmflag);	/*	 * do it!	 */	retval = uvm_map(map, addr, size, uobj, foff, uvmflag);	if (retval == KERN_SUCCESS) {		/*		 * POSIX 1003.1b -- if our address space was configured		 * to lock all future mappings, wire the one we just made.		 */		if (prot == VM_PROT_NONE) {			/*			 * No more work to do in this case.			 */			return (0);		}				vm_map_lock(map);		if (map->flags & VM_MAP_WIREFUTURE) {			/*			 * uvm_map_pageable() always returns the map			 * unlocked.			 */			if ((atop(size) + uvmexp.wired) > uvmexp.wiredmax#ifdef pmap_wired_count			    || (locklimit != 0 && (size +			         ptoa(pmap_wired_count(vm_map_pmap(map)))) >			        locklimit)#endif			) {				retval = KERN_RESOURCE_SHORTAGE;				/* unmap the region! */				(void) uvm_unmap(map, *addr, *addr + size);				goto bad;			}			retval = uvm_map_pageable(map, *addr, *addr + size,			    FALSE, TRUE);			if (retval != KERN_SUCCESS) {				/* unmap the region! */				(void) uvm_unmap(map, *addr, *addr + size);				goto bad;			}			return (0);		}		vm_map_unlock(map);		return (0);	}	/*	 * errors: first detach from the uobj, if any.	 */		if (uobj)		uobj->pgops->pgo_detach(uobj); bad:	switch (retval) {	case KERN_INVALID_ADDRESS:	case KERN_NO_SPACE:		return(ENOMEM);	case KERN_RESOURCE_SHORTAGE:		return (EAGAIN);	case KERN_PROTECTION_FAILURE:		return(EACCES);	}	return(EINVAL);}