Commit 9e0ed16a authored by Sagi Grimberg's avatar Sagi Grimberg Committed by Christoph Hellwig
Browse files

nvme-fc: check if queue is ready in queue_rq



In case the queue is not LIVE (fully functional and connected at the nvmf
level), we cannot allow any commands other than connect to pass through.

Add a new queue state flag NVME_FC_Q_LIVE which is set after nvmf connect
and cleared in queue teardown.

Signed-off-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 48832f8d
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@

enum nvme_fc_queue_flags {
	NVME_FC_Q_CONNECTED = (1 << 0),
	NVME_FC_Q_LIVE = (1 << 1),
};

#define NVMEFC_QUEUE_DELAY	3		/* ms units */
@@ -1927,6 +1928,7 @@ nvme_fc_free_queue(struct nvme_fc_queue *queue)
	if (!test_and_clear_bit(NVME_FC_Q_CONNECTED, &queue->flags))
		return;

	clear_bit(NVME_FC_Q_LIVE, &queue->flags);
	/*
	 * Current implementation never disconnects a single queue.
	 * It always terminates a whole association. So there is never
@@ -1934,7 +1936,6 @@ nvme_fc_free_queue(struct nvme_fc_queue *queue)
	 */

	queue->connection_id = 0;
	clear_bit(NVME_FC_Q_CONNECTED, &queue->flags);
}

static void
@@ -2013,6 +2014,8 @@ nvme_fc_connect_io_queues(struct nvme_fc_ctrl *ctrl, u16 qsize)
		ret = nvmf_connect_io_queue(&ctrl->ctrl, i);
		if (ret)
			break;

		set_bit(NVME_FC_Q_LIVE, &ctrl->queues[i].flags);
	}

	return ret;
@@ -2320,6 +2323,14 @@ busy:
	return BLK_STS_RESOURCE;
}

static inline blk_status_t nvme_fc_is_ready(struct nvme_fc_queue *queue,
		struct request *rq)
{
	if (unlikely(!test_bit(NVME_FC_Q_LIVE, &queue->flags)))
		return nvmf_check_init_req(&queue->ctrl->ctrl, rq);
	return BLK_STS_OK;
}

static blk_status_t
nvme_fc_queue_rq(struct blk_mq_hw_ctx *hctx,
			const struct blk_mq_queue_data *bd)
@@ -2335,6 +2346,10 @@ nvme_fc_queue_rq(struct blk_mq_hw_ctx *hctx,
	u32 data_len;
	blk_status_t ret;

	ret = nvme_fc_is_ready(queue, rq);
	if (unlikely(ret))
		return ret;

	ret = nvme_setup_cmd(ns, rq, sqe);
	if (ret)
		return ret;
@@ -2727,6 +2742,8 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl)
	if (ret)
		goto out_disconnect_admin_queue;

	set_bit(NVME_FC_Q_LIVE, &ctrl->queues[0].flags);

	/*
	 * Check controller capabilities
	 *