validate_mm(mm);
}
-/*
- * Helper for vma_adjust() in the split_vma insert case: insert a vma into the
- * mm's list and the mm tree. It has already been inserted into the interval tree.
- */
-static void __insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
-{
- vma_store(mm, vma);
- mm->map_count++;
-}
-
/*
* vma_expand - Expand an existing VMA
*
bool vma_changed = false;
long adjust_next = 0;
int remove_next = 0;
+ MA_STATE(mas, &mm->mm_mt, 0, 0);
+ struct vm_area_struct *exporter = NULL, *importer = NULL;
if (next && !insert) {
- struct vm_area_struct *exporter = NULL, *importer = NULL;
if (end >= next->vm_end) {
/*
again:
vma_adjust_trans_huge(orig_vma, start, end, adjust_next);
+ if (mas_preallocate(&mas, vma, GFP_KERNEL)) {
+ if (exporter && exporter->anon_vma)
+ unlink_anon_vmas(importer);
+ return -ENOMEM;
+ }
+
if (file) {
mapping = file->f_mapping;
root = &mapping->i_mmap;
}
if (vma_changed)
- vma_store(mm, vma);
+ vma_mas_store(vma, &mas);
vma->vm_pgoff = pgoff;
if (adjust_next) {
next->vm_start += adjust_next;
next->vm_pgoff += adjust_next >> PAGE_SHIFT;
- vma_store(mm, next);
+ vma_mas_store(next, &mas);
}
if (file) {
* us to insert it before dropping the locks
* (it may either follow vma or precede it).
*/
- __insert_vm_struct(mm, insert);
+ mas_reset(&mas);
+ vma_mas_store(insert, &mas);
+ mm->map_count++;
}
if (anon_vma) {
anon_vma_merge(vma, next);
mm->map_count--;
mpol_put(vma_policy(next));
+ BUG_ON(vma->vm_end < next->vm_end);
vm_area_free(next);
+
/*
* In mprotect's case 6 (see comments on vma_merge),
* we must remove another next too. It would clutter
next = vma;
}
if (remove_next == 2) {
- vma_changed = false;
+ mas_reset(&mas);
remove_next = 1;
end = next->vm_end;
goto again;