diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 8b394a08d427..926a6bcb32c8 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1469,6 +1469,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, { struct dm_mpath_io *mpio = get_mpio(map_context); struct pgpath *pgpath = mpio->pgpath; + int r = DM_ENDIO_DONE; /* * We don't queue any clone request inside the multipath target @@ -1484,14 +1485,18 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, if (error && !noretry_error(error)) { struct multipath *m = ti->private; - error = DM_ENDIO_REQUEUE; + r = DM_ENDIO_REQUEUE; if (pgpath) fail_path(pgpath); if (atomic_read(&m->nr_valid_paths) == 0 && - !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) - error = dm_report_EIO(m); + !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { + if (error == -EIO) + error = dm_report_EIO(m); + /* complete with the original error */ + r = DM_ENDIO_DONE; + } } if (pgpath) { @@ -1501,7 +1506,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); } - return error; + return r; } static int do_end_io_bio(struct multipath *m, struct bio *clone, diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index d445b712970b..920e854caba9 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -287,7 +287,7 @@ static void dm_requeue_original_request(struct dm_rq_target_io *tio, bool delay_ static void dm_done(struct request *clone, int error, bool mapped) { - int r = error; + int r = DM_ENDIO_DONE; struct dm_rq_target_io *tio = clone->end_io_data; dm_request_endio_fn rq_end_io = NULL; @@ -298,7 +298,7 @@ static void dm_done(struct request *clone, int error, bool mapped) r = rq_end_io(tio->ti, clone, error, &tio->info); } - if (unlikely(r == -EREMOTEIO)) { + if (unlikely(error == -EREMOTEIO)) { if (req_op(clone) == REQ_OP_WRITE_SAME && !clone->q->limits.max_write_same_sectors) disable_write_same(tio->md); @@ -307,16 +307,19 @@ static void dm_done(struct request *clone, int error, bool mapped) disable_write_zeroes(tio->md); } - if (r <= 0) + switch (r) { + case DM_ENDIO_DONE: /* The target wants to complete the I/O */ - dm_end_request(clone, r); - else if (r == DM_ENDIO_INCOMPLETE) + dm_end_request(clone, error); + break; + case DM_ENDIO_INCOMPLETE: /* The target will handle the I/O */ return; - else if (r == DM_ENDIO_REQUEUE) + case DM_ENDIO_REQUEUE: /* The target wants to requeue the I/O */ dm_requeue_original_request(tio, false); - else { + break; + default: DMWARN("unimplemented target endio return value: %d", r); BUG(); } diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 925b63cdef52..5a02fc0ff311 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -593,6 +593,7 @@ extern struct ratelimit_state dm_ratelimit_state; /* * Definitions of return values from target end_io function. */ +#define DM_ENDIO_DONE 0 #define DM_ENDIO_INCOMPLETE 1 #define DM_ENDIO_REQUEUE 2