diff options
author | dg <dg@FreeBSD.org> | 1995-02-22 08:40:54 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-02-22 08:40:54 +0000 |
commit | a40bad2c2dece3e17c30cc2004d9caa97b8dab74 (patch) | |
tree | aff77c49ef3f13b6bc0dcdc52b4db351019f45bb /sys | |
parent | a1c965a8b5f832d0561113fcaaca20981b1b6376 (diff) | |
download | FreeBSD-src-a40bad2c2dece3e17c30cc2004d9caa97b8dab74.zip FreeBSD-src-a40bad2c2dece3e17c30cc2004d9caa97b8dab74.tar.gz |
Rewrote MAP_PRIVATE case of vm_mmap() - all of the COW portion of this
routine was highly convoluted.
Submitted by: John Dyson
Diffstat (limited to 'sys')
-rw-r--r-- | sys/vm/vm_mmap.c | 107 |
1 files changed, 53 insertions, 54 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index bcc9a21..990caff 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -38,7 +38,7 @@ * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$ * * @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94 - * $Id: vm_mmap.c,v 1.9 1995/02/15 09:22:17 davidg Exp $ + * $Id: vm_mmap.c,v 1.10 1995/02/21 01:22:46 davidg Exp $ */ /* @@ -678,70 +678,69 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff) } } /* - * A COW regular file + * mmap a COW regular file */ else { vm_map_t tmap; vm_offset_t off; + vm_map_entry_t entry; - /* locate and allocate the target address space */ - rv = vm_map_find(map, NULL, 0, addr, size, fitit); - if (rv != KERN_SUCCESS) { - vm_object_deallocate(object); - goto out; - } - - off = VM_MIN_ADDRESS; - tmap = vm_map_create(NULL, off, off + size, TRUE); - rv = vm_map_find(tmap, object, foff, &off, size, FALSE); - if (rv != KERN_SUCCESS) { - vm_object_deallocate(object); + if (flags & MAP_COPY) { + /* locate and allocate the target address space */ + rv = vm_map_find(map, NULL, 0, addr, size, fitit); + if (rv != KERN_SUCCESS) { + vm_object_deallocate(object); + goto out; + } + + off = VM_MIN_ADDRESS; + tmap = vm_map_create(NULL, off, off + size, TRUE); + rv = vm_map_find(tmap, object, foff, &off, size, FALSE); + if (rv != KERN_SUCCESS) { + vm_object_deallocate(object); + vm_map_deallocate(tmap); + goto out; + } + + rv = vm_map_copy(map, tmap, *addr, size, off, + FALSE, FALSE); vm_map_deallocate(tmap); - goto out; - } + if (rv != KERN_SUCCESS) + goto out; - /* - * (XXX) MAP_PRIVATE implies that we see changes made - * by others. To ensure that we need to guarentee - * that no copy object is created (otherwise original - * pages would be pushed to the copy object and we - * would never see changes made by others). We - * totally sleeze it right now by marking the object - * internal temporarily. - */ - if ((flags & MAP_COPY) == 0) - object->flags |= OBJ_INTERNAL; - rv = vm_map_copy(map, tmap, *addr, size, off, - FALSE, FALSE); - object->flags &= ~OBJ_INTERNAL; - /* - * (XXX) My oh my, this only gets worse... Force - * creation of a shadow object so that vm_map_fork - * will do the right thing. - */ - if ((flags & MAP_COPY) == 0) { - vm_map_t tmap; - vm_map_entry_t tentry; - vm_object_t tobject; - vm_offset_t toffset; - vm_prot_t tprot; - boolean_t twired, tsu; - - tmap = map; - vm_map_lookup(&tmap, *addr, VM_PROT_WRITE, - &tentry, &tobject, &toffset, - &tprot, &twired, &tsu); - vm_map_lookup_done(tmap, tentry); + } else { + vm_object_t user_object; + + user_object = vm_object_allocate( size); + user_object->shadow = object; + TAILQ_INSERT_TAIL(&object->reverse_shadow_head, + user_object, reverse_shadow_list); + + object->ref_count += 1; + + rv = vm_map_find(map, user_object, foff, addr, size, fitit); + if( rv != KERN_SUCCESS) { + vm_object_deallocate(user_object); + vm_object_deallocate(object); + goto out; + } + + /* + * this is a consistancy check, gets the map entry, and should + * never fail + */ + if (!vm_map_lookup_entry(map, *addr, &entry)) { + panic("vm_mmap: missing map entry!!!\n"); + } + + entry->copy_on_write = TRUE; } + /* - * (XXX) Map copy code cannot detect sharing unless a - * sharing map is involved. So we cheat and write - * protect everything ourselves. + * set pages COW and protect for read access only */ vm_object_pmap_copy(object, foff, foff + size); - vm_map_deallocate(tmap); - if (rv != KERN_SUCCESS) - goto out; + } /* |