summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 01d741a0c079..c65be45a4c42 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -846,35 +846,46 @@ static void dm_end_request(struct request *clone, int error)
rq_completed(md, rw, 1);
}
-/*
- * Request completion handler for request-based dm
- */
-static void dm_softirq_done(struct request *rq)
+static void dm_done(struct request *clone, int error, bool mapped)
{
- struct request *clone = rq->completion_data;
+ int r = error;
struct dm_rq_target_io *tio = clone->end_io_data;
dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io;
- int error = tio->error;
- if (!(rq->cmd_flags & REQ_FAILED) && rq_end_io)
- error = rq_end_io(tio->ti, clone, error, &tio->info);
+ if (mapped && rq_end_io)
+ r = rq_end_io(tio->ti, clone, error, &tio->info);
- if (error <= 0)
+ if (r <= 0)
/* The target wants to complete the I/O */
- dm_end_request(clone, error);
- else if (error == DM_ENDIO_INCOMPLETE)
+ dm_end_request(clone, r);
+ else if (r == DM_ENDIO_INCOMPLETE)
/* The target will handle the I/O */
return;
- else if (error == DM_ENDIO_REQUEUE)
+ else if (r == DM_ENDIO_REQUEUE)
/* The target wants to requeue the I/O */
dm_requeue_unmapped_request(clone);
else {
- DMWARN("unimplemented target endio return value: %d", error);
+ DMWARN("unimplemented target endio return value: %d", r);
BUG();
}
}
/*
+ * Request completion handler for request-based dm
+ */
+static void dm_softirq_done(struct request *rq)
+{
+ bool mapped = true;
+ struct request *clone = rq->completion_data;
+ struct dm_rq_target_io *tio = clone->end_io_data;
+
+ if (rq->cmd_flags & REQ_FAILED)
+ mapped = false;
+
+ dm_done(clone, tio->error, mapped);
+}
+
+/*
* Complete the clone and the original request with the error status
* through softirq context.
*/