diff options
author | Damien Le Moal <damien.lemoal@opensource.wdc.com> | 2023-03-15 13:59:38 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-05-11 17:03:22 +0300 |
commit | 1e4f23c61feb0a35d436a86c66b4377557bd8733 (patch) | |
tree | eedecc94a85ce88e36b224436f73da7b94c6fb5e /drivers/nvme/target | |
parent | fd95ae3bb8a6b427bd1d4fd1cda64c535eff0a67 (diff) | |
download | linux-1e4f23c61feb0a35d436a86c66b4377557bd8733.tar.xz |
nvmet: fix I/O Command Set specific Identify Controller
[ Upstream commit a5a6ab0950b46ab1ef4a5c83c80234018b81b38a ]
For an identify command with cns set to NVME_ID_CNS_CS_CTRL, the NVMe
2.0 specification states that:
If the I/O Command Set specified by the CSI field does not have an
Identify Controller data structure, then the controller shall return
a zero filled data structure. If the host requests a data structure for
an I/O Command Set that the controller does not support, the controller
shall abort the command with a status code of Invalid Field in Command.
However, the current implementation of this identify command in
nvmet_execute_identify() only handles the ZNS command set, returning an
error for the NVM command set, which is not compliant with the
specifications as we do support this command set.
Fix this by:
1) Renaming nvmet_execute_identify_cns_cs_ctrl() to
nvmet_execute_identify_ctrl_zns() to continue handling the
ZNS command set as is.
2) Introduce a nvmet_execute_identify_ctrl_ns() helper to handle the
NVM command set, returning a zero filled nvme_id_ctrl_nvm data
structure.
3) Modify nvmet_execute_identify() to call these helpers based on
the csi specified, returning an error for unsupported command sets.
Fixes: aaf2e048af27 ("nvmet: add ZBD over ZNS backend support")
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Tested-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/nvme/target')
-rw-r--r-- | drivers/nvme/target/admin-cmd.c | 22 | ||||
-rw-r--r-- | drivers/nvme/target/nvmet.h | 2 | ||||
-rw-r--r-- | drivers/nvme/target/zns.c | 2 |
3 files changed, 18 insertions, 8 deletions
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index d414269756c8..31d35279b37a 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -686,6 +686,13 @@ static bool nvmet_handle_identify_desclist(struct nvmet_req *req) } } +static void nvmet_execute_identify_ctrl_nvm(struct nvmet_req *req) +{ + /* Not supported: return zeroes */ + nvmet_req_complete(req, + nvmet_zero_sgl(req, 0, sizeof(struct nvme_id_ctrl_nvm))); +} + static void nvmet_execute_identify(struct nvmet_req *req) { if (!nvmet_check_transfer_len(req, NVME_IDENTIFY_DATA_SIZE)) @@ -709,13 +716,16 @@ static void nvmet_execute_identify(struct nvmet_req *req) nvmet_execute_identify_ctrl(req); return; case NVME_ID_CNS_CS_CTRL: - if (IS_ENABLED(CONFIG_BLK_DEV_ZONED)) { - switch (req->cmd->identify.csi) { - case NVME_CSI_ZNS: - return nvmet_execute_identify_cns_cs_ctrl(req); - default: - break; + switch (req->cmd->identify.csi) { + case NVME_CSI_NVM: + nvmet_execute_identify_ctrl_nvm(req); + return; + case NVME_CSI_ZNS: + if (IS_ENABLED(CONFIG_BLK_DEV_ZONED)) { + nvmet_execute_identify_ctrl_zns(req); + return; } + break; } break; case NVME_ID_CNS_NS_ACTIVE_LIST: diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index bda1c1f71f39..273cca49a040 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -578,7 +578,7 @@ bool nvmet_ns_revalidate(struct nvmet_ns *ns); u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts); bool nvmet_bdev_zns_enable(struct nvmet_ns *ns); -void nvmet_execute_identify_cns_cs_ctrl(struct nvmet_req *req); +void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req); void nvmet_execute_identify_cns_cs_ns(struct nvmet_req *req); void nvmet_bdev_execute_zone_mgmt_recv(struct nvmet_req *req); void nvmet_bdev_execute_zone_mgmt_send(struct nvmet_req *req); diff --git a/drivers/nvme/target/zns.c b/drivers/nvme/target/zns.c index 017c13f8bef1..d93ee4ae1945 100644 --- a/drivers/nvme/target/zns.c +++ b/drivers/nvme/target/zns.c @@ -70,7 +70,7 @@ bool nvmet_bdev_zns_enable(struct nvmet_ns *ns) return true; } -void nvmet_execute_identify_cns_cs_ctrl(struct nvmet_req *req) +void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req) { u8 zasl = req->sq->ctrl->subsys->zasl; struct nvmet_ctrl *ctrl = req->sq->ctrl; |