page-flags: introduce page flags policies wrt compound pages
[cascardo/linux.git] / mm / memory.c
index f7026c0..d4e4d37 100644 (file)
@@ -1938,6 +1938,20 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
                copy_user_highpage(dst, src, va, vma);
 }
 
+static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma)
+{
+       struct file *vm_file = vma->vm_file;
+
+       if (vm_file)
+               return mapping_gfp_mask(vm_file->f_mapping) | __GFP_FS | __GFP_IO;
+
+       /*
+        * Special mappings (e.g. VDSO) do not have any file so fake
+        * a default GFP_KERNEL for them.
+        */
+       return GFP_KERNEL;
+}
+
 /*
  * Notify the address space that the page is about to become writable so that
  * it can prohibit this or wait for the page to get into an appropriate state.
@@ -1953,6 +1967,7 @@ static int do_page_mkwrite(struct vm_area_struct *vma, struct page *page,
        vmf.virtual_address = (void __user *)(address & PAGE_MASK);
        vmf.pgoff = page->index;
        vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE;
+       vmf.gfp_mask = __get_fault_gfp_mask(vma);
        vmf.page = page;
        vmf.cow_page = NULL;
 
@@ -2757,6 +2772,7 @@ static int __do_fault(struct vm_area_struct *vma, unsigned long address,
        vmf.pgoff = pgoff;
        vmf.flags = flags;
        vmf.page = NULL;
+       vmf.gfp_mask = __get_fault_gfp_mask(vma);
        vmf.cow_page = cow_page;
 
        ret = vma->vm_ops->fault(vma, &vmf);
@@ -2923,6 +2939,7 @@ static void do_fault_around(struct vm_area_struct *vma, unsigned long address,
        vmf.pgoff = pgoff;
        vmf.max_pgoff = max_pgoff;
        vmf.flags = flags;
+       vmf.gfp_mask = __get_fault_gfp_mask(vma);
        vma->vm_ops->map_pages(vma, &vmf);
 }