Since .initialize_rq_fn() is called from inside blk_get_request()
that function is only called for pass-through requests but not for
filesystem requests. There is agreement in the SCSI community that
the jiffies_at_alloc and retries members of struct scsi_cmnd
should be initialized at request allocation time instead of when
preparing a request. This will allow to preserve the value of these
members when requeuing a request. Since the block layer does not
yet allow block drivers to initialize filesystem requests without
overriding request_queue.make_request_fn, move the
.initialize_rq_fn() calls from blk_get_request() into
blk_mq_rq_ctx_init() and blk_rq_init().

See also https://www.spinics.net/lists/linux-scsi/msg108934.html.

Signed-off-by: Bart Van Assche <bart.vanass...@wdc.com>
Cc: Christoph Hellwig <h...@lst.de>
Cc: Martin K. Petersen <martin.peter...@oracle.com>
Cc: Hannes Reinecke <h...@suse.com>
---
 block/blk-core.c | 20 +++++++-------------
 block/blk-mq.c   |  4 ++++
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 78a46794053e..463aa0ee36ce 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -126,6 +126,9 @@ void blk_rq_init(struct request_queue *q, struct request 
*rq)
        rq->start_time = jiffies;
        set_start_time_ns(rq);
        rq->part = NULL;
+
+       if (q && q->initialize_rq_fn)
+               q->initialize_rq_fn(rq);
 }
 EXPORT_SYMBOL(blk_rq_init);
 
@@ -1420,21 +1423,12 @@ static struct request *blk_old_get_request(struct 
request_queue *q,
 struct request *blk_get_request(struct request_queue *q, unsigned int op,
                                gfp_t gfp_mask)
 {
-       struct request *req;
-
-       if (q->mq_ops) {
-               req = blk_mq_alloc_request(q, op,
+       if (q->mq_ops)
+               return blk_mq_alloc_request(q, op,
                        (gfp_mask & __GFP_DIRECT_RECLAIM) ?
                                0 : BLK_MQ_REQ_NOWAIT);
-               if (!IS_ERR(req) && q->mq_ops->initialize_rq_fn)
-                       q->mq_ops->initialize_rq_fn(req);
-       } else {
-               req = blk_old_get_request(q, op, gfp_mask);
-               if (!IS_ERR(req) && q->initialize_rq_fn)
-                       q->initialize_rq_fn(req);
-       }
-
-       return req;
+       else
+               return blk_old_get_request(q, op, gfp_mask);
 }
 EXPORT_SYMBOL(blk_get_request);
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 21f2cff217ce..fdb33f8a2860 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -273,6 +273,7 @@ EXPORT_SYMBOL(blk_mq_can_queue);
 static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
                unsigned int tag, unsigned int op)
 {
+       struct request_queue *q = data->q;
        struct blk_mq_tags *tags = blk_mq_tags_from_data(data);
        struct request *rq = tags->static_rqs[tag];
 
@@ -325,6 +326,9 @@ static struct request *blk_mq_rq_ctx_init(struct 
blk_mq_alloc_data *data,
        rq->end_io_data = NULL;
        rq->next_rq = NULL;
 
+       if (q->mq_ops->initialize_rq_fn)
+               q->mq_ops->initialize_rq_fn(rq);
+
        data->ctx->rq_dispatched[op_is_sync(op)]++;
        return rq;
 }
-- 
2.14.1

Reply via email to