summaryrefslogtreecommitdiffstats
path: root/drivers/nvme/host/fabrics.h
diff options
context:
space:
mode:
authorSagi Grimberg2017-10-24 14:25:20 +0200
committerChristoph Hellwig2017-11-20 08:28:31 +0100
commit48832f8d58cfedb2f9bee11bbfbb657efb42e7e7 (patch)
tree30360bde8edf83b16502dc7d832bb5aa586add4b /drivers/nvme/host/fabrics.h
parentblktrace: Use blk_trace_bio_get_cgid inside blk_add_trace_bio (diff)
downloadkernel-qcow2-linux-48832f8d58cfedb2f9bee11bbfbb657efb42e7e7.tar.gz
kernel-qcow2-linux-48832f8d58cfedb2f9bee11bbfbb657efb42e7e7.tar.xz
kernel-qcow2-linux-48832f8d58cfedb2f9bee11bbfbb657efb42e7e7.zip
nvme-fabrics: introduce init command check for a queue that is not alive
When the fabrics queue is not alive and fully functional, no commands should be allowed to pass but connect (which moves the queue to a fully functional state). Any other command should be failed, with either temporary status BLK_STS_RESOUCE or permanent status BLK_STS_IOERR. This is shared across all fabrics, hence move the check to fabrics library. Signed-off-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/nvme/host/fabrics.h')
-rw-r--r--drivers/nvme/host/fabrics.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h
index 42232e731f19..9ba614953607 100644
--- a/drivers/nvme/host/fabrics.h
+++ b/drivers/nvme/host/fabrics.h
@@ -156,4 +156,34 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts);
int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size);
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl);
+static inline blk_status_t nvmf_check_init_req(struct nvme_ctrl *ctrl,
+ struct request *rq)
+{
+ struct nvme_command *cmd = nvme_req(rq)->cmd;
+
+ /*
+ * We cannot accept any other command until the connect command has
+ * completed, so only allow connect to pass.
+ */
+ if (!blk_rq_is_passthrough(rq) ||
+ cmd->common.opcode != nvme_fabrics_command ||
+ cmd->fabrics.fctype != nvme_fabrics_type_connect) {
+ /*
+ * Reconnecting state means transport disruption, which can take
+ * a long time and even might fail permanently, fail fast to
+ * give upper layers a chance to failover.
+ * Deleting state means that the ctrl will never accept commands
+ * again, fail it permanently.
+ */
+ if (ctrl->state == NVME_CTRL_RECONNECTING ||
+ ctrl->state == NVME_CTRL_DELETING) {
+ nvme_req(rq)->status = NVME_SC_ABORT_REQ;
+ return BLK_STS_IOERR;
+ }
+ return BLK_STS_RESOURCE; /* try again later */
+ }
+
+ return BLK_STS_OK;
+}
+
#endif /* _NVME_FABRICS_H */