struct mm_struct *mm = vma->vm_mm;
unsigned long old_start = vma->vm_start;
unsigned long old_end = vma->vm_end;
-// unsigned long old_pgoff = vma->vm_pgoff;
struct vm_area_struct *next = vma->vm_next;
struct address_space *mapping = NULL;
struct rb_root_cached *root = NULL;
vma_init(unmap, mm);
- if (end != old_end) { // shortening the start, unmap the end of vma.
- unmap->vm_start = end;
- unmap->vm_end = old_end;
- unmap->vm_next = vma->vm_next;
- unmap->vm_prev = vma;
- } else {
+ unmap->vm_pgoff = vma->vm_pgoff;
+ unmap->vm_flags = vma->vm_flags;
+ if (end == old_end) {
+ /* Changing the start of the VMA. */
unmap->vm_start = old_start;
unmap->vm_end = start;
unmap->vm_next = vma;
unmap->vm_prev = vma->vm_prev;
+ } else {
+ /* unmap will contain the end section of the VMA to be removed */
+ unmap->vm_start = end;
+ unmap->vm_end = old_end;
+ unmap->vm_next = vma->vm_next;
+ unmap->vm_prev = vma;
+ unmap->vm_pgoff += ((old_start - end) >> PAGE_SHIFT);
}
- vma_adjust_trans_huge(vma, vma->vm_start, end, 0);
+ vma_adjust_trans_huge(vma, start, end, 0);
if (file) {
mapping = file->f_mapping;
vma_interval_tree_remove(vma, root);
}
- if (end == old_end)
+ if (end == old_end) { // Altering the vm_start.
vma->vm_pgoff += (old_start - start) >> PAGE_SHIFT;
-
- vma->vm_end = end;
- vma->vm_start = start;
+ vma->vm_start = start;
+ } else {
+ vma->vm_end = end;
+ }
if (file) {
vma_interval_tree_insert(vma, root);
if (start > vma->vm_start) {
if (unlikely(vma->vm_end > end)) {
- // adjust the same vma twice requires a split.
+ /* Essentially, this means there is a hole punched in
+ * this VMA, so a split is unavoidable. */
int error;
/*
* Make sure that map_count on return from munmap() will