nvme: read the subsystem NQN from Identify Controller
NVMe 1.2.1 or later requires controllers to provide a subsystem NQN in the Identify controller data structures. Use this NQN for the subsysnqn sysfs attribute by storing it in the nvme_ctrl structure after verifying it. For older controllers we generate a "fake" NQN per non-normative text in the NVMe 1.3 spec. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Keith Busch <keith.busch@intel.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
942fbab4cd
commit
180de00700
|
@ -1705,6 +1705,31 @@ static bool quirk_matches(const struct nvme_id_ctrl *id,
|
|||
string_matches(id->fr, q->fr, sizeof(id->fr));
|
||||
}
|
||||
|
||||
static void nvme_init_subnqn(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
|
||||
{
|
||||
size_t nqnlen;
|
||||
int off;
|
||||
|
||||
nqnlen = strnlen(id->subnqn, NVMF_NQN_SIZE);
|
||||
if (nqnlen > 0 && nqnlen < NVMF_NQN_SIZE) {
|
||||
strcpy(ctrl->subnqn, id->subnqn);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctrl->vs >= NVME_VS(1, 2, 1))
|
||||
dev_warn(ctrl->device, "missing or invalid SUBNQN field.\n");
|
||||
|
||||
/* Generate a "fake" NQN per Figure 254 in NVMe 1.3 + ECN 001 */
|
||||
off = snprintf(ctrl->subnqn, NVMF_NQN_SIZE,
|
||||
"nqn.2014.08.org.nvmexpress:%4x%4x",
|
||||
le16_to_cpu(id->vid), le16_to_cpu(id->ssvid));
|
||||
memcpy(ctrl->subnqn + off, id->sn, sizeof(id->sn));
|
||||
off += sizeof(id->sn);
|
||||
memcpy(ctrl->subnqn + off, id->mn, sizeof(id->mn));
|
||||
off += sizeof(id->mn);
|
||||
memset(ctrl->subnqn + off, 0, sizeof(ctrl->subnqn) - off);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the cached copies of the Identify data and various controller
|
||||
* register in our nvme_ctrl structure. This should be called as soon as
|
||||
|
@ -1740,6 +1765,8 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
nvme_init_subnqn(ctrl, id);
|
||||
|
||||
if (!ctrl->identified) {
|
||||
/*
|
||||
* Check for quirks. Quirk can depend on firmware version,
|
||||
|
@ -2135,8 +2162,7 @@ static ssize_t nvme_sysfs_show_subsysnqn(struct device *dev,
|
|||
{
|
||||
struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
ctrl->ops->get_subsysnqn(ctrl));
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", ctrl->subnqn);
|
||||
}
|
||||
static DEVICE_ATTR(subsysnqn, S_IRUGO, nvme_sysfs_show_subsysnqn, NULL);
|
||||
|
||||
|
@ -2181,7 +2207,6 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
|
|||
return 0;
|
||||
}
|
||||
|
||||
CHECK_ATTR(ctrl, a, subsysnqn);
|
||||
CHECK_ATTR(ctrl, a, address);
|
||||
|
||||
return a->mode;
|
||||
|
|
|
@ -125,16 +125,6 @@ int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(nvmf_get_address);
|
||||
|
||||
/**
|
||||
* nvmf_get_subsysnqn() - Get subsystem NQN
|
||||
* @ctrl: Host NVMe controller instance which we got the NQN
|
||||
*/
|
||||
const char *nvmf_get_subsysnqn(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
return ctrl->opts->subsysnqn;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvmf_get_subsysnqn);
|
||||
|
||||
/**
|
||||
* nvmf_reg_read32() - NVMe Fabrics "Property Get" API function.
|
||||
* @ctrl: Host NVMe controller instance maintaining the admin
|
||||
|
|
|
@ -139,7 +139,6 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid);
|
|||
int nvmf_register_transport(struct nvmf_transport_ops *ops);
|
||||
void nvmf_unregister_transport(struct nvmf_transport_ops *ops);
|
||||
void nvmf_free_options(struct nvmf_ctrl_options *opts);
|
||||
const char *nvmf_get_subsysnqn(struct nvme_ctrl *ctrl);
|
||||
int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size);
|
||||
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl);
|
||||
|
||||
|
|
|
@ -2631,7 +2631,6 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = {
|
|||
.free_ctrl = nvme_fc_nvme_ctrl_freed,
|
||||
.submit_async_event = nvme_fc_submit_async_event,
|
||||
.delete_ctrl = nvme_fc_del_nvme_ctrl,
|
||||
.get_subsysnqn = nvmf_get_subsysnqn,
|
||||
.get_address = nvmf_get_address,
|
||||
};
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ struct nvme_ctrl {
|
|||
char serial[20];
|
||||
char model[40];
|
||||
char firmware_rev[8];
|
||||
char subnqn[NVMF_NQN_SIZE];
|
||||
u16 cntlid;
|
||||
|
||||
u32 ctrl_config;
|
||||
|
@ -225,7 +226,6 @@ struct nvme_ctrl_ops {
|
|||
void (*free_ctrl)(struct nvme_ctrl *ctrl);
|
||||
void (*submit_async_event)(struct nvme_ctrl *ctrl, int aer_idx);
|
||||
int (*delete_ctrl)(struct nvme_ctrl *ctrl);
|
||||
const char *(*get_subsysnqn)(struct nvme_ctrl *ctrl);
|
||||
int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
|
||||
};
|
||||
|
||||
|
|
|
@ -1757,7 +1757,6 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
|
|||
.free_ctrl = nvme_rdma_free_ctrl,
|
||||
.submit_async_event = nvme_rdma_submit_async_event,
|
||||
.delete_ctrl = nvme_rdma_del_ctrl,
|
||||
.get_subsysnqn = nvmf_get_subsysnqn,
|
||||
.get_address = nvmf_get_address,
|
||||
};
|
||||
|
||||
|
|
|
@ -540,7 +540,6 @@ static const struct nvme_ctrl_ops nvme_loop_ctrl_ops = {
|
|||
.free_ctrl = nvme_loop_free_ctrl,
|
||||
.submit_async_event = nvme_loop_submit_async_event,
|
||||
.delete_ctrl = nvme_loop_del_ctrl,
|
||||
.get_subsysnqn = nvmf_get_subsysnqn,
|
||||
};
|
||||
|
||||
static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
|
||||
|
|
Loading…
Reference in New Issue