return error;
}
-static struct page *
-generic_file_buffered_read_no_cached_page(struct kiocb *iocb,
- struct iov_iter *iter)
+static int filemap_new_page(struct kiocb *iocb, struct iov_iter *iter,
+ struct page **page)
{
- struct file *filp = iocb->ki_filp;
- struct address_space *mapping = filp->f_mapping;
+ struct address_space *mapping = iocb->ki_filp->f_mapping;
+ gfp_t gfp = mapping_gfp_constraint(mapping, GFP_KERNEL);
pgoff_t index = iocb->ki_pos >> PAGE_SHIFT;
- struct page *page;
int error;
if (iocb->ki_flags & IOCB_NOIO)
- return ERR_PTR(-EAGAIN);
+ return -EAGAIN;
- /*
- * Ok, it wasn't cached, so we need to create a new
- * page..
- */
- page = page_cache_alloc(mapping);
+ *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));
+ return -ENOMEM;
+ error = add_to_page_cache_lru(*page, mapping, index, gfp);
if (error) {
- put_page(page);
- return error != -EEXIST ? ERR_PTR(error) : NULL;
+ put_page(*page);
+ return error;
}
- error = filemap_readpage(iocb, page);
- if (error) {
- if (error == AOP_TRUNCATED_PAGE)
- return NULL;
- return ERR_PTR(error);
- }
- return page;
+ return filemap_readpage(iocb, *page);
}
static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
nr_got = find_get_pages_contig(mapping, index, nr, pages);
if (nr_got)
goto got_pages;
-
- pages[0] = generic_file_buffered_read_no_cached_page(iocb, iter);
- err = PTR_ERR_OR_ZERO(pages[0]);
- if (!IS_ERR_OR_NULL(pages[0]))
+ 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);
if (err) {
- if (err == AOP_TRUNCATED_PAGE)
- err = 0;
for (j = i + 1; j < nr_got; j++)
put_page(pages[j]);
nr_got = i;
if (likely(nr_got))
return nr_got;
- if (err)
- return err;
- /*
- * No pages and no error means we raced and should retry:
- */
- goto find_page;
+ if (err == -EEXIST || err == AOP_TRUNCATED_PAGE)
+ goto find_page;
+ return err;
}
/**