aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 61ba5e405791..6b9aee20f242 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page)
143void remove_from_page_cache(struct page *page) 143void remove_from_page_cache(struct page *page)
144{ 144{
145 struct address_space *mapping = page->mapping; 145 struct address_space *mapping = page->mapping;
146 void (*freepage)(struct page *);
146 147
147 BUG_ON(!PageLocked(page)); 148 BUG_ON(!PageLocked(page));
148 149
150 freepage = mapping->a_ops->freepage;
149 spin_lock_irq(&mapping->tree_lock); 151 spin_lock_irq(&mapping->tree_lock);
150 __remove_from_page_cache(page); 152 __remove_from_page_cache(page);
151 spin_unlock_irq(&mapping->tree_lock); 153 spin_unlock_irq(&mapping->tree_lock);
152 mem_cgroup_uncharge_cache_page(page); 154 mem_cgroup_uncharge_cache_page(page);
155
156 if (freepage)
157 freepage(page);
153} 158}
154EXPORT_SYMBOL(remove_from_page_cache); 159EXPORT_SYMBOL(remove_from_page_cache);
155 160
@@ -644,7 +649,9 @@ repeat:
644 pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); 649 pagep = radix_tree_lookup_slot(&mapping->page_tree, offset);
645 if (pagep) { 650 if (pagep) {
646 page = radix_tree_deref_slot(pagep); 651 page = radix_tree_deref_slot(pagep);
647 if (unlikely(!page || page == RADIX_TREE_RETRY)) 652 if (unlikely(!page))
653 goto out;
654 if (radix_tree_deref_retry(page))
648 goto repeat; 655 goto repeat;
649 656
650 if (!page_cache_get_speculative(page)) 657 if (!page_cache_get_speculative(page))
@@ -660,6 +667,7 @@ repeat:
660 goto repeat; 667 goto repeat;
661 } 668 }
662 } 669 }
670out:
663 rcu_read_unlock(); 671 rcu_read_unlock();
664 672
665 return page; 673 return page;
@@ -777,12 +785,11 @@ repeat:
777 page = radix_tree_deref_slot((void **)pages[i]); 785 page = radix_tree_deref_slot((void **)pages[i]);
778 if (unlikely(!page)) 786 if (unlikely(!page))
779 continue; 787 continue;
780 /* 788 if (radix_tree_deref_retry(page)) {
781 * this can only trigger if nr_found == 1, making livelock 789 if (ret)
782 * a non issue. 790 start = pages[ret-1]->index;
783 */
784 if (unlikely(page == RADIX_TREE_RETRY))
785 goto restart; 791 goto restart;
792 }
786 793
787 if (!page_cache_get_speculative(page)) 794 if (!page_cache_get_speculative(page))
788 goto repeat; 795 goto repeat;
@@ -830,11 +837,7 @@ repeat:
830 page = radix_tree_deref_slot((void **)pages[i]); 837 page = radix_tree_deref_slot((void **)pages[i]);
831 if (unlikely(!page)) 838 if (unlikely(!page))
832 continue; 839 continue;
833 /* 840 if (radix_tree_deref_retry(page))
834 * this can only trigger if nr_found == 1, making livelock
835 * a non issue.
836 */
837 if (unlikely(page == RADIX_TREE_RETRY))
838 goto restart; 841 goto restart;
839 842
840 if (page->mapping == NULL || page->index != index) 843 if (page->mapping == NULL || page->index != index)
@@ -887,11 +890,7 @@ repeat:
887 page = radix_tree_deref_slot((void **)pages[i]); 890 page = radix_tree_deref_slot((void **)pages[i]);
888 if (unlikely(!page)) 891 if (unlikely(!page))
889 continue; 892 continue;
890 /* 893 if (radix_tree_deref_retry(page))
891 * this can only trigger if nr_found == 1, making livelock
892 * a non issue.
893 */
894 if (unlikely(page == RADIX_TREE_RETRY))
895 goto restart; 894 goto restart;
896 895
897 if (!page_cache_get_speculative(page)) 896 if (!page_cache_get_speculative(page))
@@ -1029,6 +1028,9 @@ find_page:
1029 goto page_not_up_to_date; 1028 goto page_not_up_to_date;
1030 if (!trylock_page(page)) 1029 if (!trylock_page(page))
1031 goto page_not_up_to_date; 1030 goto page_not_up_to_date;
1031 /* Did it get truncated before we got the lock? */
1032 if (!page->mapping)
1033 goto page_not_up_to_date_locked;
1032 if (!mapping->a_ops->is_partially_uptodate(page, 1034 if (!mapping->a_ops->is_partially_uptodate(page,
1033 desc, offset)) 1035 desc, offset))
1034 goto page_not_up_to_date_locked; 1036 goto page_not_up_to_date_locked;