aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/buffer.c')
-rw-r--r--fs/buffer.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 517860f2d75b..d1f1b54d3108 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -35,6 +35,7 @@
35#include <linux/hash.h> 35#include <linux/hash.h>
36#include <linux/suspend.h> 36#include <linux/suspend.h>
37#include <linux/buffer_head.h> 37#include <linux/buffer_head.h>
38#include <linux/task_io_accounting_ops.h>
38#include <linux/bio.h> 39#include <linux/bio.h>
39#include <linux/notifier.h> 40#include <linux/notifier.h>
40#include <linux/cpu.h> 41#include <linux/cpu.h>
@@ -724,20 +725,21 @@ int __set_page_dirty_buffers(struct page *page)
724 } 725 }
725 spin_unlock(&mapping->private_lock); 726 spin_unlock(&mapping->private_lock);
726 727
727 if (!TestSetPageDirty(page)) { 728 if (TestSetPageDirty(page))
728 write_lock_irq(&mapping->tree_lock); 729 return 0;
729 if (page->mapping) { /* Race with truncate? */ 730
730 if (mapping_cap_account_dirty(mapping)) 731 write_lock_irq(&mapping->tree_lock);
731 __inc_zone_page_state(page, NR_FILE_DIRTY); 732 if (page->mapping) { /* Race with truncate? */
732 radix_tree_tag_set(&mapping->page_tree, 733 if (mapping_cap_account_dirty(mapping)) {
733 page_index(page), 734 __inc_zone_page_state(page, NR_FILE_DIRTY);
734 PAGECACHE_TAG_DIRTY); 735 task_io_account_write(PAGE_CACHE_SIZE);
735 } 736 }
736 write_unlock_irq(&mapping->tree_lock); 737 radix_tree_tag_set(&mapping->page_tree,
737 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); 738 page_index(page), PAGECACHE_TAG_DIRTY);
738 return 1;
739 } 739 }
740 return 0; 740 write_unlock_irq(&mapping->tree_lock);
741 __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
742 return 1;
741} 743}
742EXPORT_SYMBOL(__set_page_dirty_buffers); 744EXPORT_SYMBOL(__set_page_dirty_buffers);
743 745
@@ -2851,8 +2853,13 @@ int try_to_free_buffers(struct page *page)
2851 * could encounter a non-uptodate page, which is unresolvable. 2853 * could encounter a non-uptodate page, which is unresolvable.
2852 * This only applies in the rare case where try_to_free_buffers 2854 * This only applies in the rare case where try_to_free_buffers
2853 * succeeds but the page is not freed. 2855 * succeeds but the page is not freed.
2856 *
2857 * Also, during truncate, discard_buffer will have marked all
2858 * the page's buffers clean. We discover that here and clean
2859 * the page also.
2854 */ 2860 */
2855 clear_page_dirty(page); 2861 if (test_clear_page_dirty(page))
2862 task_io_account_cancelled_write(PAGE_CACHE_SIZE);
2856 } 2863 }
2857out: 2864out:
2858 if (buffers_to_free) { 2865 if (buffers_to_free) {