Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[linux-2.6-block.git] / mm / page-writeback.c
index 644bcb665773f6e53f50fe6599429595b506f0c5..5daf5568b9e149ea9dce0383b0452bd30ad67f84 100644 (file)
@@ -2110,6 +2110,25 @@ void account_page_dirtied(struct page *page, struct address_space *mapping)
 }
 EXPORT_SYMBOL(account_page_dirtied);
 
+/*
+ * Helper function for deaccounting dirty page without writeback.
+ *
+ * Doing this should *normally* only ever be done when a page
+ * is truncated, and is not actually mapped anywhere at all. However,
+ * fs/buffer.c does this when it notices that somebody has cleaned
+ * out all the buffers on a page without actually doing it through
+ * the VM. Can you say "ext3 is horribly ugly"? Thought you could.
+ */
+void account_page_cleaned(struct page *page, struct address_space *mapping)
+{
+       if (mapping_cap_account_dirty(mapping)) {
+               dec_zone_page_state(page, NR_FILE_DIRTY);
+               dec_bdi_stat(inode_to_bdi(mapping->host), BDI_RECLAIMABLE);
+               task_io_account_cancelled_write(PAGE_CACHE_SIZE);
+       }
+}
+EXPORT_SYMBOL(account_page_cleaned);
+
 /*
  * For address_spaces which do not use buffers.  Just tag the page as dirty in
  * its radix tree.
@@ -2209,7 +2228,8 @@ int set_page_dirty(struct page *page)
                 * it will confuse readahead and make it restart the size rampup
                 * process. But it's a trivial problem.
                 */
-               ClearPageReclaim(page);
+               if (PageReclaim(page))
+                       ClearPageReclaim(page);
 #ifdef CONFIG_BLOCK
                if (!spd)
                        spd = __set_page_dirty_buffers;