diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 61ba5e405791..ea89840fc65f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -644,7 +644,9 @@ repeat: | |||
644 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); | 644 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); |
645 | if (pagep) { | 645 | if (pagep) { |
646 | page = radix_tree_deref_slot(pagep); | 646 | page = radix_tree_deref_slot(pagep); |
647 | if (unlikely(!page || page == RADIX_TREE_RETRY)) | 647 | if (unlikely(!page)) |
648 | goto out; | ||
649 | if (radix_tree_deref_retry(page)) | ||
648 | goto repeat; | 650 | goto repeat; |
649 | 651 | ||
650 | if (!page_cache_get_speculative(page)) | 652 | if (!page_cache_get_speculative(page)) |
@@ -660,6 +662,7 @@ repeat: | |||
660 | goto repeat; | 662 | goto repeat; |
661 | } | 663 | } |
662 | } | 664 | } |
665 | out: | ||
663 | rcu_read_unlock(); | 666 | rcu_read_unlock(); |
664 | 667 | ||
665 | return page; | 668 | return page; |
@@ -777,12 +780,11 @@ repeat: | |||
777 | page = radix_tree_deref_slot((void **)pages[i]); | 780 | page = radix_tree_deref_slot((void **)pages[i]); |
778 | if (unlikely(!page)) | 781 | if (unlikely(!page)) |
779 | continue; | 782 | continue; |
780 | /* | 783 | if (radix_tree_deref_retry(page)) { |
781 | * this can only trigger if nr_found == 1, making livelock | 784 | if (ret) |
782 | * a non issue. | 785 | start = pages[ret-1]->index; |
783 | */ | ||
784 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
785 | goto restart; | 786 | goto restart; |
787 | } | ||
786 | 788 | ||
787 | if (!page_cache_get_speculative(page)) | 789 | if (!page_cache_get_speculative(page)) |
788 | goto repeat; | 790 | goto repeat; |
@@ -830,11 +832,7 @@ repeat: | |||
830 | page = radix_tree_deref_slot((void **)pages[i]); | 832 | page = radix_tree_deref_slot((void **)pages[i]); |
831 | if (unlikely(!page)) | 833 | if (unlikely(!page)) |
832 | continue; | 834 | continue; |
833 | /* | 835 | 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; | 836 | goto restart; |
839 | 837 | ||
840 | if (page->mapping == NULL || page->index != index) | 838 | if (page->mapping == NULL || page->index != index) |
@@ -887,11 +885,7 @@ repeat: | |||
887 | page = radix_tree_deref_slot((void **)pages[i]); | 885 | page = radix_tree_deref_slot((void **)pages[i]); |
888 | if (unlikely(!page)) | 886 | if (unlikely(!page)) |
889 | continue; | 887 | continue; |
890 | /* | 888 | 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; | 889 | goto restart; |
896 | 890 | ||
897 | if (!page_cache_get_speculative(page)) | 891 | if (!page_cache_get_speculative(page)) |
@@ -1029,6 +1023,9 @@ find_page: | |||
1029 | goto page_not_up_to_date; | 1023 | goto page_not_up_to_date; |
1030 | if (!trylock_page(page)) | 1024 | if (!trylock_page(page)) |
1031 | goto page_not_up_to_date; | 1025 | goto page_not_up_to_date; |
1026 | /* Did it get truncated before we got the lock? */ | ||
1027 | if (!page->mapping) | ||
1028 | goto page_not_up_to_date_locked; | ||
1032 | if (!mapping->a_ops->is_partially_uptodate(page, | 1029 | if (!mapping->a_ops->is_partially_uptodate(page, |
1033 | desc, offset)) | 1030 | desc, offset)) |
1034 | goto page_not_up_to_date_locked; | 1031 | goto page_not_up_to_date_locked; |