struct anon_vma *anon_vma = vma->anon_vma;
struct file *file = vma->vm_file;
bool remove_next = false;
+ bool anon_cloned = false;
if (next && (vma != next) && (end == next->vm_end)) {
remove_next = true;
error = anon_vma_clone(vma, next);
if (error)
return error;
+ anon_cloned = true;
}
}
/* Only handles expanding */
VM_BUG_ON(vma->vm_start < start || vma->vm_end > end);
+ if (mas_preallocate(mas, vma, GFP_KERNEL))
+ goto nomem;
+
vma_adjust_trans_huge(vma, start, end, 0);
if (file) {
validate_mm(mm);
return 0;
+
+nomem:
+ if (anon_cloned)
+ unlink_anon_vmas(vma);
+ return -ENOMEM;
}
/*