-
-kern_return_t
-vm_conflict_check(
- vm_map_t map,
- vm_map_offset_t off,
- vm_map_size_t len,
- memory_object_t pager,
- vm_object_offset_t file_off)
-{
- vm_map_entry_t entry;
- vm_object_t obj;
- vm_object_offset_t obj_off;
- vm_map_t base_map;
- vm_map_offset_t base_offset;
- vm_map_offset_t original_offset;
- kern_return_t kr;
- vm_map_size_t local_len;
-
- base_map = map;
- base_offset = off;
- original_offset = off;
- kr = KERN_SUCCESS;
- vm_map_lock(map);
- while(vm_map_lookup_entry(map, off, &entry)) {
- local_len = len;
-
- if (VME_OBJECT(entry) == VM_OBJECT_NULL) {
- vm_map_unlock(map);
- return KERN_SUCCESS;
- }
- if (entry->is_sub_map) {
- vm_map_t old_map;
-
- old_map = map;
- vm_map_lock(VME_SUBMAP(entry));
- map = VME_SUBMAP(entry);
- off = VME_OFFSET(entry) + (off - entry->vme_start);
- vm_map_unlock(old_map);
- continue;
- }
- obj = VME_OBJECT(entry);
- obj_off = (off - entry->vme_start) + VME_OFFSET(entry);
- while(obj->shadow) {
- obj_off += obj->vo_shadow_offset;
- obj = obj->shadow;
- }
- if((obj->pager_created) && (obj->pager == pager)) {
- if(((obj->paging_offset) + obj_off) == file_off) {
- if(off != base_offset) {
- vm_map_unlock(map);
- return KERN_FAILURE;
- }
- kr = KERN_ALREADY_WAITING;
- } else {
- vm_object_offset_t obj_off_aligned;
- vm_object_offset_t file_off_aligned;
-
- obj_off_aligned = obj_off & ~PAGE_MASK;
- file_off_aligned = file_off & ~PAGE_MASK;
-
- if (file_off_aligned == (obj->paging_offset + obj_off_aligned)) {
- /*
- * the target map and the file offset start in the same page
- * but are not identical...
- */
- vm_map_unlock(map);
- return KERN_FAILURE;
- }
- if ((file_off < (obj->paging_offset + obj_off_aligned)) &&
- ((file_off + len) > (obj->paging_offset + obj_off_aligned))) {
- /*
- * some portion of the tail of the I/O will fall
- * within the encompass of the target map
- */
- vm_map_unlock(map);
- return KERN_FAILURE;
- }
- if ((file_off_aligned > (obj->paging_offset + obj_off)) &&
- (file_off_aligned < (obj->paging_offset + obj_off) + len)) {
- /*
- * the beginning page of the file offset falls within
- * the target map's encompass
- */
- vm_map_unlock(map);
- return KERN_FAILURE;
- }
- }
- } else if(kr != KERN_SUCCESS) {
- vm_map_unlock(map);
- return KERN_FAILURE;
- }
-
- if(len <= ((entry->vme_end - entry->vme_start) -
- (off - entry->vme_start))) {
- vm_map_unlock(map);
- return kr;
- } else {
- len -= (entry->vme_end - entry->vme_start) -
- (off - entry->vme_start);
- }
- base_offset = base_offset + (local_len - len);
- file_off = file_off + (local_len - len);
- off = base_offset;
- if(map != base_map) {
- vm_map_unlock(map);
- vm_map_lock(base_map);
- map = base_map;
- }
- }
-
- vm_map_unlock(map);
- return kr;
-}
-