struct anon_vma *anon_vma = vma->anon_vma;
struct file *file = vma->vm_file;
bool remove_next = false;
+ struct vm_area_struct *anon_dup = NULL;
if (next && (vma != next) && (end == next->vm_end)) {
remove_next = true;
error = anon_vma_clone(vma, next);
if (error)
return error;
+
+ anon_dup = vma;
}
}
return 0;
nomem:
+ if (anon_dup)
+ unlink_anon_vmas(anon_dup);
+
return -ENOMEM;
}
int remove_next = 0;
MA_STATE(mas, &mm->mm_mt, 0, 0);
struct vm_area_struct *exporter = NULL, *importer = NULL;
+ struct vm_area_struct *anon_dup = NULL;
if (next && !insert) {
if (end >= next->vm_end) {
error = anon_vma_clone(importer, exporter);
if (error)
return error;
+
+ anon_dup = importer;
}
}
- if (mas_preallocate(&mas, vma, GFP_KERNEL))
+ if (mas_preallocate(&mas, vma, GFP_KERNEL)) {
+ if (anon_dup)
+ unlink_anon_vmas(anon_dup);
+
return -ENOMEM;
+ }
vma_adjust_trans_huge(orig_vma, start, end, adjust_next);
if (file) {