@@ -2285,26 +2285,20 @@ static struct page *filemap_update_page(struct kiocb *iocb, struct file *filp,
return NULL;
}
-static struct page *filemap_create_page(struct kiocb *iocb,
- struct iov_iter *iter)
+static struct page *filemap_create_page(struct file *file,
+ struct address_space *mapping, pgoff_t index)
{
- struct file *filp = iocb->ki_filp;
- struct address_space *mapping = filp->f_mapping;
- pgoff_t index = iocb->ki_pos >> PAGE_SHIFT;
struct page *page;
int error;
- if (iocb->ki_flags & (IOCB_NOIO | IOCB_NOWAIT | IOCB_WAITQ))
- return ERR_PTR(-EAGAIN);
-
page = page_cache_alloc(mapping);
if (!page)
return ERR_PTR(-ENOMEM);
error = add_to_page_cache_lru(page, mapping, index,
- mapping_gfp_constraint(mapping, GFP_KERNEL));
+ mapping_gfp_constraint(mapping, GFP_KERNEL));
if (!error)
- error = filemap_read_page(iocb->ki_filp, mapping, page);
+ error = filemap_read_page(file, mapping, page);
if (!error)
return page;
put_page(page);
@@ -2338,13 +2332,17 @@ static int filemap_get_pages(struct kiocb *iocb, struct iov_iter *iter,
page_cache_sync_readahead(mapping, ra, filp, index, last_index - index);
nr_got = mapping_get_read_thps(mapping, index, nr, pages);
- if (nr_got)
- goto got_pages;
-
- pages[0] = filemap_create_page(iocb, iter);
- err = PTR_ERR_OR_ZERO(pages[0]);
- if (!IS_ERR_OR_NULL(pages[0]))
- nr_got = 1;
+ if (!nr_got) {
+ if (iocb->ki_flags & (IOCB_NOWAIT | IOCB_WAITQ))
+ return -EAGAIN;
+ pages[0] = filemap_create_page(filp, mapping,
+ iocb->ki_pos >> PAGE_SHIFT);
+ if (!pages[0])
+ goto find_page;
+ if (IS_ERR(pages[0]))
+ return PTR_ERR(pages[0]);
+ return 1;
+ }
got_pages:
if (nr_got > 0) {
struct page *page = pages[nr_got - 1];
filemap_create_page() doesn't need the iocb or the iter. It just needs the file and the index. Move the iocb flag checks to the caller. We can skip checking GFP_NOIO as that's checked a few lines earlier. There's no need to fall through to filemap_update_page() -- if filemap_create_page couldn't update it, filemap_update_page will not be able to. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> --- mm/filemap.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-)