Commit 002fab04 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

nvme: introduce a nvme_ns_ids structure

This allows us to manage the various uniqueue namespace identifiers
together instead needing various variables and arguments.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent ab9e00cc
...@@ -797,7 +797,7 @@ static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id) ...@@ -797,7 +797,7 @@ static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id)
} }
static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
u8 *eui64, u8 *nguid, uuid_t *uuid) struct nvme_ns_ids *ids)
{ {
struct nvme_command c = { }; struct nvme_command c = { };
int status; int status;
...@@ -833,7 +833,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, ...@@ -833,7 +833,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
goto free_data; goto free_data;
} }
len = NVME_NIDT_EUI64_LEN; len = NVME_NIDT_EUI64_LEN;
memcpy(eui64, data + pos + sizeof(*cur), len); memcpy(ids->eui64, data + pos + sizeof(*cur), len);
break; break;
case NVME_NIDT_NGUID: case NVME_NIDT_NGUID:
if (cur->nidl != NVME_NIDT_NGUID_LEN) { if (cur->nidl != NVME_NIDT_NGUID_LEN) {
...@@ -843,7 +843,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, ...@@ -843,7 +843,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
goto free_data; goto free_data;
} }
len = NVME_NIDT_NGUID_LEN; len = NVME_NIDT_NGUID_LEN;
memcpy(nguid, data + pos + sizeof(*cur), len); memcpy(ids->nguid, data + pos + sizeof(*cur), len);
break; break;
case NVME_NIDT_UUID: case NVME_NIDT_UUID:
if (cur->nidl != NVME_NIDT_UUID_LEN) { if (cur->nidl != NVME_NIDT_UUID_LEN) {
...@@ -853,7 +853,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid, ...@@ -853,7 +853,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
goto free_data; goto free_data;
} }
len = NVME_NIDT_UUID_LEN; len = NVME_NIDT_UUID_LEN;
uuid_copy(uuid, data + pos + sizeof(*cur)); uuid_copy(&ids->uuid, data + pos + sizeof(*cur));
break; break;
default: default:
/* Skip unnkown types */ /* Skip unnkown types */
...@@ -1233,22 +1233,31 @@ static void nvme_config_discard(struct nvme_ctrl *ctrl, ...@@ -1233,22 +1233,31 @@ static void nvme_config_discard(struct nvme_ctrl *ctrl,
} }
static void nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid, static void nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid,
struct nvme_id_ns *id, u8 *eui64, u8 *nguid, uuid_t *uuid) struct nvme_id_ns *id, struct nvme_ns_ids *ids)
{ {
memset(ids, 0, sizeof(*ids));
if (ctrl->vs >= NVME_VS(1, 1, 0)) if (ctrl->vs >= NVME_VS(1, 1, 0))
memcpy(eui64, id->eui64, sizeof(id->eui64)); memcpy(ids->eui64, id->eui64, sizeof(id->eui64));
if (ctrl->vs >= NVME_VS(1, 2, 0)) if (ctrl->vs >= NVME_VS(1, 2, 0))
memcpy(nguid, id->nguid, sizeof(id->nguid)); memcpy(ids->nguid, id->nguid, sizeof(id->nguid));
if (ctrl->vs >= NVME_VS(1, 3, 0)) { if (ctrl->vs >= NVME_VS(1, 3, 0)) {
/* Don't treat error as fatal we potentially /* Don't treat error as fatal we potentially
* already have a NGUID or EUI-64 * already have a NGUID or EUI-64
*/ */
if (nvme_identify_ns_descs(ctrl, nsid, eui64, nguid, uuid)) if (nvme_identify_ns_descs(ctrl, nsid, ids))
dev_warn(ctrl->device, dev_warn(ctrl->device,
"%s: Identify Descriptors failed\n", __func__); "%s: Identify Descriptors failed\n", __func__);
} }
} }
static bool nvme_ns_ids_equal(struct nvme_ns_ids *a, struct nvme_ns_ids *b)
{
return uuid_equal(&a->uuid, &b->uuid) &&
memcmp(&a->nguid, &b->nguid, sizeof(a->nguid)) == 0 &&
memcmp(&a->eui64, &b->eui64, sizeof(a->eui64)) == 0;
}
static void nvme_update_disk_info(struct gendisk *disk, static void nvme_update_disk_info(struct gendisk *disk,
struct nvme_ns *ns, struct nvme_id_ns *id) struct nvme_ns *ns, struct nvme_id_ns *id)
{ {
...@@ -1304,8 +1313,7 @@ static int nvme_revalidate_disk(struct gendisk *disk) ...@@ -1304,8 +1313,7 @@ static int nvme_revalidate_disk(struct gendisk *disk)
struct nvme_ns *ns = disk->private_data; struct nvme_ns *ns = disk->private_data;
struct nvme_ctrl *ctrl = ns->ctrl; struct nvme_ctrl *ctrl = ns->ctrl;
struct nvme_id_ns *id; struct nvme_id_ns *id;
u8 eui64[8] = { 0 }, nguid[16] = { 0 }; struct nvme_ns_ids ids;
uuid_t uuid = uuid_null;
int ret = 0; int ret = 0;
if (test_bit(NVME_NS_DEAD, &ns->flags)) { if (test_bit(NVME_NS_DEAD, &ns->flags)) {
...@@ -1322,10 +1330,8 @@ static int nvme_revalidate_disk(struct gendisk *disk) ...@@ -1322,10 +1330,8 @@ static int nvme_revalidate_disk(struct gendisk *disk)
goto out; goto out;
} }
nvme_report_ns_ids(ctrl, ns->ns_id, id, eui64, nguid, &uuid); nvme_report_ns_ids(ctrl, ns->ns_id, id, &ids);
if (!uuid_equal(&ns->uuid, &uuid) || if (!nvme_ns_ids_equal(&ns->ids, &ids)) {
memcmp(&ns->nguid, &nguid, sizeof(ns->nguid)) ||
memcmp(&ns->eui, &eui64, sizeof(ns->eui))) {
dev_err(ctrl->device, dev_err(ctrl->device,
"identifiers changed for nsid %d\n", ns->ns_id); "identifiers changed for nsid %d\n", ns->ns_id);
ret = -ENODEV; ret = -ENODEV;
...@@ -2266,18 +2272,19 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr, ...@@ -2266,18 +2272,19 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct nvme_ns *ns = nvme_get_ns_from_dev(dev); struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
struct nvme_ns_ids *ids = &ns->ids;
struct nvme_subsystem *subsys = ns->ctrl->subsys; struct nvme_subsystem *subsys = ns->ctrl->subsys;
int serial_len = sizeof(subsys->serial); int serial_len = sizeof(subsys->serial);
int model_len = sizeof(subsys->model); int model_len = sizeof(subsys->model);
if (!uuid_is_null(&ns->uuid)) if (!uuid_is_null(&ids->uuid))
return sprintf(buf, "uuid.%pU\n", &ns->uuid); return sprintf(buf, "uuid.%pU\n", &ids->uuid);
if (memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) if (memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
return sprintf(buf, "eui.%16phN\n", ns->nguid); return sprintf(buf, "eui.%16phN\n", ids->nguid);
if (memchr_inv(ns->eui, 0, sizeof(ns->eui))) if (memchr_inv(ids->eui64, 0, sizeof(ids->eui64)))
return sprintf(buf, "eui.%8phN\n", ns->eui); return sprintf(buf, "eui.%8phN\n", ids->eui64);
while (serial_len > 0 && (subsys->serial[serial_len - 1] == ' ' || while (serial_len > 0 && (subsys->serial[serial_len - 1] == ' ' ||
subsys->serial[serial_len - 1] == '\0')) subsys->serial[serial_len - 1] == '\0'))
...@@ -2296,7 +2303,7 @@ static ssize_t nguid_show(struct device *dev, struct device_attribute *attr, ...@@ -2296,7 +2303,7 @@ static ssize_t nguid_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct nvme_ns *ns = nvme_get_ns_from_dev(dev); struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
return sprintf(buf, "%pU\n", ns->nguid); return sprintf(buf, "%pU\n", ns->ids.nguid);
} }
static DEVICE_ATTR(nguid, S_IRUGO, nguid_show, NULL); static DEVICE_ATTR(nguid, S_IRUGO, nguid_show, NULL);
...@@ -2304,16 +2311,17 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr, ...@@ -2304,16 +2311,17 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct nvme_ns *ns = nvme_get_ns_from_dev(dev); struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
struct nvme_ns_ids *ids = &ns->ids;
/* For backward compatibility expose the NGUID to userspace if /* For backward compatibility expose the NGUID to userspace if
* we have no UUID set * we have no UUID set
*/ */
if (uuid_is_null(&ns->uuid)) { if (uuid_is_null(&ids->uuid)) {
printk_ratelimited(KERN_WARNING printk_ratelimited(KERN_WARNING
"No UUID available providing old NGUID\n"); "No UUID available providing old NGUID\n");
return sprintf(buf, "%pU\n", ns->nguid); return sprintf(buf, "%pU\n", ids->nguid);
} }
return sprintf(buf, "%pU\n", &ns->uuid); return sprintf(buf, "%pU\n", &ids->uuid);
} }
static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL); static DEVICE_ATTR(uuid, S_IRUGO, uuid_show, NULL);
...@@ -2321,7 +2329,7 @@ static ssize_t eui_show(struct device *dev, struct device_attribute *attr, ...@@ -2321,7 +2329,7 @@ static ssize_t eui_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct nvme_ns *ns = nvme_get_ns_from_dev(dev); struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
return sprintf(buf, "%8ph\n", ns->eui); return sprintf(buf, "%8ph\n", ns->ids.eui64);
} }
static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL); static DEVICE_ATTR(eui, S_IRUGO, eui_show, NULL);
...@@ -2347,18 +2355,19 @@ static umode_t nvme_ns_attrs_are_visible(struct kobject *kobj, ...@@ -2347,18 +2355,19 @@ static umode_t nvme_ns_attrs_are_visible(struct kobject *kobj,
{ {
struct device *dev = container_of(kobj, struct device, kobj); struct device *dev = container_of(kobj, struct device, kobj);
struct nvme_ns *ns = nvme_get_ns_from_dev(dev); struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
struct nvme_ns_ids *ids = &ns->ids;
if (a == &dev_attr_uuid.attr) { if (a == &dev_attr_uuid.attr) {
if (uuid_is_null(&ns->uuid) || if (uuid_is_null(&ids->uuid) ||
!memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) !memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
return 0; return 0;
} }
if (a == &dev_attr_nguid.attr) { if (a == &dev_attr_nguid.attr) {
if (!memchr_inv(ns->nguid, 0, sizeof(ns->nguid))) if (!memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
return 0; return 0;
} }
if (a == &dev_attr_eui.attr) { if (a == &dev_attr_eui.attr) {
if (!memchr_inv(ns->eui, 0, sizeof(ns->eui))) if (!memchr_inv(ids->eui64, 0, sizeof(ids->eui64)))
return 0; return 0;
} }
return a->mode; return a->mode;
...@@ -2591,7 +2600,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) ...@@ -2591,7 +2600,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
if (id->ncap == 0) if (id->ncap == 0)
goto out_free_id; goto out_free_id;
nvme_report_ns_ids(ctrl, ns->ns_id, id, ns->eui, ns->nguid, &ns->uuid); nvme_report_ns_ids(ctrl, ns->ns_id, id, &ns->ids);
if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) { if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) {
if (nvme_nvm_register(ns, disk_name, node)) { if (nvme_nvm_register(ns, disk_name, node)) {
......
...@@ -217,6 +217,15 @@ struct nvme_subsystem { ...@@ -217,6 +217,15 @@ struct nvme_subsystem {
u16 vendor_id; u16 vendor_id;
}; };
/*
* Container structure for uniqueue namespace identifiers.
*/
struct nvme_ns_ids {
u8 eui64[8];
u8 nguid[16];
uuid_t uuid;
};
struct nvme_ns { struct nvme_ns {
struct list_head list; struct list_head list;
...@@ -227,11 +236,8 @@ struct nvme_ns { ...@@ -227,11 +236,8 @@ struct nvme_ns {
struct kref kref; struct kref kref;
int instance; int instance;
u8 eui[8];
u8 nguid[16];
uuid_t uuid;
unsigned ns_id; unsigned ns_id;
struct nvme_ns_ids ids;
int lba_shift; int lba_shift;
u16 ms; u16 ms;
u16 sgs; u16 sgs;
......
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