Commit 00ff400e authored by Christoph Hellwig's avatar Christoph Hellwig

nvme: add a quirk to disable namespace identifiers

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <kbusch@kernel.org>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarChaitanya Kulkarni <kch@nvidia.com>
parent b42b6f44
...@@ -1288,6 +1288,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids, ...@@ -1288,6 +1288,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids,
warn_str, cur->nidl); warn_str, cur->nidl);
return -1; return -1;
} }
if (ctrl->quirks & NVME_QUIRK_BOGUS_NID)
return NVME_NIDT_EUI64_LEN;
memcpy(ids->eui64, data + sizeof(*cur), NVME_NIDT_EUI64_LEN); memcpy(ids->eui64, data + sizeof(*cur), NVME_NIDT_EUI64_LEN);
return NVME_NIDT_EUI64_LEN; return NVME_NIDT_EUI64_LEN;
case NVME_NIDT_NGUID: case NVME_NIDT_NGUID:
...@@ -1296,6 +1298,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids, ...@@ -1296,6 +1298,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids,
warn_str, cur->nidl); warn_str, cur->nidl);
return -1; return -1;
} }
if (ctrl->quirks & NVME_QUIRK_BOGUS_NID)
return NVME_NIDT_NGUID_LEN;
memcpy(ids->nguid, data + sizeof(*cur), NVME_NIDT_NGUID_LEN); memcpy(ids->nguid, data + sizeof(*cur), NVME_NIDT_NGUID_LEN);
return NVME_NIDT_NGUID_LEN; return NVME_NIDT_NGUID_LEN;
case NVME_NIDT_UUID: case NVME_NIDT_UUID:
...@@ -1304,6 +1308,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids, ...@@ -1304,6 +1308,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids,
warn_str, cur->nidl); warn_str, cur->nidl);
return -1; return -1;
} }
if (ctrl->quirks & NVME_QUIRK_BOGUS_NID)
return NVME_NIDT_UUID_LEN;
uuid_copy(&ids->uuid, data + sizeof(*cur)); uuid_copy(&ids->uuid, data + sizeof(*cur));
return NVME_NIDT_UUID_LEN; return NVME_NIDT_UUID_LEN;
case NVME_NIDT_CSI: case NVME_NIDT_CSI:
...@@ -1400,12 +1406,18 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, ...@@ -1400,12 +1406,18 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
if ((*id)->ncap == 0) /* namespace not allocated or attached */ if ((*id)->ncap == 0) /* namespace not allocated or attached */
goto out_free_id; goto out_free_id;
if (ctrl->vs >= NVME_VS(1, 1, 0) &&
!memchr_inv(ids->eui64, 0, sizeof(ids->eui64))) if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) {
memcpy(ids->eui64, (*id)->eui64, sizeof(ids->eui64)); dev_info(ctrl->device,
if (ctrl->vs >= NVME_VS(1, 2, 0) && "Ignoring bogus Namespace Identifiers\n");
!memchr_inv(ids->nguid, 0, sizeof(ids->nguid))) } else {
memcpy(ids->nguid, (*id)->nguid, sizeof(ids->nguid)); 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; return 0;
......
...@@ -144,6 +144,11 @@ enum nvme_quirks { ...@@ -144,6 +144,11 @@ enum nvme_quirks {
* encoding the generation sequence number. * encoding the generation sequence number.
*/ */
NVME_QUIRK_SKIP_CID_GEN = (1 << 17), NVME_QUIRK_SKIP_CID_GEN = (1 << 17),
/*
* Reports garbage in the namespace identifiers (eui64, nguid, uuid).
*/
NVME_QUIRK_BOGUS_NID = (1 << 18),
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment