X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/9eed27f6f2f002145667fb4abfc5e476b53630e5..7b8a1bcad75628f9add4590db2bb9b8e418ee8eb:/lunaix-os/kernel/mm/mmap.c diff --git a/lunaix-os/kernel/mm/mmap.c b/lunaix-os/kernel/mm/mmap.c index afb4246..fa71016 100644 --- 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->flen = param->flen; 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 -__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; @@ -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; + + // 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; - region->flen = MAX(region->flen, f_shifted) - f_shifted; } 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; - } 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; @@ -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; - vmr->flen = MAX(vmr->flen, displ) - displ; } *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); - __unmap_overlapped_cases(pos, &cur_addr, &length); + __unmap_overlapped_cases(mnt, pos, &cur_addr, &length); pos = n; }