nvme-loop: retrieve iod from the cqe command_id
authorSagi Grimberg <sagi@grimberg.me>
Mon, 27 Feb 2017 16:28:25 +0000 (18:28 +0200)
committerJens Axboe <axboe@fb.com>
Tue, 4 Apr 2017 15:48:23 +0000 (09:48 -0600)
useful to validate that the we didn't mess up
the command_id.

Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/nvme/target/loop.c

index ac828af16c342a355aba4401873cafe0633f21f6..35314d96b4dbdb7415633dc8a0788c90cfc4ecad 100644 (file)
@@ -111,11 +111,20 @@ static void nvme_loop_complete_rq(struct request *req)
        blk_mq_end_request(req, error);
 }
 
+static struct blk_mq_tags *nvme_loop_tagset(struct nvme_loop_queue *queue)
+{
+       u32 queue_idx = nvme_loop_queue_idx(queue);
+
+       if (queue_idx == 0)
+               return queue->ctrl->admin_tag_set.tags[queue_idx];
+       return queue->ctrl->tag_set.tags[queue_idx - 1];
+}
+
 static void nvme_loop_queue_response(struct nvmet_req *req)
 {
-       struct nvme_loop_iod *iod =
-               container_of(req, struct nvme_loop_iod, req);
-       struct nvme_completion *cqe = &iod->rsp;
+       struct nvme_loop_queue *queue =
+               container_of(req->sq, struct nvme_loop_queue, nvme_sq);
+       struct nvme_completion *cqe = req->rsp;
 
        /*
         * AEN requests are special as they don't time out and can
@@ -123,13 +132,23 @@ static void nvme_loop_queue_response(struct nvmet_req *req)
         * aborts.  We don't even bother to allocate a struct request
         * for them but rather special case them here.
         */
-       if (unlikely(nvme_loop_queue_idx(iod->queue) == 0 &&
+       if (unlikely(nvme_loop_queue_idx(queue) == 0 &&
                        cqe->command_id >= NVME_LOOP_AQ_BLKMQ_DEPTH)) {
-               nvme_complete_async_event(&iod->queue->ctrl->ctrl, cqe->status,
+               nvme_complete_async_event(&queue->ctrl->ctrl, cqe->status,
                                &cqe->result);
        } else {
-               struct request *rq = blk_mq_rq_from_pdu(iod);
+               struct request *rq;
+               struct nvme_loop_iod *iod;
+
+               rq = blk_mq_tag_to_rq(nvme_loop_tagset(queue), cqe->command_id);
+               if (!rq) {
+                       dev_err(queue->ctrl->ctrl.device,
+                               "tag 0x%x on queue %d not found\n",
+                               cqe->command_id, nvme_loop_queue_idx(queue));
+                       return;
+               }
 
+               iod = blk_mq_rq_to_pdu(rq);
                iod->nvme_req.result = cqe->result;
                blk_mq_complete_request(rq, le16_to_cpu(cqe->status) >> 1);
        }