}
mas_set_range(&mas, addr, end - 1);
- if (vm_flags & VM_SPECIAL) {
- ma_prev = mas;
- prev = mas_prev(&ma_prev, 0);
+ mas_walk(&mas); // Walk to the empty area (munmapped above)
+ ma_prev = mas;
+ prev = mas_prev(&ma_prev, 0);
+
+ if (vm_flags & VM_SPECIAL)
goto cannot_expand;
- }
/* Attempt to expand an old mapping */
merge_end = next->vm_end;
vma = next;
vm_pgoff = next->vm_pgoff - pglen;
- tmp = mas;
}
}
/* Check prev */
- ma_prev = tmp;
- prev = mas_prev(&ma_prev, 0);
if (prev && prev->vm_end == addr && !vma_policy(prev) &&
can_vma_merge_after(prev, vm_flags, NULL, file, pgoff,
NULL_VM_UFFD_CTX)) {
/* Try to expand the prev over the requested area */
merge_start = prev->vm_start;
vma = prev;
- tmp = ma_prev;
+ mas = ma_prev;
vm_pgoff = prev->vm_pgoff;
}
/* Actually expand, if possible */
if (vma &&
- !vma_expand(&tmp, vma, merge_start, merge_end, vm_pgoff, next)) {
+ !vma_expand(&mas, vma, merge_start, merge_end, vm_pgoff, next)) {
khugepaged_enter_vma_merge(vma, vm_flags);
goto expanded;
}
* f_op->mmap method. -DaveM
*/
WARN_ON_ONCE(addr != vma->vm_start);
+ if (addr != vma->vm_start) {
+ addr = vma->vm_start;
+ mas_set_range(&mas, addr, end - 1);
+ }
- addr = vma->vm_start;
/* If vm_flags changed after call_mmap(), we should try merge vma again
* as we may succeed this time.
goto free_vma;
}
- // addr may have changed.
- mas_set_range(&mas, addr, end - 1);
vma_mas_link(mm, vma, &mas);
/* Once vma denies write, undo our temporary denial count */