Currently we were reporting errors from IO completion in ext4_end_bio(). Additionally we were setting page error bit in ext4_finish_bio() and also unnecessarily calling mapping_set_error() again. Move all the error reporting from IO completion to ext4_finish_bio(). Signed-off-by: Jan Kara <jack@xxxxxxx> --- fs/ext4/page-io.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 1a82138ba739..61e4e25b8e95 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -62,6 +62,7 @@ static void ext4_finish_bio(struct bio *bio) { int i; struct bio_vec *bvec; + bool error_reported = false; bio_for_each_segment_all(bvec, bio, i) { struct page *page = bvec->bv_page; @@ -87,7 +88,19 @@ static void ext4_finish_bio(struct bio *bio) if (bio->bi_error) { SetPageError(page); - mapping_set_error(page->mapping, -EIO); + if (!error_reported) { + struct inode *inode = page->mapping->host; + sector_t bi_sector = bio->bi_iter.bi_sector; + + ext4_warning(inode->i_sb, + "I/O error %d writing to inode %lu " + "(starting block %llu)", + bio->bi_error, inode->i_ino, + (unsigned long long) + bi_sector >> (inode->i_blkbits - 9)); + mapping_set_error(page->mapping, bio->bi_error); + error_reported = true; + } } bh = head = page_buffers(page); /* @@ -296,7 +309,6 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end) static void ext4_end_bio(struct bio *bio) { ext4_io_end_t *io_end = bio->bi_private; - sector_t bi_sector = bio->bi_iter.bi_sector; char b[BDEVNAME_SIZE]; if (WARN_ONCE(!io_end, "io_end is NULL: %s: sector %Lu len %u err %d\n", @@ -310,19 +322,6 @@ static void ext4_end_bio(struct bio *bio) } bio->bi_end_io = NULL; - if (bio->bi_error) { - struct inode *inode = io_end->inode; - - ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu " - "(offset %llu size %ld starting block %llu)", - bio->bi_error, inode->i_ino, - (unsigned long long) io_end->offset, - (long) io_end->size, - (unsigned long long) - bi_sector >> (inode->i_blkbits - 9)); - mapping_set_error(inode->i_mapping, bio->bi_error); - } - if (io_end->flag & EXT4_IO_END_UNWRITTEN) { /* * Link bio into list hanging from io_end. We have to do it -- 2.12.0