If a CPU faults this page into pagetables after invalidate_mapping_pages()
checked page_mapped(), invalidate_complete_page() will still proceed to remove
the page from pagecache.  This leaves the page-faulting process with a
detached page.  If it was MAP_SHARED then file data loss will ensue.
Fix that up by checking the page's refcount after taking tree_lock.
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
                return 0;
 
        write_lock_irq(&mapping->tree_lock);
-       if (PageDirty(page)) {
-               write_unlock_irq(&mapping->tree_lock);
-               return 0;
-       }
+       if (PageDirty(page))
+               goto failed;
+       if (page_count(page) != 2)      /* caller's ref + pagecache ref */
+               goto failed;
 
        BUG_ON(PagePrivate(page));
        __remove_from_page_cache(page);
        ClearPageUptodate(page);
        page_cache_release(page);       /* pagecache ref */
        return 1;
+failed:
+       write_unlock_irq(&mapping->tree_lock);
+       return 0;
 }
 
 /**