shmem: prepare huge= mount option and sysfs knob
[linux-2.6-block.git] / mm / mmap.c
index de2c1769cc68d6de4744307ee45201a2f2c35cc4..a41872c8f2af09994e6728cc7d282984e7851bea 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -675,6 +675,8 @@ again:                      remove_next = 1 + (end > next->vm_end);
                }
        }
 
+       vma_adjust_trans_huge(vma, start, end, adjust_next);
+
        if (file) {
                mapping = file->f_mapping;
                root = &mapping->i_mmap;
@@ -695,8 +697,6 @@ again:                      remove_next = 1 + (end > next->vm_end);
                }
        }
 
-       vma_adjust_trans_huge(vma, start, end, adjust_next);
-
        anon_vma = vma->anon_vma;
        if (!anon_vma && adjust_next)
                anon_vma = next->anon_vma;
@@ -2591,6 +2591,12 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
                /* drop PG_Mlocked flag for over-mapped range */
                for (tmp = vma; tmp->vm_start >= start + size;
                                tmp = tmp->vm_next) {
+                       /*
+                        * Split pmd and munlock page on the border
+                        * of the range.
+                        */
+                       vma_adjust_trans_huge(tmp, start, start + size, 0);
+
                        munlock_vma_pages_range(tmp,
                                        max(tmp->vm_start, start),
                                        min(tmp->vm_end, start + size));
@@ -2943,9 +2949,19 @@ static const char *special_mapping_name(struct vm_area_struct *vma)
        return ((struct vm_special_mapping *)vma->vm_private_data)->name;
 }
 
+static int special_mapping_mremap(struct vm_area_struct *new_vma)
+{
+       struct vm_special_mapping *sm = new_vma->vm_private_data;
+
+       if (sm->mremap)
+               return sm->mremap(sm, new_vma);
+       return 0;
+}
+
 static const struct vm_operations_struct special_mapping_vmops = {
        .close = special_mapping_close,
        .fault = special_mapping_fault,
+       .mremap = special_mapping_mremap,
        .name = special_mapping_name,
 };