Move the put_page on error from filemap_readpage into the callers. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- mm/filemap.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 96855299247c56..6089f1d9dd429f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2171,11 +2171,11 @@ static int lock_page_for_iocb(struct kiocb *iocb, struct page *page) static int filemap_readpage(struct kiocb *iocb, struct page *page) { struct file *file = iocb->ki_filp; - int error = -EAGAIN; + int error; if (iocb->ki_flags & (IOCB_NOIO | IOCB_NOWAIT)) { unlock_page(page); - goto out_put_page; + return -EAGAIN; } /* @@ -2186,12 +2186,12 @@ static int filemap_readpage(struct kiocb *iocb, struct page *page) /* Start the actual read. The read will unlock the page. */ error = file->f_mapping->a_ops->readpage(file, page); if (unlikely(error)) - goto out_put_page; + return error; if (!PageUptodate(page)) { error = lock_page_for_iocb(iocb, page); if (unlikely(error)) - goto out_put_page; + return error; if (!PageUptodate(page)) { if (page->mapping == NULL) { @@ -2199,22 +2199,16 @@ static int filemap_readpage(struct kiocb *iocb, struct page *page) * invalidate_mapping_pages got it */ unlock_page(page); - error = AOP_TRUNCATED_PAGE; - goto out_put_page; + return AOP_TRUNCATED_PAGE; } unlock_page(page); shrink_readahead_size_eio(&file->f_ra); - error = -EIO; - goto out_put_page; + return -EIO; } unlock_page(page); } return 0; - -out_put_page: - put_page(page); - return error; } static int filemap_make_page_uptodate(struct kiocb *iocb, struct iov_iter *iter, @@ -2293,7 +2287,10 @@ static int filemap_make_page_uptodate(struct kiocb *iocb, struct iov_iter *iter, /* Did somebody else fill it already? */ if (PageUptodate(page)) goto unlock_page; - return filemap_readpage(iocb, page); + error = filemap_readpage(iocb, page); + if (error) + goto put_page; + return 0; put_page: put_page(page); @@ -2315,15 +2312,15 @@ static int filemap_new_page(struct kiocb *iocb, struct iov_iter *iter, if (!page) return -ENOMEM; error = add_to_page_cache_lru(*page, mapping, index, gfp); - if (error) { - put_page(*page); - return error; - } - + if (error) + goto put_page; error = filemap_readpage(iocb, *page); if (error) - return error; + goto put_page; return filemap_make_page_uptodate(iocb, iter, *page, index, true); +put_page: + put_page(*page); + return error; } static int filemap_find_get_pages(struct kiocb *iocb, struct iov_iter *iter, -- 2.28.0