Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+39 −30
Original line number Diff line number Diff line
@@ -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,
		u8 *eui64, u8 *nguid, uuid_t *uuid)
		struct nvme_ns_ids *ids)
{
	struct nvme_command c = { };
	int status;
@@ -833,7 +833,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
				goto free_data;
			}
			len = NVME_NIDT_EUI64_LEN;
			memcpy(eui64, data + pos + sizeof(*cur), len);
			memcpy(ids->eui64, data + pos + sizeof(*cur), len);
			break;
		case NVME_NIDT_NGUID:
			if (cur->nidl != NVME_NIDT_NGUID_LEN) {
@@ -843,7 +843,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
				goto free_data;
			}
			len = NVME_NIDT_NGUID_LEN;
			memcpy(nguid, data + pos + sizeof(*cur), len);
			memcpy(ids->nguid, data + pos + sizeof(*cur), len);
			break;
		case NVME_NIDT_UUID:
			if (cur->nidl != NVME_NIDT_UUID_LEN) {
@@ -853,7 +853,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
				goto free_data;
			}
			len = NVME_NIDT_UUID_LEN;
			uuid_copy(uuid, data + pos + sizeof(*cur));
			uuid_copy(&ids->uuid, data + pos + sizeof(*cur));
			break;
		default:
			/* Skip unnkown types */
@@ -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,
		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))
		memcpy(eui64, id->eui64, sizeof(id->eui64));
		memcpy(ids->eui64, id->eui64, sizeof(id->eui64));
	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)) {
		 /* Don't treat error as fatal we potentially
		  * 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,
				 "%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,
		struct nvme_ns *ns, struct nvme_id_ns *id)
{
@@ -1304,8 +1313,7 @@ static int nvme_revalidate_disk(struct gendisk *disk)
	struct nvme_ns *ns = disk->private_data;
	struct nvme_ctrl *ctrl = ns->ctrl;
	struct nvme_id_ns *id;
	u8 eui64[8] = { 0 }, nguid[16] = { 0 };
	uuid_t uuid = uuid_null;
	struct nvme_ns_ids ids;
	int ret = 0;

	if (test_bit(NVME_NS_DEAD, &ns->flags)) {
@@ -1322,10 +1330,8 @@ static int nvme_revalidate_disk(struct gendisk *disk)
		goto out;
	}

	nvme_report_ns_ids(ctrl, ns->ns_id, id, eui64, nguid, &uuid);
	if (!uuid_equal(&ns->uuid, &uuid) ||
	    memcmp(&ns->nguid, &nguid, sizeof(ns->nguid)) ||
	    memcmp(&ns->eui, &eui64, sizeof(ns->eui))) {
	nvme_report_ns_ids(ctrl, ns->ns_id, id, &ids);
	if (!nvme_ns_ids_equal(&ns->ids, &ids)) {
		dev_err(ctrl->device,
			"identifiers changed for nsid %d\n", ns->ns_id);
		ret = -ENODEV;
@@ -2266,18 +2272,19 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
								char *buf)
{
	struct nvme_ns *ns = nvme_get_ns_from_dev(dev);
	struct nvme_ns_ids *ids = &ns->ids;
	struct nvme_subsystem *subsys = ns->ctrl->subsys;
	int serial_len = sizeof(subsys->serial);
	int model_len = sizeof(subsys->model);

	if (!uuid_is_null(&ns->uuid))
		return sprintf(buf, "uuid.%pU\n", &ns->uuid);
	if (!uuid_is_null(&ids->uuid))
		return sprintf(buf, "uuid.%pU\n", &ids->uuid);

	if (memchr_inv(ns->nguid, 0, sizeof(ns->nguid)))
		return sprintf(buf, "eui.%16phN\n", ns->nguid);
	if (memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
		return sprintf(buf, "eui.%16phN\n", ids->nguid);

	if (memchr_inv(ns->eui, 0, sizeof(ns->eui)))
		return sprintf(buf, "eui.%8phN\n", ns->eui);
	if (memchr_inv(ids->eui64, 0, sizeof(ids->eui64)))
		return sprintf(buf, "eui.%8phN\n", ids->eui64);

	while (serial_len > 0 && (subsys->serial[serial_len - 1] == ' ' ||
				  subsys->serial[serial_len - 1] == '\0'))
@@ -2296,7 +2303,7 @@ static ssize_t nguid_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	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);

@@ -2304,16 +2311,17 @@ static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
								char *buf)
{
	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
	 * we have no UUID set
	 */
	if (uuid_is_null(&ns->uuid)) {
	if (uuid_is_null(&ids->uuid)) {
		printk_ratelimited(KERN_WARNING
				   "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);

@@ -2321,7 +2329,7 @@ static ssize_t eui_show(struct device *dev, struct device_attribute *attr,
								char *buf)
{
	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);

@@ -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 nvme_ns *ns = nvme_get_ns_from_dev(dev);
	struct nvme_ns_ids *ids = &ns->ids;

	if (a == &dev_attr_uuid.attr) {
		if (uuid_is_null(&ns->uuid) ||
		    !memchr_inv(ns->nguid, 0, sizeof(ns->nguid)))
		if (uuid_is_null(&ids->uuid) ||
		    !memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
			return 0;
	}
	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;
	}
	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 a->mode;
@@ -2591,7 +2600,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
	if (id->ncap == 0)
		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 (nvme_nvm_register(ns, disk_name, node)) {
+10 −4
Original line number Diff line number Diff line
@@ -217,6 +217,15 @@ struct nvme_subsystem {
	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 list_head list;

@@ -227,11 +236,8 @@ struct nvme_ns {
	struct kref kref;
	int instance;

	u8 eui[8];
	u8 nguid[16];
	uuid_t uuid;

	unsigned ns_id;
	struct nvme_ns_ids ids;
	int lba_shift;
	u16 ms;
	u16 sgs;