diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-13 18:45:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 20:32:32 -0500 |
commit | 9cbb4cb21b19fff46cf1174d0ed699ef710e641c (patch) | |
tree | 56480b1f4082d6158f077378db36c99d6d3ff209 /mm | |
parent | f0bc0a60b13f209df16062f94e9fb4b90dc08708 (diff) |
mm: find_get_pages_contig fixlet
Testing ->mapping and ->index without a ref is not stable as the page
may have been reused at this point.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Reviewed-by: Wu Fengguang <fengguang.wu@intel.com>
Reviewed-by: Minchan Kim <minchan.kim@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index ca389394fa2a..1a3dd5914726 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -837,9 +837,6 @@ repeat: | |||
837 | if (radix_tree_deref_retry(page)) | 837 | if (radix_tree_deref_retry(page)) |
838 | goto restart; | 838 | goto restart; |
839 | 839 | ||
840 | if (page->mapping == NULL || page->index != index) | ||
841 | break; | ||
842 | |||
843 | if (!page_cache_get_speculative(page)) | 840 | if (!page_cache_get_speculative(page)) |
844 | goto repeat; | 841 | goto repeat; |
845 | 842 | ||
@@ -849,6 +846,16 @@ repeat: | |||
849 | goto repeat; | 846 | goto repeat; |
850 | } | 847 | } |
851 | 848 | ||
849 | /* | ||
850 | * must check mapping and index after taking the ref. | ||
851 | * otherwise we can get both false positives and false | ||
852 | * negatives, which is just confusing to the caller. | ||
853 | */ | ||
854 | if (page->mapping == NULL || page->index != index) { | ||
855 | page_cache_release(page); | ||
856 | break; | ||
857 | } | ||
858 | |||
852 | pages[ret] = page; | 859 | pages[ret] = page; |
853 | ret++; | 860 | ret++; |
854 | index++; | 861 | index++; |