vm: fix vm_pgoff wrap in stack expansion
[pandora-kernel.git] / mm / truncate.c
index 49feb46..a956675 100644 (file)
@@ -106,9 +106,8 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
        cancel_dirty_page(page, PAGE_CACHE_SIZE);
 
        clear_page_mlock(page);
-       remove_from_page_cache(page);
        ClearPageMappedToDisk(page);
-       page_cache_release(page);       /* pagecache ref */
+       delete_from_page_cache(page);
        return 0;
 }
 
@@ -225,6 +224,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
        next = start;
        while (next <= end &&
               pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+               mem_cgroup_uncharge_start();
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
                        pgoff_t page_index = page->index;
@@ -247,6 +247,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
                        unlock_page(page);
                }
                pagevec_release(&pvec);
+               mem_cgroup_uncharge_end();
                cond_resched();
        }
 
@@ -320,11 +321,12 @@ EXPORT_SYMBOL(truncate_inode_pages);
  * pagetables.
  */
 unsigned long invalidate_mapping_pages(struct address_space *mapping,
-                                      pgoff_t start, pgoff_t end)
+               pgoff_t start, pgoff_t end)
 {
        struct pagevec pvec;
        pgoff_t next = start;
-       unsigned long ret = 0;
+       unsigned long ret;
+       unsigned long count = 0;
        int i;
 
        pagevec_init(&pvec, 0);
@@ -351,9 +353,15 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
                        if (lock_failed)
                                continue;
 
-                       ret += invalidate_inode_page(page);
-
+                       ret = invalidate_inode_page(page);
                        unlock_page(page);
+                       /*
+                        * Invalidation is a hint that the page is no longer
+                        * of interest and try to speed up its reclaim.
+                        */
+                       if (!ret)
+                               deactivate_page(page);
+                       count += ret;
                        if (next > end)
                                break;
                }
@@ -361,7 +369,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
                mem_cgroup_uncharge_end();
                cond_resched();
        }
-       return ret;
+       return count;
 }
 EXPORT_SYMBOL(invalidate_mapping_pages);
 
@@ -387,7 +395,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
 
        clear_page_mlock(page);
        BUG_ON(page_has_private(page));
-       __remove_from_page_cache(page);
+       __delete_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);