The error returned from ext4_map_blocks() was being discarded, leading to the generic -EIO being returned to userspace. Now ext4 can return more precise errors. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- fs/ext4/readpage.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c index f014c5e473a9..00a024f3a954 100644 --- a/fs/ext4/readpage.c +++ b/fs/ext4/readpage.c @@ -237,7 +237,7 @@ int ext4_mpage_readpages(struct inode *inode, sector_t blocks[MAX_BUF_PER_PAGE]; unsigned page_block; struct block_device *bdev = inode->i_sb->s_bdev; - int length; + int length, err = 0; unsigned relative_block = 0; struct ext4_map_blocks map; unsigned int nr_pages = rac ? readahead_count(rac) : 1; @@ -301,14 +301,9 @@ int ext4_mpage_readpages(struct inode *inode, map.m_lblk = block_in_file; map.m_len = last_block - block_in_file; - if (ext4_map_blocks(NULL, inode, &map, 0) < 0) { - set_error_page: - SetPageError(page); - zero_user_segment(page, 0, - PAGE_SIZE); - unlock_page(page); - goto next_page; - } + err = ext4_map_blocks(NULL, inode, &map, 0); + if (err < 0) + goto err; } if ((map.m_flags & EXT4_MAP_MAPPED) == 0) { fully_mapped = 0; @@ -395,6 +390,15 @@ int ext4_mpage_readpages(struct inode *inode, } else last_block_in_bio = blocks[blocks_per_page - 1]; goto next_page; + set_error_page: + err = -EIO; + err: + if (rac) { + SetPageError(page); + zero_user_segment(page, 0, PAGE_SIZE); + } + unlock_page(page); + goto next_page; confused: if (bio) { submit_bio(bio); @@ -410,7 +414,7 @@ int ext4_mpage_readpages(struct inode *inode, } if (bio) submit_bio(bio); - return 0; + return err; } int __init ext4_init_post_read_processing(void) -- 2.28.0