summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-crypt.c8
-rw-r--r--drivers/md/dm-io.c4
-rw-r--r--drivers/md/raid5.c3
-rw-r--r--fs/direct-io.c5
4 files changed, 14 insertions, 6 deletions
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, &region);
+ 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;
}
/*