Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b1d0e4f535e10775cffde922208b49629169aeaa
Commit:     b1d0e4f535e10775cffde922208b49629169aeaa
Parent:     6a306e8b4c81a1c1f538e390d92bfe80d04b254c
Author:     Nick Piggin <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 9 01:15:19 2008 +0100
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Fri Feb 8 18:57:39 2008 -0800

    mm: special mapping nopage
    
    Convert special mapping install from nopage to fault.
    
    Because the "vm_file" is NULL for the special mapping, the generic VM
    code has messed up "vm_pgoff" thinking that it's an anonymous mapping
    and the offset does't matter.  For that reason, we need to undo the
    vm_pgoff offset that got added into vmf->pgoff.
    
    [ We _really_ should clean that up - either by making this whole special
      mapping code just use a real file entry rather than that ugly array of
      "struct page" pointers, or by just making the VM code realize that
      even if vm_file is NULL it may not be a regular anonymous mmap.
                                                         - Linus ]
    
    Signed-off-by: Nick Piggin <[EMAIL PROTECTED]>
    Cc: [EMAIL PROTECTED]
    Cc: [EMAIL PROTECTED]
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 mm/mmap.c |   25 ++++++++++++++++---------
 1 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index ad6e4ea..a32d28c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2165,24 +2165,31 @@ int may_expand_vm(struct mm_struct *mm, unsigned long 
npages)
 }
 
 
-static struct page *special_mapping_nopage(struct vm_area_struct *vma,
-                                          unsigned long address, int *type)
+static int special_mapping_fault(struct vm_area_struct *vma,
+                               struct vm_fault *vmf)
 {
+       pgoff_t pgoff;
        struct page **pages;
 
-       BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+       /*
+        * special mappings have no vm_file, and in that case, the mm
+        * uses vm_pgoff internally. So we have to subtract it from here.
+        * We are allowed to do this because we are the mm; do not copy
+        * this code into drivers!
+        */
+       pgoff = vmf->pgoff - vma->vm_pgoff;
 
-       address -= vma->vm_start;
-       for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
-               address -= PAGE_SIZE;
+       for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
+               pgoff--;
 
        if (*pages) {
                struct page *page = *pages;
                get_page(page);
-               return page;
+               vmf->page = page;
+               return 0;
        }
 
-       return NOPAGE_SIGBUS;
+       return VM_FAULT_SIGBUS;
 }
 
 /*
@@ -2194,7 +2201,7 @@ static void special_mapping_close(struct vm_area_struct 
*vma)
 
 static struct vm_operations_struct special_mapping_vmops = {
        .close = special_mapping_close,
-       .nopage = special_mapping_nopage,
+       .fault = special_mapping_fault,
 };
 
 /*
-
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  http://vger.kernel.org/majordomo-info.html

Reply via email to