| From a2a16ff244e39f8dd29bc682bddc43d2368c8331 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 11 Apr 2022 08:05:27 +0200 |
| Subject: nvme: add a quirk to disable namespace identifiers |
| |
| From: Christoph Hellwig <hch@lst.de> |
| |
| [ Upstream commit 00ff400e6deee00f7b15e200205b2708b63b8cf6 ] |
| |
| Add a quirk to disable using and exporting namespace identifiers for |
| controllers where they are broken beyond repair. |
| |
| The most directly visible problem with non-unique namespace identifiers |
| is that they break the /dev/disk/by-id/ links, with the link for a |
| supposedly unique identifier now pointing to one of multiple possible |
| namespaces that share the same ID, and a somewhat random selection of |
| which one actually shows up. |
| |
| Signed-off-by: Christoph Hellwig <hch@lst.de> |
| Reviewed-by: Keith Busch <kbusch@kernel.org> |
| Reviewed-by: Sagi Grimberg <sagi@grimberg.me> |
| Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/nvme/host/core.c | 24 ++++++++++++++++++------ |
| drivers/nvme/host/nvme.h | 5 +++++ |
| 2 files changed, 23 insertions(+), 6 deletions(-) |
| |
| diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c |
| index 853b9a24f744..ad4f1cfbad2e 100644 |
| --- a/drivers/nvme/host/core.c |
| +++ b/drivers/nvme/host/core.c |
| @@ -1270,6 +1270,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids, |
| warn_str, cur->nidl); |
| return -1; |
| } |
| + if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) |
| + return NVME_NIDT_EUI64_LEN; |
| memcpy(ids->eui64, data + sizeof(*cur), NVME_NIDT_EUI64_LEN); |
| return NVME_NIDT_EUI64_LEN; |
| case NVME_NIDT_NGUID: |
| @@ -1278,6 +1280,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids, |
| warn_str, cur->nidl); |
| return -1; |
| } |
| + if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) |
| + return NVME_NIDT_NGUID_LEN; |
| memcpy(ids->nguid, data + sizeof(*cur), NVME_NIDT_NGUID_LEN); |
| return NVME_NIDT_NGUID_LEN; |
| case NVME_NIDT_UUID: |
| @@ -1286,6 +1290,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids, |
| warn_str, cur->nidl); |
| return -1; |
| } |
| + if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) |
| + return NVME_NIDT_UUID_LEN; |
| uuid_copy(&ids->uuid, data + sizeof(*cur)); |
| return NVME_NIDT_UUID_LEN; |
| case NVME_NIDT_CSI: |
| @@ -1381,12 +1387,18 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, |
| if ((*id)->ncap == 0) /* namespace not allocated or attached */ |
| goto out_free_id; |
| |
| - if (ctrl->vs >= NVME_VS(1, 1, 0) && |
| - !memchr_inv(ids->eui64, 0, sizeof(ids->eui64))) |
| - memcpy(ids->eui64, (*id)->eui64, sizeof(ids->eui64)); |
| - if (ctrl->vs >= NVME_VS(1, 2, 0) && |
| - !memchr_inv(ids->nguid, 0, sizeof(ids->nguid))) |
| - memcpy(ids->nguid, (*id)->nguid, sizeof(ids->nguid)); |
| + |
| + if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) { |
| + dev_info(ctrl->device, |
| + "Ignoring bogus Namespace Identifiers\n"); |
| + } else { |
| + if (ctrl->vs >= NVME_VS(1, 1, 0) && |
| + !memchr_inv(ids->eui64, 0, sizeof(ids->eui64))) |
| + memcpy(ids->eui64, (*id)->eui64, sizeof(ids->eui64)); |
| + if (ctrl->vs >= NVME_VS(1, 2, 0) && |
| + !memchr_inv(ids->nguid, 0, sizeof(ids->nguid))) |
| + memcpy(ids->nguid, (*id)->nguid, sizeof(ids->nguid)); |
| + } |
| |
| return 0; |
| |
| diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h |
| index 5dd1dd8021ba..10e5ae3a8c0d 100644 |
| --- a/drivers/nvme/host/nvme.h |
| +++ b/drivers/nvme/host/nvme.h |
| @@ -150,6 +150,11 @@ enum nvme_quirks { |
| * encoding the generation sequence number. |
| */ |
| NVME_QUIRK_SKIP_CID_GEN = (1 << 17), |
| + |
| + /* |
| + * Reports garbage in the namespace identifiers (eui64, nguid, uuid). |
| + */ |
| + NVME_QUIRK_BOGUS_NID = (1 << 18), |
| }; |
| |
| /* |
| -- |
| 2.35.1 |
| |