[PATCH v2 2/6] blk-mq: introduce prepare_flush_rq_fn callback and its pair

From: Ming Lei
Date: Sat Aug 30 2014 - 12:09:42 EST


Currently pdu of the flush rq is simlpy copied from another rq,
it isn't enough to initialize pointer field well, so introduce
these two callbacks for driver to handle the case easily.

Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx>
---
block/blk-flush.c | 4 ++++
block/blk-mq.c | 12 ++++++++++--
include/linux/blk-mq.h | 12 ++++++++++++
3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/block/blk-flush.c b/block/blk-flush.c
index 3cb5e9e..cd36596 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -225,6 +225,10 @@ static void flush_end_io(struct request *flush_rq, int error)

if (q->mq_ops) {
spin_lock_irqsave(&q->mq_flush_lock, flags);
+ if (q->mq_ops->unprepare_flush_rq)
+ q->mq_ops->unprepare_flush_rq(
+ q->tag_set->driver_data,
+ q, q->flush_rq);
q->flush_rq->tag = -1;
}

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 3ad7524..4a610d2 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -291,11 +291,19 @@ void blk_mq_clone_flush_request(struct request *flush_rq,
{
struct blk_mq_hw_ctx *hctx =
orig_rq->q->mq_ops->map_queue(orig_rq->q, orig_rq->mq_ctx->cpu);
+ int ret = 0;

flush_rq->mq_ctx = orig_rq->mq_ctx;
flush_rq->tag = orig_rq->tag;
- memcpy(blk_mq_rq_to_pdu(flush_rq), blk_mq_rq_to_pdu(orig_rq),
- hctx->cmd_size);
+
+ if (orig_rq->q->mq_ops->prepare_flush_rq)
+ ret = orig_rq->q->mq_ops->prepare_flush_rq(
+ orig_rq->q->tag_set->driver_data,
+ orig_rq->q, flush_rq, orig_rq);
+ else
+ memcpy(blk_mq_rq_to_pdu(flush_rq),
+ blk_mq_rq_to_pdu(orig_rq), hctx->cmd_size);
+ WARN_ON(ret);
}

inline void __blk_mq_end_io(struct request *rq, int error)
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index c6b2bfa..8935f34 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -85,6 +85,10 @@ typedef int (init_request_fn)(void *, struct request *, unsigned int,
unsigned int, unsigned int);
typedef void (exit_request_fn)(void *, struct request *, unsigned int,
unsigned int);
+typedef int (prepare_flush_rq_fn)(void *, struct request_queue *,
+ struct request *, const struct request *);
+typedef void (unprepare_flush_rq_fn)(void *, struct request_queue *,
+ struct request *);

struct blk_mq_ops {
/*
@@ -119,6 +123,14 @@ struct blk_mq_ops {
*/
init_request_fn *init_request;
exit_request_fn *exit_request;
+
+ /*
+ * Called after flush request cloned by the block layer to allow
+ * the driver to set up driver specific data, since simple memcpy
+ * may not initialize flush req well.
+ */
+ prepare_flush_rq_fn *prepare_flush_rq;
+ unprepare_flush_rq_fn *unprepare_flush_rq;
};

enum {
--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/