diff options
| -rw-r--r-- | include/linux/writeback.h | 2 | ||||
| -rw-r--r-- | mm/memory.c | 9 | ||||
| -rw-r--r-- | mm/page-writeback.c | 4 |
3 files changed, 10 insertions, 5 deletions
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 4ef4d22e5e43..b4af6bcb7b7a 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
| @@ -127,7 +127,7 @@ int sync_page_range(struct inode *inode, struct address_space *mapping, | |||
| 127 | loff_t pos, loff_t count); | 127 | loff_t pos, loff_t count); |
| 128 | int sync_page_range_nolock(struct inode *inode, struct address_space *mapping, | 128 | int sync_page_range_nolock(struct inode *inode, struct address_space *mapping, |
| 129 | loff_t pos, loff_t count); | 129 | loff_t pos, loff_t count); |
| 130 | void set_page_dirty_balance(struct page *page); | 130 | void set_page_dirty_balance(struct page *page, int page_mkwrite); |
| 131 | void writeback_set_ratelimit(void); | 131 | void writeback_set_ratelimit(void); |
| 132 | 132 | ||
| 133 | /* pdflush.c */ | 133 | /* pdflush.c */ |
diff --git a/mm/memory.c b/mm/memory.c index c0e7741a98de..f82b359b2745 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1639,6 +1639,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 1639 | struct page *old_page, *new_page; | 1639 | struct page *old_page, *new_page; |
| 1640 | pte_t entry; | 1640 | pte_t entry; |
| 1641 | int reuse = 0, ret = 0; | 1641 | int reuse = 0, ret = 0; |
| 1642 | int page_mkwrite = 0; | ||
| 1642 | struct page *dirty_page = NULL; | 1643 | struct page *dirty_page = NULL; |
| 1643 | 1644 | ||
| 1644 | old_page = vm_normal_page(vma, address, orig_pte); | 1645 | old_page = vm_normal_page(vma, address, orig_pte); |
| @@ -1687,6 +1688,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 1687 | page_cache_release(old_page); | 1688 | page_cache_release(old_page); |
| 1688 | if (!pte_same(*page_table, orig_pte)) | 1689 | if (!pte_same(*page_table, orig_pte)) |
| 1689 | goto unlock; | 1690 | goto unlock; |
| 1691 | |||
| 1692 | page_mkwrite = 1; | ||
| 1690 | } | 1693 | } |
| 1691 | dirty_page = old_page; | 1694 | dirty_page = old_page; |
| 1692 | get_page(dirty_page); | 1695 | get_page(dirty_page); |
| @@ -1774,7 +1777,7 @@ unlock: | |||
| 1774 | * do_no_page is protected similarly. | 1777 | * do_no_page is protected similarly. |
| 1775 | */ | 1778 | */ |
| 1776 | wait_on_page_locked(dirty_page); | 1779 | wait_on_page_locked(dirty_page); |
| 1777 | set_page_dirty_balance(dirty_page); | 1780 | set_page_dirty_balance(dirty_page, page_mkwrite); |
| 1778 | put_page(dirty_page); | 1781 | put_page(dirty_page); |
| 1779 | } | 1782 | } |
| 1780 | return ret; | 1783 | return ret; |
| @@ -2322,6 +2325,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2322 | struct page *dirty_page = NULL; | 2325 | struct page *dirty_page = NULL; |
| 2323 | struct vm_fault vmf; | 2326 | struct vm_fault vmf; |
| 2324 | int ret; | 2327 | int ret; |
| 2328 | int page_mkwrite = 0; | ||
| 2325 | 2329 | ||
| 2326 | vmf.virtual_address = (void __user *)(address & PAGE_MASK); | 2330 | vmf.virtual_address = (void __user *)(address & PAGE_MASK); |
| 2327 | vmf.pgoff = pgoff; | 2331 | vmf.pgoff = pgoff; |
| @@ -2398,6 +2402,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 2398 | anon = 1; /* no anon but release vmf.page */ | 2402 | anon = 1; /* no anon but release vmf.page */ |
| 2399 | goto out; | 2403 | goto out; |
| 2400 | } | 2404 | } |
| 2405 | page_mkwrite = 1; | ||
| 2401 | } | 2406 | } |
| 2402 | } | 2407 | } |
| 2403 | 2408 | ||
| @@ -2453,7 +2458,7 @@ out_unlocked: | |||
| 2453 | if (anon) | 2458 | if (anon) |
| 2454 | page_cache_release(vmf.page); | 2459 | page_cache_release(vmf.page); |
| 2455 | else if (dirty_page) { | 2460 | else if (dirty_page) { |
| 2456 | set_page_dirty_balance(dirty_page); | 2461 | set_page_dirty_balance(dirty_page, page_mkwrite); |
| 2457 | put_page(dirty_page); | 2462 | put_page(dirty_page); |
| 2458 | } | 2463 | } |
| 2459 | 2464 | ||
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 63512a9ed57e..44720363374c 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
| @@ -274,9 +274,9 @@ static void balance_dirty_pages(struct address_space *mapping) | |||
| 274 | pdflush_operation(background_writeout, 0); | 274 | pdflush_operation(background_writeout, 0); |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | void set_page_dirty_balance(struct page *page) | 277 | void set_page_dirty_balance(struct page *page, int page_mkwrite) |
| 278 | { | 278 | { |
| 279 | if (set_page_dirty(page)) { | 279 | if (set_page_dirty(page) || page_mkwrite) { |
| 280 | struct address_space *mapping = page_mapping(page); | 280 | struct address_space *mapping = page_mapping(page); |
| 281 | 281 | ||
| 282 | if (mapping) | 282 | if (mapping) |
