Stop passing pointless arguments, and return an int instead of a page struct that contains either the passed in page, an ERR_PTR or NULL and use goto labels to share common code. Also rename the function to filemap_readpage as it is a fairly generic wrapper around ->readpage that isn't really specific to generic_file_buffered_read. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- mm/filemap.c | 66 ++++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index d90614f501daa5..2e997890cc81c2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2168,59 +2168,53 @@ static int lock_page_for_iocb(struct kiocb *iocb, struct page *page) return lock_page_killable(page); } -static struct page * -generic_file_buffered_read_readpage(struct kiocb *iocb, - struct file *filp, - struct address_space *mapping, - struct page *page) +static int filemap_readpage(struct kiocb *iocb, struct page *page) { - struct file_ra_state *ra = &filp->f_ra; - int error; + struct file *file = iocb->ki_filp; + int error = -EAGAIN; if (iocb->ki_flags & (IOCB_NOIO | IOCB_NOWAIT)) { unlock_page(page); - put_page(page); - return ERR_PTR(-EAGAIN); + goto out_put_page; } /* - * A previous I/O error may have been due to temporary - * failures, eg. multipath errors. - * PG_error will be set again if readpage fails. + * A previous I/O error may have been due to temporary failures, e.g. + * multipath errors. PG_error will be set again if readpage fails. */ ClearPageError(page); /* Start the actual read. The read will unlock the page. */ - error = mapping->a_ops->readpage(filp, page); - - if (unlikely(error)) { - put_page(page); - return error != AOP_TRUNCATED_PAGE ? ERR_PTR(error) : NULL; - } + error = file->f_mapping->a_ops->readpage(file, page); + if (unlikely(error)) + goto out_put_page; if (!PageUptodate(page)) { error = lock_page_for_iocb(iocb, page); - if (unlikely(error)) { - put_page(page); - return ERR_PTR(error); - } + if (unlikely(error)) + goto out_put_page; + if (!PageUptodate(page)) { if (page->mapping == NULL) { /* * invalidate_mapping_pages got it */ unlock_page(page); - put_page(page); - return NULL; + error = AOP_TRUNCATED_PAGE; + goto out_put_page; } unlock_page(page); - shrink_readahead_size_eio(ra); - put_page(page); - return ERR_PTR(-EIO); + shrink_readahead_size_eio(&file->f_ra); + error = -EIO; + goto out_put_page; } + unlock_page(page); } + return 0; - return page; +out_put_page: + put_page(page); + return error; } static struct page * @@ -2291,7 +2285,13 @@ generic_file_buffered_read_pagenotuptodate(struct kiocb *iocb, return page; } - return generic_file_buffered_read_readpage(iocb, filp, mapping, page); + error = filemap_readpage(iocb, page); + if (error) { + if (error == AOP_TRUNCATED_PAGE) + return NULL; + return ERR_PTR(error); + } + return page; } static struct page * @@ -2322,7 +2322,13 @@ generic_file_buffered_read_no_cached_page(struct kiocb *iocb, return error != -EEXIST ? ERR_PTR(error) : NULL; } - return generic_file_buffered_read_readpage(iocb, filp, mapping, page); + error = filemap_readpage(iocb, page); + if (error) { + if (error == AOP_TRUNCATED_PAGE) + return NULL; + return ERR_PTR(error); + } + return page; } static int generic_file_buffered_read_get_pages(struct kiocb *iocb, -- 2.28.0