mm: abstract the vma_merge()/split_vma() pattern for mprotect() et al.
[linux-block.git] / mm / mempolicy.c
index 38a47fa33ef4f9cf1c03c27b18f28c0b4ecee3d4..8bb5b4b4b3955a975c7c2b29f7e6ea0babbea843 100644 (file)
@@ -811,10 +811,7 @@ static int mbind_range(struct vma_iterator *vmi, struct vm_area_struct *vma,
                struct vm_area_struct **prev, unsigned long start,
                unsigned long end, struct mempolicy *new_pol)
 {
-       struct vm_area_struct *merged;
        unsigned long vmstart, vmend;
-       pgoff_t pgoff;
-       int err;
 
        vmend = min(end, vma->vm_end);
        if (start > vma->vm_start) {
@@ -829,26 +826,9 @@ static int mbind_range(struct vma_iterator *vmi, struct vm_area_struct *vma,
                return 0;
        }
 
-       pgoff = vma->vm_pgoff + ((vmstart - vma->vm_start) >> PAGE_SHIFT);
-       merged = vma_merge(vmi, vma->vm_mm, *prev, vmstart, vmend, vma->vm_flags,
-                        vma->anon_vma, vma->vm_file, pgoff, new_pol,
-                        vma->vm_userfaultfd_ctx, anon_vma_name(vma));
-       if (merged) {
-               *prev = merged;
-               return vma_replace_policy(merged, new_pol);
-       }
-
-       if (vma->vm_start != vmstart) {
-               err = split_vma(vmi, vma, vmstart, 1);
-               if (err)
-                       return err;
-       }
-
-       if (vma->vm_end != vmend) {
-               err = split_vma(vmi, vma, vmend, 0);
-               if (err)
-                       return err;
-       }
+       vma =  vma_modify_policy(vmi, *prev, vma, vmstart, vmend, new_pol);
+       if (IS_ERR(vma))
+               return PTR_ERR(vma);
 
        *prev = vma;
        return vma_replace_policy(vma, new_pol);