[PATCH 3/3] nvmet: include all configured port in the discovery log page
Hannes Reinecke
hare at suse.de
Wed Apr 6 07:22:10 PDT 2022
When exposed discovery subsystems are enabled we should include
all configured ports in the discovery log page, not just those
through which the controller was connected.
Signed-off-by: Hannes Reinecke <hare at suse.de>
---
drivers/nvme/target/discovery.c | 72 ++++++++++++++++++++++++++++-----
1 file changed, 61 insertions(+), 11 deletions(-)
diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c
index 13fda8f9d60c..d23353a750dd 100644
--- a/drivers/nvme/target/discovery.c
+++ b/drivers/nvme/target/discovery.c
@@ -172,6 +172,7 @@ static void nvmet_set_disc_traddr(struct nvmet_req *req, struct nvmet_port *port
static size_t discovery_log_entries(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
+ struct nvmet_subsys *disc_subsys = ctrl->subsys;
struct nvmet_subsys_link *p;
struct nvmet_port *r;
size_t entries = 0;
@@ -179,10 +180,27 @@ static size_t discovery_log_entries(struct nvmet_req *req)
if (!nvmet_expose_discovery_subsys())
entries++;
- list_for_each_entry(p, &req->port->subsystems, entry) {
- if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn))
- continue;
- entries++;
+ list_for_each_entry(r, nvmet_ports, global_entry) {
+ if (!nvmet_expose_discovery_subsys()) {
+ if (r != req->port)
+ continue;
+ } else {
+ bool linked = false;
+
+ list_for_each_entry(p, &r->subsystems, entry) {
+ if (p->subsys == disc_subsys) {
+ linked = true;
+ break;
+ }
+ }
+ if (!linked)
+ continue;
+ }
+ list_for_each_entry(p, &r->subsystems, entry) {
+ if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn))
+ continue;
+ entries++;
+ }
}
list_for_each_entry(r, &req->port->referrals, entry)
entries++;
@@ -193,6 +211,7 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req)
{
const int entry_size = sizeof(struct nvmf_disc_rsp_page_entry);
struct nvmet_ctrl *ctrl = req->sq->ctrl;
+ struct nvmet_subsys *disc_subsys = ctrl->subsys;
struct nvmf_disc_rsp_page_hdr *hdr;
u64 offset = nvmet_get_log_page_offset(req->cmd);
size_t data_len = nvmet_get_log_page_len(req->cmd);
@@ -246,14 +265,45 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req)
numrec++;
}
- list_for_each_entry(p, &req->port->subsystems, entry) {
- if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn))
- continue;
+ list_for_each_entry(r, nvmet_ports, global_entry) {
+ nvmet_set_disc_traddr(req, r, traddr);
+
+ if (!nvmet_expose_discovery_subsys()) {
+ /*
+ * If the discovery subsystem is not exposed fall
+ * back to the original design of only presenting
+ * information about the port to which the controller
+ * is connected.
+ */
+ if (r != req->port)
+ continue;
+ } else {
+ bool linked = false;
+
+ /*
+ * If the discovery subsystem is exposed present
+ * information about all ports into which the
+ * discovery subsystem is linked.
+ */
+ list_for_each_entry(p, &r->subsystems, entry) {
+ if (p->subsys == disc_subsys) {
+ linked = true;
+ break;
+ }
+ }
+ if (!linked)
+ continue;
+ }
- nvmet_format_discovery_entry(hdr, req->port,
- p->subsys->subsysnqn, traddr,
- p->subsys->type, numrec);
- numrec++;
+ list_for_each_entry(p, &r->subsystems, entry) {
+ if (!nvmet_host_allowed(p->subsys, ctrl->hostnqn))
+ continue;
+
+ nvmet_format_discovery_entry(hdr, r,
+ p->subsys->subsysnqn, traddr,
+ p->subsys->type, numrec);
+ numrec++;
+ }
}
list_for_each_entry(r, &req->port->referrals, entry) {
--
2.29.2
More information about the Linux-nvme
mailing list