A synchronous readpage lets us report the actual errno instead of ineffectively setting PageError. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- fs/mpage.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/fs/mpage.c b/fs/mpage.c index 830e6cc2a9e7..88aba79a1861 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -406,11 +406,30 @@ int mpage_readpage(struct page *page, get_block_t get_block) .nr_pages = 1, .get_block = get_block, }; + int err; args.bio = do_mpage_readpage(&args); - if (args.bio) - mpage_bio_submit(REQ_OP_READ, 0, args.bio); - return 0; + /* + * XXX: We can't tell the difference between "fell back to + * block_read_full_page" and "this was a hole". If we could, + * we'd avoid unlocking the page in do_mpage_readpage() and + * return AOP_UPDATED_PAGE here. + */ + if (!args.bio) + return 0; + bio_set_op_attrs(args.bio, REQ_OP_READ, 0); + guard_bio_eod(args.bio); + err = submit_bio_killable(args.bio, mpage_end_io); + if (unlikely(err)) + goto err; + + SetPageUptodate(page); + return AOP_UPDATED_PAGE; + +err: + if (err != -ERESTARTSYS) + unlock_page(page); + return err; } EXPORT_SYMBOL(mpage_readpage); -- 2.28.0