diff options
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r-- | mm/page-writeback.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 77a0bc4e261a..555752907dc3 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/backing-dev.h> | 23 | #include <linux/backing-dev.h> |
24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
25 | #include <linux/mpage.h> | 25 | #include <linux/mpage.h> |
26 | #include <linux/rmap.h> | ||
26 | #include <linux/percpu.h> | 27 | #include <linux/percpu.h> |
27 | #include <linux/notifier.h> | 28 | #include <linux/notifier.h> |
28 | #include <linux/smp.h> | 29 | #include <linux/smp.h> |
@@ -243,6 +244,16 @@ static void balance_dirty_pages(struct address_space *mapping) | |||
243 | pdflush_operation(background_writeout, 0); | 244 | pdflush_operation(background_writeout, 0); |
244 | } | 245 | } |
245 | 246 | ||
247 | void set_page_dirty_balance(struct page *page) | ||
248 | { | ||
249 | if (set_page_dirty(page)) { | ||
250 | struct address_space *mapping = page_mapping(page); | ||
251 | |||
252 | if (mapping) | ||
253 | balance_dirty_pages_ratelimited(mapping); | ||
254 | } | ||
255 | } | ||
256 | |||
246 | /** | 257 | /** |
247 | * balance_dirty_pages_ratelimited_nr - balance dirty memory state | 258 | * balance_dirty_pages_ratelimited_nr - balance dirty memory state |
248 | * @mapping: address_space which was dirtied | 259 | * @mapping: address_space which was dirtied |
@@ -550,7 +561,7 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
550 | return 0; | 561 | return 0; |
551 | wbc->for_writepages = 1; | 562 | wbc->for_writepages = 1; |
552 | if (mapping->a_ops->writepages) | 563 | if (mapping->a_ops->writepages) |
553 | ret = mapping->a_ops->writepages(mapping, wbc); | 564 | ret = mapping->a_ops->writepages(mapping, wbc); |
554 | else | 565 | else |
555 | ret = generic_writepages(mapping, wbc); | 566 | ret = generic_writepages(mapping, wbc); |
556 | wbc->for_writepages = 0; | 567 | wbc->for_writepages = 0; |
@@ -690,7 +701,7 @@ int set_page_dirty_lock(struct page *page) | |||
690 | { | 701 | { |
691 | int ret; | 702 | int ret; |
692 | 703 | ||
693 | lock_page(page); | 704 | lock_page_nosync(page); |
694 | ret = set_page_dirty(page); | 705 | ret = set_page_dirty(page); |
695 | unlock_page(page); | 706 | unlock_page(page); |
696 | return ret; | 707 | return ret; |
@@ -712,9 +723,15 @@ int test_clear_page_dirty(struct page *page) | |||
712 | radix_tree_tag_clear(&mapping->page_tree, | 723 | radix_tree_tag_clear(&mapping->page_tree, |
713 | page_index(page), | 724 | page_index(page), |
714 | PAGECACHE_TAG_DIRTY); | 725 | PAGECACHE_TAG_DIRTY); |
715 | if (mapping_cap_account_dirty(mapping)) | ||
716 | __dec_zone_page_state(page, NR_FILE_DIRTY); | ||
717 | write_unlock_irqrestore(&mapping->tree_lock, flags); | 726 | write_unlock_irqrestore(&mapping->tree_lock, flags); |
727 | /* | ||
728 | * We can continue to use `mapping' here because the | ||
729 | * page is locked, which pins the address_space | ||
730 | */ | ||
731 | if (mapping_cap_account_dirty(mapping)) { | ||
732 | page_mkclean(page); | ||
733 | dec_zone_page_state(page, NR_FILE_DIRTY); | ||
734 | } | ||
718 | return 1; | 735 | return 1; |
719 | } | 736 | } |
720 | write_unlock_irqrestore(&mapping->tree_lock, flags); | 737 | write_unlock_irqrestore(&mapping->tree_lock, flags); |
@@ -744,8 +761,10 @@ int clear_page_dirty_for_io(struct page *page) | |||
744 | 761 | ||
745 | if (mapping) { | 762 | if (mapping) { |
746 | if (TestClearPageDirty(page)) { | 763 | if (TestClearPageDirty(page)) { |
747 | if (mapping_cap_account_dirty(mapping)) | 764 | if (mapping_cap_account_dirty(mapping)) { |
765 | page_mkclean(page); | ||
748 | dec_zone_page_state(page, NR_FILE_DIRTY); | 766 | dec_zone_page_state(page, NR_FILE_DIRTY); |
767 | } | ||
749 | return 1; | 768 | return 1; |
750 | } | 769 | } |
751 | return 0; | 770 | return 0; |