Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[linux-2.6-block.git] / mm / filemap.c
index 182b21825255397d8691431f7f47673b52ff79c7..00ae878b2a3860ce5b4bfe41967430e781ebabc1 100644 (file)
@@ -114,14 +114,11 @@ static void page_cache_tree_delete(struct address_space *mapping,
                                   struct page *page, void *shadow)
 {
        struct radix_tree_node *node;
-       unsigned long index;
-       unsigned int offset;
-       unsigned int tag;
-       void **slot;
 
        VM_BUG_ON(!PageLocked(page));
 
-       __radix_tree_lookup(&mapping->page_tree, page->index, &node, &slot);
+       node = radix_tree_replace_clear_tags(&mapping->page_tree, page->index,
+                                                               shadow);
 
        if (shadow) {
                mapping->nrexceptional++;
@@ -135,23 +132,9 @@ static void page_cache_tree_delete(struct address_space *mapping,
        }
        mapping->nrpages--;
 
-       if (!node) {
-               /* Clear direct pointer tags in root node */
-               mapping->page_tree.gfp_mask &= __GFP_BITS_MASK;
-               radix_tree_replace_slot(slot, shadow);
+       if (!node)
                return;
-       }
-
-       /* Clear tree tags for the removed page */
-       index = page->index;
-       offset = index & RADIX_TREE_MAP_MASK;
-       for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
-               if (test_bit(offset, node->tags[tag]))
-                       radix_tree_tag_clear(&mapping->page_tree, index, tag);
-       }
 
-       /* Delete page, swap shadow entry */
-       radix_tree_replace_slot(slot, shadow);
        workingset_node_pages_dec(node);
        if (shadow)
                workingset_node_shadows_inc(node);
@@ -160,13 +143,15 @@ static void page_cache_tree_delete(struct address_space *mapping,
                        return;
 
        /*
-        * Track node that only contains shadow entries.
+        * Track node that only contains shadow entries. DAX mappings contain
+        * no shadow entries and may contain other exceptional entries so skip
+        * those.
         *
         * Avoid acquiring the list_lru lock if already tracked.  The
         * list_empty() test is safe as node->private_list is
         * protected by mapping->tree_lock.
         */
-       if (!workingset_node_pages(node) &&
+       if (!dax_mapping(mapping) && !workingset_node_pages(node) &&
            list_empty(&node->private_list)) {
                node->private_data = mapping;
                list_lru_add(&workingset_shadow_nodes, &node->private_list);
@@ -213,7 +198,7 @@ void __delete_from_page_cache(struct page *page, void *shadow)
                         * some other bad page check should catch it later.
                         */
                        page_mapcount_reset(page);
-                       atomic_sub(mapcount, &page->_count);
+                       page_ref_sub(page, mapcount);
                }
        }
 
@@ -597,14 +582,24 @@ static int page_cache_tree_insert(struct address_space *mapping,
                if (!radix_tree_exceptional_entry(p))
                        return -EEXIST;
 
-               if (WARN_ON(dax_mapping(mapping)))
-                       return -EINVAL;
-
-               if (shadowp)
-                       *shadowp = p;
                mapping->nrexceptional--;
-               if (node)
-                       workingset_node_shadows_dec(node);
+               if (!dax_mapping(mapping)) {
+                       if (shadowp)
+                               *shadowp = p;
+                       if (node)
+                               workingset_node_shadows_dec(node);
+               } else {
+                       /* DAX can replace empty locked entry with a hole */
+                       WARN_ON_ONCE(p !=
+                               (void *)(RADIX_TREE_EXCEPTIONAL_ENTRY |
+                                        RADIX_DAX_ENTRY_LOCK));
+                       /* DAX accounts exceptional entries as normal pages */
+                       if (node)
+                               workingset_node_pages_dec(node);
+                       /* Wakeup waiters for exceptional entry lock */
+                       dax_wake_mapping_entry_waiter(mapping, page->index,
+                                                     false);
+               }
        }
        radix_tree_replace_slot(slot, page);
        mapping->nrpages++;
@@ -713,8 +708,12 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
                 * The page might have been evicted from cache only
                 * recently, in which case it should be activated like
                 * any other repeatedly accessed page.
+                * The exception is pages getting rewritten; evicting other
+                * data from the working set, only to cache data that will
+                * get overwritten with something else, is a waste of memory.
                 */
-               if (shadow && workingset_refault(shadow)) {
+               if (!(gfp_mask & __GFP_WRITE) &&
+                   shadow && workingset_refault(shadow)) {
                        SetPageActive(page);
                        workingset_activation(page);
                } else
@@ -2187,7 +2186,7 @@ repeat:
                if (file->f_ra.mmap_miss > 0)
                        file->f_ra.mmap_miss--;
                addr = address + (page->index - vmf->pgoff) * PAGE_SIZE;
-               do_set_pte(vma, addr, page, pte, false, false);
+               do_set_pte(vma, addr, page, pte, false, false, true);
                unlock_page(page);
                goto next;
 unlock:
@@ -2574,7 +2573,7 @@ struct page *grab_cache_page_write_begin(struct address_space *mapping,
                                        pgoff_t index, unsigned flags)
 {
        struct page *page;
-       int fgp_flags = FGP_LOCK|FGP_ACCESSED|FGP_WRITE|FGP_CREAT;
+       int fgp_flags = FGP_LOCK|FGP_WRITE|FGP_CREAT;
 
        if (flags & AOP_FLAG_NOFS)
                fgp_flags |= FGP_NOFS;