Index: vm_map.c =================================================================== --- vm_map.c +++ vm_map.c @@ -2453,6 +2453,7 @@ vm_map_entry_t current, entry, in_tran; vm_object_t obj; struct ucred *cred; + vm_ooffset_t to_reserve; vm_prot_t old_prot; if (start == end) @@ -2460,6 +2461,7 @@ again: in_tran = NULL; + to_reserve = 0; vm_map_lock(map); /* @@ -2472,9 +2474,7 @@ VM_MAP_RANGE_CHECK(map, start, end); - if (vm_map_lookup_entry(map, start, &entry)) { - vm_map_clip_start(map, entry, start); - } else { + if (!vm_map_lookup_entry(map, start, &entry)) { entry = entry->next; } @@ -2494,7 +2494,22 @@ } if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0) in_tran = entry; + if (set_max || + ((new_prot & ~(current->protection)) & VM_PROT_WRITE) == 0 || + ENTRY_CHARGED(current)) { + continue; + } + obj = current->object.vm_object; + if (obj == NULL ? (current->eflags & MAP_ENTRY_NEEDS_COPY) : + (obj->type == OBJT_DEFAULT || obj->type == OBJT_SWAP)) { + to_reserve += ulmin(end, current->end) - + ulmax(start, current->start); + } } + if (!swap_reserve(to_reserve)) { + vm_map_unlock(map); + return (KERN_RESOURCE_SHORTAGE); + } /* * Postpone the operation until all in transition map entries @@ -2515,6 +2530,8 @@ * now will do cow due to allowed write (e.g. debugger sets * breakpoint on text segment) */ + if (entry->start < start) + vm_map_clip_start(map, entry, start); for (current = entry; current->start < end; current = current->next) { vm_map_clip_end(map, current, end); @@ -2530,10 +2547,6 @@ obj = current->object.vm_object; if (obj == NULL || (current->eflags & MAP_ENTRY_NEEDS_COPY)) { - if (!swap_reserve(current->end - current->start)) { - vm_map_unlock(map); - return (KERN_RESOURCE_SHORTAGE); - } crhold(cred); current->cred = cred; continue; @@ -2553,12 +2566,6 @@ KASSERT(obj->charge == 0, ("vm_map_protect: object %p overcharged (entry %p)", obj, current)); - if (!swap_reserve(ptoa(obj->size))) { - VM_OBJECT_WUNLOCK(obj); - vm_map_unlock(map); - return (KERN_RESOURCE_SHORTAGE); - } - crhold(cred); obj->cred = cred; obj->charge = ptoa(obj->size);