X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=mm%2Ffilemap.c;h=83a45d35468b961340fb19a958eee77d0e2e2297;hb=e98ce0d7cfa6ee0650a63d45558a5121383995d9;hp=ca389394fa2a1d563097c06d34881ac0e8e42559;hpb=55065bc52795faae549abfb912aacc622dd63876;p=~andy%2Flinux diff --git a/mm/filemap.c b/mm/filemap.c index ca389394fa2..83a45d35468 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -298,7 +298,7 @@ int filemap_fdatawait_range(struct address_space *mapping, loff_t start_byte, continue; wait_on_page_writeback(page); - if (PageError(page)) + if (TestClearPageError(page)) ret = -EIO; } pagevec_release(&pvec); @@ -837,9 +837,6 @@ repeat: if (radix_tree_deref_retry(page)) goto restart; - if (page->mapping == NULL || page->index != index) - break; - if (!page_cache_get_speculative(page)) goto repeat; @@ -849,6 +846,16 @@ repeat: goto repeat; } + /* + * must check mapping and index after taking the ref. + * otherwise we can get both false positives and false + * negatives, which is just confusing to the caller. + */ + if (page->mapping == NULL || page->index != index) { + page_cache_release(page); + break; + } + pages[ret] = page; ret++; index++; @@ -2220,7 +2227,7 @@ struct page *grab_cache_page_write_begin(struct address_space *mapping, gfp_notmask = __GFP_FS; repeat: page = find_lock_page(mapping, index); - if (likely(page)) + if (page) return page; page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask);