Commit:     3ee6dafc677a68e461a7ddafc94a580ebab80735
Parent:     bb2d5ce16409efcdf94017a6b6fecd468226e29c
Author:     Miklos Szeredi <[EMAIL PROTECTED]>
AuthorDate: Thu Jul 19 01:47:24 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Jul 19 10:04:41 2007 -0700

    only allow nonlinear vmas for ram backed filesystems
    page_mkclean() doesn't re-protect ptes for non-linear mappings, so a later
    re-dirty through such a mapping will not generate a fault, PG_dirty will
    not reflect the dirty state and the dirty count will be skewed.  This
    implies that msync() is also currently broken for nonlinear mappings.
    The easiest solution is to emulate remap_file_pages on non-linear mappings
    with simple mmap() for non ram-backed filesystems.  Applications continue
    to work (albeit slower), as long as the number of remappings remain below
    the maximum vma count.
    However all currently known real uses of non-linear mappings are for ram
    backed filesystems, which this patch doesn't affect.
    Signed-off-by: Miklos Szeredi <[EMAIL PROTECTED]>
    Acked-by: Peter Zijlstra <[EMAIL PROTECTED]>
    Cc: William Lee Irwin III <[EMAIL PROTECTED]>
    Cc: Nick Piggin <[EMAIL PROTECTED]>
    Cc: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
 mm/fremap.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/mm/fremap.c b/mm/fremap.c
index 5f50d73..c395b1a 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -181,6 +181,25 @@ asmlinkage long sys_remap_file_pages(unsigned long start, 
unsigned long size,
                        goto retry;
                mapping = vma->vm_file->f_mapping;
+               /*
+                * page_mkclean doesn't work on nonlinear vmas, so if
+                * dirty pages need to be accounted, emulate with linear
+                * vmas.
+                */
+               if (mapping_cap_account_dirty(mapping)) {
+                       unsigned long addr;
+                       flags &= MAP_NONBLOCK;
+                       addr = mmap_region(vma->vm_file, start, size,
+                                       flags, vma->vm_flags, pgoff, 1);
+                       if (IS_ERR_VALUE(addr)) {
+                               err = addr;
+                       } else {
+                               BUG_ON(addr != start);
+                               err = 0;
+                       }
+                       goto out;
+               }
                vma->vm_flags |= VM_NONLINEAR;
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to