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 3d4df44e4221..9701a501f769 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -631,7 +631,9 @@ repeat: | |||
631 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); | 631 | pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); |
632 | if (pagep) { | 632 | if (pagep) { |
633 | page = radix_tree_deref_slot(pagep); | 633 | page = radix_tree_deref_slot(pagep); |
634 | if (unlikely(!page || page == RADIX_TREE_RETRY)) | 634 | if (unlikely(!page)) |
635 | goto out; | ||
636 | if (radix_tree_deref_retry(page)) | ||
635 | goto repeat; | 637 | goto repeat; |
636 | 638 | ||
637 | if (!page_cache_get_speculative(page)) | 639 | if (!page_cache_get_speculative(page)) |
@@ -647,6 +649,7 @@ repeat: | |||
647 | goto repeat; | 649 | goto repeat; |
648 | } | 650 | } |
649 | } | 651 | } |
652 | out: | ||
650 | rcu_read_unlock(); | 653 | rcu_read_unlock(); |
651 | 654 | ||
652 | return page; | 655 | return page; |
@@ -764,12 +767,11 @@ repeat: | |||
764 | page = radix_tree_deref_slot((void **)pages[i]); | 767 | page = radix_tree_deref_slot((void **)pages[i]); |
765 | if (unlikely(!page)) | 768 | if (unlikely(!page)) |
766 | continue; | 769 | continue; |
767 | /* | 770 | if (radix_tree_deref_retry(page)) { |
768 | * this can only trigger if nr_found == 1, making livelock | 771 | if (ret) |
769 | * a non issue. | 772 | start = pages[ret-1]->index; |
770 | */ | ||
771 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
772 | goto restart; | 773 | goto restart; |
774 | } | ||
773 | 775 | ||
774 | if (!page_cache_get_speculative(page)) | 776 | if (!page_cache_get_speculative(page)) |
775 | goto repeat; | 777 | goto repeat; |
@@ -817,11 +819,7 @@ repeat: | |||
817 | page = radix_tree_deref_slot((void **)pages[i]); | 819 | page = radix_tree_deref_slot((void **)pages[i]); |
818 | if (unlikely(!page)) | 820 | if (unlikely(!page)) |
819 | continue; | 821 | continue; |
820 | /* | 822 | if (radix_tree_deref_retry(page)) |
821 | * this can only trigger if nr_found == 1, making livelock | ||
822 | * a non issue. | ||
823 | */ | ||
824 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
825 | goto restart; | 823 | goto restart; |
826 | 824 | ||
827 | if (page->mapping == NULL || page->index != index) | 825 | if (page->mapping == NULL || page->index != index) |
@@ -874,11 +872,7 @@ repeat: | |||
874 | page = radix_tree_deref_slot((void **)pages[i]); | 872 | page = radix_tree_deref_slot((void **)pages[i]); |
875 | if (unlikely(!page)) | 873 | if (unlikely(!page)) |
876 | continue; | 874 | continue; |
877 | /* | 875 | if (radix_tree_deref_retry(page)) |
878 | * this can only trigger if nr_found == 1, making livelock | ||
879 | * a non issue. | ||
880 | */ | ||
881 | if (unlikely(page == RADIX_TREE_RETRY)) | ||
882 | goto restart; | 876 | goto restart; |
883 | 877 | ||
884 | if (!page_cache_get_speculative(page)) | 878 | if (!page_cache_get_speculative(page)) |
@@ -1016,6 +1010,9 @@ find_page: | |||
1016 | goto page_not_up_to_date; | 1010 | goto page_not_up_to_date; |
1017 | if (!trylock_page(page)) | 1011 | if (!trylock_page(page)) |
1018 | goto page_not_up_to_date; | 1012 | goto page_not_up_to_date; |
1013 | /* Did it get truncated before we got the lock? */ | ||
1014 | if (!page->mapping) | ||
1015 | goto page_not_up_to_date_locked; | ||
1019 | if (!mapping->a_ops->is_partially_uptodate(page, | 1016 | if (!mapping->a_ops->is_partially_uptodate(page, |
1020 | desc, offset)) | 1017 | desc, offset)) |
1021 | goto page_not_up_to_date_locked; | 1018 | goto page_not_up_to_date_locked; |