diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 744b80c608e5..59da573cf994 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1102,6 +1102,7 @@ static void crypt_endio(struct bio *clone) struct dm_crypt_io *io = clone->bi_private; struct crypt_config *cc = io->cc; unsigned rw = bio_data_dir(clone); + int error; /* * free the processed pages @@ -1109,15 +1110,16 @@ static void crypt_endio(struct bio *clone) if (rw == WRITE) crypt_free_buffer_pages(cc, clone); + error = clone->bi_error; bio_put(clone); - if (rw == READ && !clone->bi_error) { + if (rw == READ && !error) { kcryptd_queue_crypt(io); return; } - if (unlikely(clone->bi_error)) - io->error = clone->bi_error; + if (unlikely(error)) + io->error = error; crypt_dec_pending(io); } diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index efc6659f9d6a..c84714f70378 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -138,6 +138,7 @@ static void endio(struct bio *bio) { struct io *io; unsigned region; + int error; if (bio->bi_error && bio_data_dir(bio) == READ) zero_fill_bio(bio); @@ -147,9 +148,10 @@ static void endio(struct bio *bio) */ retrieve_io_and_region_from_bio(bio, &io, ®ion); + error = bio->bi_error; bio_put(bio); - dec_count(io, region, bio->bi_error); + dec_count(io, region, error); } /*----------------------------------------------------------------- diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e3d48775c9df..085db931aafc 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -4756,6 +4756,7 @@ static void raid5_align_endio(struct bio *bi) struct mddev *mddev; struct r5conf *conf; struct md_rdev *rdev; + int error = bi->bi_error; bio_put(bi); @@ -4766,7 +4767,7 @@ static void raid5_align_endio(struct bio *bi) rdev_dec_pending(rdev, conf->mddev); - if (!bi->bi_error) { + if (!error) { trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev), raid_bi, 0); bio_endio(raid_bi); diff --git a/fs/direct-io.c b/fs/direct-io.c index e1639c8c14d5..818c647f36d3 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -459,12 +459,14 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) { struct bio_vec *bvec; unsigned i; + int err; if (bio->bi_error) dio->io_error = -EIO; if (dio->is_async && dio->rw == READ) { bio_check_pages_dirty(bio); /* transfers ownership */ + err = bio->bi_error; } else { bio_for_each_segment_all(bvec, bio, i) { struct page *page = bvec->bv_page; @@ -473,9 +475,10 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio) set_page_dirty_lock(page); page_cache_release(page); } + err = bio->bi_error; bio_put(bio); } - return bio->bi_error; + return err; } /*