git://scm.lunaixsky.com
/
lunaix-os.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
feat: nearly complete POSIX.1-2008 compliant terminal interface implementation
[lunaix-os.git]
/
lunaix-os
/
kernel
/
mm
/
mmap.c
diff --git
a/lunaix-os/kernel/mm/mmap.c
b/lunaix-os/kernel/mm/mmap.c
index afb4246b67a77061f059d29c4316ff05df0c83ac..fa71016adc828e4792e47c5bf69796bb6f5a10cd 100644
(file)
--- a/
lunaix-os/kernel/mm/mmap.c
+++ b/
lunaix-os/kernel/mm/mmap.c
@@
-114,7
+114,6
@@
found:
region->mfile = file;
region->foff = param->offset;
region->mfile = file;
region->foff = param->offset;
- region->flen = param->flen;
region->proc_vms = param->pvms;
region_add(vm_regions, region);
region->proc_vms = param->pvms;
region_add(vm_regions, region);
@@
-255,7
+254,10
@@
mem_unmap_region(ptr_t mnt, struct mm_region* region)
((vmr)->start > (addr) && ((addr) + (len)) > (vmr)->end)
static void
((vmr)->start > (addr) && ((addr) + (len)) > (vmr)->end)
static void
-__unmap_overlapped_cases(struct mm_region* vmr, ptr_t* addr, size_t* length)
+__unmap_overlapped_cases(ptr_t mnt,
+ struct mm_region* vmr,
+ ptr_t* addr,
+ size_t* length)
{
// seg start, umapped segement start
ptr_t seg_start = *addr, umps_start = 0;
{
// seg start, umapped segement start
ptr_t seg_start = *addr, umps_start = 0;
@@
-267,12
+269,13
@@
__unmap_overlapped_cases(struct mm_region* vmr, ptr_t* addr, size_t* length)
if (CASE_HITI(vmr, seg_start, seg_len)) {
size_t new_start = seg_start + seg_len;
if (CASE_HITI(vmr, seg_start, seg_len)) {
size_t new_start = seg_start + seg_len;
+
+ // Require a split
if (new_start < vmr->end) {
struct mm_region* region = region_dup(vmr);
if (region->mfile) {
size_t f_shifted = new_start - region->start;
region->foff += f_shifted;
if (new_start < vmr->end) {
struct mm_region* region = region_dup(vmr);
if (region->mfile) {
size_t f_shifted = new_start - region->start;
region->foff += f_shifted;
- region->flen = MAX(region->flen, f_shifted) - f_shifted;
}
region->start = new_start;
llist_insert_after(&vmr->head, ®ion->head);
}
region->start = new_start;
llist_insert_after(&vmr->head, ®ion->head);
@@
-293,8
+296,14
@@
__unmap_overlapped_cases(struct mm_region* vmr, ptr_t* addr, size_t* length)
shrink = vmr->end - vmr->start;
umps_len = shrink;
umps_start = vmr->start;
shrink = vmr->end - vmr->start;
umps_len = shrink;
umps_start = vmr->start;
- } else {
- fail("invalid case");
+ }
+
+ mem_sync_pages(mnt, vmr, vmr->start, umps_len, 0);
+ for (size_t i = 0; i < umps_len; i += PG_SIZE) {
+ ptr_t pa = vmm_del_mapping(mnt, vmr->start + i);
+ if (pa) {
+ pmm_free_page(vmr->proc_vms->pid, pa);
+ }
}
vmr->start += displ;
}
vmr->start += displ;
@@
-305,7
+314,6
@@
__unmap_overlapped_cases(struct mm_region* vmr, ptr_t* addr, size_t* length)
region_release(vmr);
} else if (vmr->mfile) {
vmr->foff += displ;
region_release(vmr);
} else if (vmr->mfile) {
vmr->foff += displ;
- vmr->flen = MAX(vmr->flen, displ) - displ;
}
*addr = umps_start + umps_len;
}
*addr = umps_start + umps_len;
@@
-331,7
+339,7
@@
mem_unmap(ptr_t mnt, vm_regions_t* regions, ptr_t addr, size_t length)
while (&pos->head != regions && length) {
n = container_of(pos->head.next, typeof(*pos), head);
while (&pos->head != regions && length) {
n = container_of(pos->head.next, typeof(*pos), head);
- __unmap_overlapped_cases(pos, &cur_addr, &length);
+ __unmap_overlapped_cases(
mnt,
pos, &cur_addr, &length);
pos = n;
}
pos = n;
}