mm: abstract the vma_merge()/split_vma() pattern for mprotect() et al.
[linux-2.6-block.git] / mm / mprotect.c
index 03e2cec3e66924e7d812cbf9c63a9eee8e59ad16..f1dc8f8c84ef3fe3906ef36e1ee842d0d6b4311b 100644 (file)
@@ -581,7 +581,6 @@ mprotect_fixup(struct vma_iterator *vmi, struct mmu_gather *tlb,
        long nrpages = (end - start) >> PAGE_SHIFT;
        unsigned int mm_cp_flags = 0;
        unsigned long charged = 0;
-       pgoff_t pgoff;
        int error;
 
        if (newflags == oldflags) {
@@ -631,34 +630,14 @@ mprotect_fixup(struct vma_iterator *vmi, struct mmu_gather *tlb,
                newflags &= ~VM_ACCOUNT;
        }
 
-       /*
-        * First try to merge with previous and/or next vma.
-        */
-       pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
-       *pprev = vma_merge(vmi, mm, *pprev, start, end, newflags,
-                          vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
-                          vma->vm_userfaultfd_ctx, anon_vma_name(vma));
-       if (*pprev) {
-               vma = *pprev;
-               VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY);
-               goto success;
+       vma = vma_modify_flags(vmi, *pprev, vma, start, end, newflags);
+       if (IS_ERR(vma)) {
+               error = PTR_ERR(vma);
+               goto fail;
        }
 
        *pprev = vma;
 
-       if (start != vma->vm_start) {
-               error = split_vma(vmi, vma, start, 1);
-               if (error)
-                       goto fail;
-       }
-
-       if (end != vma->vm_end) {
-               error = split_vma(vmi, vma, end, 0);
-               if (error)
-                       goto fail;
-       }
-
-success:
        /*
         * vm_flags and vm_page_prot are protected by the mmap_lock
         * held in write mode.