|
Hannes Reinecke |
940608 |
From: Christoph Hellwig <hch@lst.de>
|
|
Hannes Reinecke |
940608 |
Date: Fri, 25 May 2018 17:16:09 +0200
|
|
Hannes Reinecke |
940608 |
Subject: [PATCH] nvmet: implement the changed namespaces log
|
|
Hannes Reinecke |
940608 |
References: bsc#1054245
|
|
Hannes Reinecke |
940608 |
Git-commit: c16734ea98f5549fed9a1af47e943a45855274e0
|
|
Hannes Reinecke |
940608 |
Patch-mainline: v4.18-rc1
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
Just keep a per-controller buffer of changed namespaces and copy it out
|
|
Hannes Reinecke |
940608 |
in the get log page implementation.
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
|
Hannes Reinecke |
940608 |
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
|
|
Hannes Reinecke |
940608 |
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
|
|
Hannes Reinecke |
940608 |
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
|
Hannes Reinecke |
940608 |
---
|
|
Hannes Reinecke |
940608 |
drivers/nvme/target/admin-cmd.c | 26 +++++++++++++++++++
|
|
Hannes Reinecke |
940608 |
drivers/nvme/target/core.c | 55 +++++++++++++++++++++++++++++++++++------
|
|
Hannes Reinecke |
940608 |
drivers/nvme/target/nvmet.h | 3 +++
|
|
Hannes Reinecke |
940608 |
3 files changed, 76 insertions(+), 8 deletions(-)
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
|
|
Hannes Reinecke |
940608 |
index f5d8c47d3c40..795e3c4559cb 100644
|
|
Hannes Reinecke |
940608 |
--- a/drivers/nvme/target/admin-cmd.c
|
|
Hannes Reinecke |
940608 |
+++ b/drivers/nvme/target/admin-cmd.c
|
|
Hannes Reinecke |
940608 |
@@ -118,6 +118,29 @@ static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
|
|
Hannes Reinecke |
940608 |
nvmet_req_complete(req, status);
|
|
Hannes Reinecke |
940608 |
}
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
+static void nvmet_execute_get_log_changed_ns(struct nvmet_req *req)
|
|
Hannes Reinecke |
940608 |
+{
|
|
Hannes Reinecke |
940608 |
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
|
|
Hannes Reinecke |
940608 |
+ u16 status = NVME_SC_INTERNAL;
|
|
Hannes Reinecke |
940608 |
+ size_t len;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ if (req->data_len != NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32))
|
|
Hannes Reinecke |
940608 |
+ goto out;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ mutex_lock(&ctrl->lock);
|
|
Hannes Reinecke |
940608 |
+ if (ctrl->nr_changed_ns == U32_MAX)
|
|
Hannes Reinecke |
940608 |
+ len = sizeof(__le32);
|
|
Hannes Reinecke |
940608 |
+ else
|
|
Hannes Reinecke |
940608 |
+ len = ctrl->nr_changed_ns * sizeof(__le32);
|
|
Hannes Reinecke |
940608 |
+ status = nvmet_copy_to_sgl(req, 0, ctrl->changed_ns_list, len);
|
|
Hannes Reinecke |
940608 |
+ if (!status)
|
|
Hannes Reinecke |
940608 |
+ status = nvmet_zero_sgl(req, len, req->data_len - len);
|
|
Hannes Reinecke |
940608 |
+ ctrl->nr_changed_ns = 0;
|
|
Hannes Reinecke |
940608 |
+ mutex_unlock(&ctrl->lock);
|
|
Hannes Reinecke |
940608 |
+out:
|
|
Hannes Reinecke |
940608 |
+ nvmet_req_complete(req, status);
|
|
Hannes Reinecke |
940608 |
+}
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
static void copy_and_pad(char *dst, int dst_len, const char *src, int src_len)
|
|
Hannes Reinecke |
940608 |
{
|
|
Hannes Reinecke |
940608 |
int len = min(src_len, dst_len);
|
|
Hannes Reinecke |
940608 |
@@ -545,6 +568,9 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
|
|
Hannes Reinecke |
940608 |
*/
|
|
Hannes Reinecke |
940608 |
req->execute = nvmet_execute_get_log_page_noop;
|
|
Hannes Reinecke |
940608 |
return 0;
|
|
Hannes Reinecke |
940608 |
+ case NVME_LOG_CHANGED_NS:
|
|
Hannes Reinecke |
940608 |
+ req->execute = nvmet_execute_get_log_changed_ns;
|
|
Hannes Reinecke |
940608 |
+ return 0;
|
|
Hannes Reinecke |
940608 |
}
|
|
Hannes Reinecke |
940608 |
break;
|
|
Hannes Reinecke |
940608 |
case nvme_admin_identify:
|
|
Hannes Reinecke |
940608 |
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
|
|
Hannes Reinecke |
940608 |
index 6a71fb1affc9..ea37e0053ee7 100644
|
|
Hannes Reinecke |
940608 |
--- a/drivers/nvme/target/core.c
|
|
Hannes Reinecke |
940608 |
+++ b/drivers/nvme/target/core.c
|
|
Hannes Reinecke |
940608 |
@@ -144,6 +144,42 @@ static void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
|
|
Hannes Reinecke |
940608 |
schedule_work(&ctrl->async_event_work);
|
|
Hannes Reinecke |
940608 |
}
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
+static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid)
|
|
Hannes Reinecke |
940608 |
+{
|
|
Hannes Reinecke |
940608 |
+ u32 i;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ mutex_lock(&ctrl->lock);
|
|
Hannes Reinecke |
940608 |
+ if (ctrl->nr_changed_ns > NVME_MAX_CHANGED_NAMESPACES)
|
|
Hannes Reinecke |
940608 |
+ goto out_unlock;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ for (i = 0; i < ctrl->nr_changed_ns; i++) {
|
|
Hannes Reinecke |
940608 |
+ if (ctrl->changed_ns_list[i] == nsid)
|
|
Hannes Reinecke |
940608 |
+ goto out_unlock;
|
|
Hannes Reinecke |
940608 |
+ }
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ if (ctrl->nr_changed_ns == NVME_MAX_CHANGED_NAMESPACES) {
|
|
Hannes Reinecke |
940608 |
+ ctrl->changed_ns_list[0] = cpu_to_le32(0xffffffff);
|
|
Hannes Reinecke |
940608 |
+ ctrl->nr_changed_ns = U32_MAX;
|
|
Hannes Reinecke |
940608 |
+ goto out_unlock;
|
|
Hannes Reinecke |
940608 |
+ }
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ ctrl->changed_ns_list[ctrl->nr_changed_ns++] = nsid;
|
|
Hannes Reinecke |
940608 |
+out_unlock:
|
|
Hannes Reinecke |
940608 |
+ mutex_unlock(&ctrl->lock);
|
|
Hannes Reinecke |
940608 |
+}
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+static void nvmet_ns_changed(struct nvmet_subsys *subsys, u32 nsid)
|
|
Hannes Reinecke |
940608 |
+{
|
|
Hannes Reinecke |
940608 |
+ struct nvmet_ctrl *ctrl;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
+ list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
|
|
Hannes Reinecke |
940608 |
+ nvmet_add_to_changed_ns_log(ctrl, cpu_to_le32(nsid));
|
|
Hannes Reinecke |
940608 |
+ nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE,
|
|
Hannes Reinecke |
940608 |
+ NVME_AER_NOTICE_NS_CHANGED,
|
|
Hannes Reinecke |
940608 |
+ NVME_LOG_CHANGED_NS);
|
|
Hannes Reinecke |
940608 |
+ }
|
|
Hannes Reinecke |
940608 |
+}
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
int nvmet_register_transport(const struct nvmet_fabrics_ops *ops)
|
|
Hannes Reinecke |
940608 |
{
|
|
Hannes Reinecke |
940608 |
int ret = 0;
|
|
Hannes Reinecke |
940608 |
@@ -281,7 +317,6 @@ void nvmet_put_namespace(struct nvmet_ns *ns)
|
|
Hannes Reinecke |
940608 |
int nvmet_ns_enable(struct nvmet_ns *ns)
|
|
Hannes Reinecke |
940608 |
{
|
|
Hannes Reinecke |
940608 |
struct nvmet_subsys *subsys = ns->subsys;
|
|
Hannes Reinecke |
940608 |
- struct nvmet_ctrl *ctrl;
|
|
Hannes Reinecke |
940608 |
int ret = 0;
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
mutex_lock(&subsys->lock);
|
|
Hannes Reinecke |
940608 |
@@ -327,9 +362,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
|
|
Hannes Reinecke |
940608 |
list_add_tail_rcu(&ns->dev_link, &old->dev_link);
|
|
Hannes Reinecke |
940608 |
}
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
|
|
Hannes Reinecke |
940608 |
- nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
|
|
Hannes Reinecke |
940608 |
-
|
|
Hannes Reinecke |
940608 |
+ nvmet_ns_changed(subsys, ns->nsid);
|
|
Hannes Reinecke |
940608 |
ns->enabled = true;
|
|
Hannes Reinecke |
940608 |
ret = 0;
|
|
Hannes Reinecke |
940608 |
out_unlock:
|
|
Hannes Reinecke |
940608 |
@@ -344,7 +377,6 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
|
|
Hannes Reinecke |
940608 |
void nvmet_ns_disable(struct nvmet_ns *ns)
|
|
Hannes Reinecke |
940608 |
{
|
|
Hannes Reinecke |
940608 |
struct nvmet_subsys *subsys = ns->subsys;
|
|
Hannes Reinecke |
940608 |
- struct nvmet_ctrl *ctrl;
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
mutex_lock(&subsys->lock);
|
|
Hannes Reinecke |
940608 |
if (!ns->enabled)
|
|
Hannes Reinecke |
940608 |
@@ -370,8 +402,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
|
|
Hannes Reinecke |
940608 |
percpu_ref_exit(&ns->ref);
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
mutex_lock(&subsys->lock);
|
|
Hannes Reinecke |
940608 |
- list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
|
|
Hannes Reinecke |
940608 |
- nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
|
|
Hannes Reinecke |
940608 |
+ nvmet_ns_changed(subsys, ns->nsid);
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
if (ns->bdev)
|
|
Hannes Reinecke |
940608 |
blkdev_put(ns->bdev, FMODE_WRITE|FMODE_READ);
|
|
Hannes Reinecke |
940608 |
@@ -817,11 +848,16 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
|
|
Hannes Reinecke |
940608 |
kref_init(&ctrl->ref);
|
|
Hannes Reinecke |
940608 |
ctrl->subsys = subsys;
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
+ ctrl->changed_ns_list = kmalloc_array(NVME_MAX_CHANGED_NAMESPACES,
|
|
Hannes Reinecke |
940608 |
+ sizeof(__le32), GFP_KERNEL);
|
|
Hannes Reinecke |
940608 |
+ if (!ctrl->changed_ns_list)
|
|
Hannes Reinecke |
940608 |
+ goto out_free_ctrl;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
ctrl->cqs = kcalloc(subsys->max_qid + 1,
|
|
Hannes Reinecke |
940608 |
sizeof(struct nvmet_cq *),
|
|
Hannes Reinecke |
940608 |
GFP_KERNEL);
|
|
Hannes Reinecke |
940608 |
if (!ctrl->cqs)
|
|
Hannes Reinecke |
940608 |
- goto out_free_ctrl;
|
|
Hannes Reinecke |
940608 |
+ goto out_free_changed_ns_list;
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
ctrl->sqs = kcalloc(subsys->max_qid + 1,
|
|
Hannes Reinecke |
940608 |
sizeof(struct nvmet_sq *),
|
|
Hannes Reinecke |
940608 |
@@ -879,6 +915,8 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
|
|
Hannes Reinecke |
940608 |
kfree(ctrl->sqs);
|
|
Hannes Reinecke |
940608 |
out_free_cqs:
|
|
Hannes Reinecke |
940608 |
kfree(ctrl->cqs);
|
|
Hannes Reinecke |
940608 |
+out_free_changed_ns_list:
|
|
Hannes Reinecke |
940608 |
+ kfree(ctrl->changed_ns_list);
|
|
Hannes Reinecke |
940608 |
out_free_ctrl:
|
|
Hannes Reinecke |
940608 |
kfree(ctrl);
|
|
Hannes Reinecke |
940608 |
out_put_subsystem:
|
|
Hannes Reinecke |
940608 |
@@ -905,6 +943,7 @@ static void nvmet_ctrl_free(struct kref *ref)
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
kfree(ctrl->sqs);
|
|
Hannes Reinecke |
940608 |
kfree(ctrl->cqs);
|
|
Hannes Reinecke |
940608 |
+ kfree(ctrl->changed_ns_list);
|
|
Hannes Reinecke |
940608 |
kfree(ctrl);
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
nvmet_subsys_put(subsys);
|
|
Hannes Reinecke |
940608 |
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
|
|
Hannes Reinecke |
940608 |
index 77779522eb2a..b9783d32c3da 100644
|
|
Hannes Reinecke |
940608 |
--- a/drivers/nvme/target/nvmet.h
|
|
Hannes Reinecke |
940608 |
+++ b/drivers/nvme/target/nvmet.h
|
|
Hannes Reinecke |
940608 |
@@ -132,6 +132,9 @@ struct nvmet_ctrl {
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
const struct nvmet_fabrics_ops *ops;
|
|
Hannes Reinecke |
940608 |
|
|
Hannes Reinecke |
940608 |
+ __le32 *changed_ns_list;
|
|
Hannes Reinecke |
940608 |
+ u32 nr_changed_ns;
|
|
Hannes Reinecke |
940608 |
+
|
|
Hannes Reinecke |
940608 |
char subsysnqn[NVMF_NQN_FIELD_LEN];
|
|
Hannes Reinecke |
940608 |
char hostnqn[NVMF_NQN_FIELD_LEN];
|
|
Hannes Reinecke |
940608 |
};
|
|
Hannes Reinecke |
940608 |
--
|
|
Hannes Reinecke |
940608 |
2.12.3
|
|
Hannes Reinecke |
940608 |
|