From b79f10eefd4bc450a595b93c75e3a9d159ac3885 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Apr 2017 09:40:36 +0200 Subject: dm mpath: merge do_end_io into multipath_end_io This simplifies the I/O completion path a bit. Signed-off-by: Christoph Hellwig Signed-off-by: Mike Snitzer --- drivers/md/dm-mpath.c | 51 +++++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 34 deletions(-) (limited to 'drivers/md') diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 52cd3f1608b3..8b394a08d427 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1464,12 +1464,12 @@ static int noretry_error(int error) return 0; } -/* - * end_io handling - */ -static int do_end_io(struct multipath *m, struct request *clone, - int error, struct dm_mpath_io *mpio) +static int multipath_end_io(struct dm_target *ti, struct request *clone, + int error, union map_info *map_context) { + struct dm_mpath_io *mpio = get_mpio(map_context); + struct pgpath *pgpath = mpio->pgpath; + /* * We don't queue any clone request inside the multipath target * during end I/O handling, since those clone requests don't have @@ -1481,44 +1481,27 @@ static int do_end_io(struct multipath *m, struct request *clone, * request into dm core, which will remake a clone request and * clone bios for it and resubmit it later. */ - int r = DM_ENDIO_REQUEUE; - - if (!error) - return 0; /* I/O complete */ + if (error && !noretry_error(error)) { + struct multipath *m = ti->private; - if (noretry_error(error)) - return error; - - if (mpio->pgpath) - fail_path(mpio->pgpath); + error = DM_ENDIO_REQUEUE; - if (atomic_read(&m->nr_valid_paths) == 0 && - !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) - r = dm_report_EIO(m); - - return r; -} - -static int multipath_end_io(struct dm_target *ti, struct request *clone, - int error, union map_info *map_context) -{ - struct multipath *m = ti->private; - struct dm_mpath_io *mpio = get_mpio(map_context); - struct pgpath *pgpath; - struct path_selector *ps; - int r; + if (pgpath) + fail_path(pgpath); - BUG_ON(!mpio); + if (atomic_read(&m->nr_valid_paths) == 0 && + !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) + error = dm_report_EIO(m); + } - r = do_end_io(m, clone, error, mpio); - pgpath = mpio->pgpath; if (pgpath) { - ps = &pgpath->pg->ps; + struct path_selector *ps = &pgpath->pg->ps; + if (ps->type->end_io) ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); } - return r; + return error; } static int do_end_io_bio(struct multipath *m, struct bio *clone, -- cgit v1.2.3-58-ga151 From 7ed8578a96ad98231d8bf6388f776e034673e18a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Apr 2017 09:40:37 +0200 Subject: dm rq: change ->rq_end_io calling conventions Instead of returning either a DM_ENDIO_* constant or an error code, add a new DM_ENDIO_DONE value that means keep errno as is. This allows us to easily keep the existing error code in case where we can't push back, and it also preparares for the new block level status codes with strict type checking. Signed-off-by: Christoph Hellwig Signed-off-by: Mike Snitzer --- drivers/md/dm-mpath.c | 13 +++++++++---- drivers/md/dm-rq.c | 17 ++++++++++------- include/linux/device-mapper.h | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers/md') 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 -- cgit v1.2.3-58-ga151 From 412445acb6cad4cef026daae37c4765fb9942c60 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Apr 2017 09:40:39 +0200 Subject: dm: introduce a new DM_MAPIO_KILL return value This untangles the DM_MAPIO_* values returned from ->clone_and_map_rq from the error codes used by the block layer. Signed-off-by: Christoph Hellwig Signed-off-by: Mike Snitzer --- drivers/md/dm-rq.c | 12 +++++------- drivers/md/dm-target.c | 2 +- include/linux/device-mapper.h | 1 + 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/md') diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 920e854caba9..a48130b90157 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -504,14 +504,12 @@ static int map_request(struct dm_rq_target_io *tio) /* The target wants to requeue the I/O after a delay */ dm_requeue_original_request(tio, true); break; - default: - if (r > 0) { - DMWARN("unimplemented target map return value: %d", r); - BUG(); - } - + case DM_MAPIO_KILL: /* The target wants to complete the I/O */ - dm_kill_unmapped_request(rq, r); + dm_kill_unmapped_request(rq, -EIO); + default: + DMWARN("unimplemented target map return value: %d", r); + BUG(); } return r; diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c index 43d3445b121d..6264ff00dcf0 100644 --- a/drivers/md/dm-target.c +++ b/drivers/md/dm-target.c @@ -135,7 +135,7 @@ static int io_err_clone_and_map_rq(struct dm_target *ti, struct request *rq, union map_info *map_context, struct request **clone) { - return -EIO; + return DM_MAPIO_KILL; } static void io_err_release_clone_rq(struct request *clone) diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 5a02fc0ff311..78ad0624cdae 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -604,6 +604,7 @@ extern struct ratelimit_state dm_ratelimit_state; #define DM_MAPIO_REMAPPED 1 #define DM_MAPIO_REQUEUE DM_ENDIO_REQUEUE #define DM_MAPIO_DELAY_REQUEUE 3 +#define DM_MAPIO_KILL 4 #define dm_sector_div64(x, y)( \ { \ -- cgit v1.2.3-58-ga151