Factor out a helper to lookup a range of contiguous pages from generic_file_buffered_read_get_pages. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- mm/filemap.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 9e1cc18afe1134..0af7ddaa0fe7ba 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2323,39 +2323,46 @@ static int filemap_new_page(struct kiocb *iocb, struct iov_iter *iter, return filemap_readpage(iocb, *page); } +static int filemap_find_get_pages(struct kiocb *iocb, struct iov_iter *iter, + struct page **pages, unsigned int nr) +{ + struct address_space *mapping = iocb->ki_filp->f_mapping; + pgoff_t index = iocb->ki_pos >> PAGE_SHIFT; + pgoff_t last_index = (iocb->ki_pos + iter->count + PAGE_SIZE - 1) >> + PAGE_SHIFT; + int nr_pages; + + nr = min_t(unsigned long, last_index - index, nr); + nr_pages = find_get_pages_contig(mapping, index, nr, pages); + if (nr_pages) + return nr_pages; + + if (iocb->ki_flags & IOCB_NOIO) + return -EAGAIN; + page_cache_sync_readahead(mapping, &iocb->ki_filp->f_ra, iocb->ki_filp, + index, last_index - index); + return find_get_pages_contig(mapping, index, nr, pages); +} + static int generic_file_buffered_read_get_pages(struct kiocb *iocb, struct iov_iter *iter, struct page **pages, unsigned int nr) { - struct file *filp = iocb->ki_filp; - struct address_space *mapping = filp->f_mapping; - struct file_ra_state *ra = &filp->f_ra; pgoff_t index = iocb->ki_pos >> PAGE_SHIFT; - pgoff_t last_index = (iocb->ki_pos + iter->count + PAGE_SIZE-1) >> PAGE_SHIFT; int i, j, nr_got, err = 0; - nr = min_t(unsigned long, last_index - index, nr); find_page: if (fatal_signal_pending(current)) return -EINTR; - nr_got = find_get_pages_contig(mapping, index, nr, pages); - if (nr_got) - goto got_pages; - - if (iocb->ki_flags & IOCB_NOIO) - return -EAGAIN; - - page_cache_sync_readahead(mapping, ra, filp, index, last_index - index); + nr_got = filemap_find_get_pages(iocb, iter, pages, nr); + if (!nr_got) { + err = filemap_new_page(iocb, iter, &pages[0]); + if (!err) + nr_got = 1; + } - nr_got = find_get_pages_contig(mapping, index, nr, pages); - if (nr_got) - goto got_pages; - err = filemap_new_page(iocb, iter, &pages[0]); - if (!err) - nr_got = 1; -got_pages: for (i = 0; i < nr_got; i++) { err = filemap_make_page_uptodate(iocb, iter, pages[i], index + i, i == 0); -- 2.28.0