提交 8ab0805f 编写于 作者: C Christoph Hellwig

nvmet: split log page implementation

Remove the common code to allocate a buffer and copy it into the SGL.
Instead the two no-op implementations just zero the SGL directly, and
the smart log allocates a buffer on its own.  This prepares for the
more elaborate ANA log page.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Reviewed-by: NSagi Grimberg <sagi@grimberg.me>
Reviewed-by: NJohannes Thumshirn <jthumshirn@suse.de>
上级 c7759fff
...@@ -32,6 +32,11 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd) ...@@ -32,6 +32,11 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd)
return len; return len;
} }
static void nvmet_execute_get_log_page_noop(struct nvmet_req *req)
{
nvmet_req_complete(req, nvmet_zero_sgl(req, 0, req->data_len));
}
static u16 nvmet_get_smart_log_nsid(struct nvmet_req *req, static u16 nvmet_get_smart_log_nsid(struct nvmet_req *req,
struct nvme_smart_log *slog) struct nvme_smart_log *slog)
{ {
...@@ -97,74 +102,26 @@ static u16 nvmet_get_smart_log_all(struct nvmet_req *req, ...@@ -97,74 +102,26 @@ static u16 nvmet_get_smart_log_all(struct nvmet_req *req,
return NVME_SC_SUCCESS; return NVME_SC_SUCCESS;
} }
static u16 nvmet_get_smart_log(struct nvmet_req *req, static void nvmet_execute_get_log_page_smart(struct nvmet_req *req)
struct nvme_smart_log *slog)
{
u16 status;
WARN_ON(req == NULL || slog == NULL);
if (req->cmd->get_log_page.nsid == cpu_to_le32(NVME_NSID_ALL))
status = nvmet_get_smart_log_all(req, slog);
else
status = nvmet_get_smart_log_nsid(req, slog);
return status;
}
static void nvmet_execute_get_log_page(struct nvmet_req *req)
{ {
struct nvme_smart_log *smart_log; struct nvme_smart_log *log;
size_t data_len = nvmet_get_log_page_len(req->cmd); u16 status = NVME_SC_INTERNAL;
void *buf;
u16 status = 0;
buf = kzalloc(data_len, GFP_KERNEL); if (req->data_len != sizeof(*log))
if (!buf) {
status = NVME_SC_INTERNAL;
goto out; goto out;
}
switch (req->cmd->get_log_page.lid) { log = kzalloc(sizeof(*log), GFP_KERNEL);
case NVME_LOG_ERROR: if (!log)
/* goto out;
* We currently never set the More bit in the status field,
* so all error log entries are invalid and can be zeroed out.
* This is called a minum viable implementation (TM) of this
* mandatory log page.
*/
break;
case NVME_LOG_SMART:
/*
* XXX: fill out actual smart log
*
* We might have a hard time coming up with useful values for
* many of the fields, and even when we have useful data
* available (e.g. units or commands read/written) those aren't
* persistent over power loss.
*/
if (data_len != sizeof(*smart_log)) {
status = NVME_SC_INTERNAL;
goto err;
}
smart_log = buf;
status = nvmet_get_smart_log(req, smart_log);
if (status)
goto err;
break;
case NVME_LOG_FW_SLOT:
/*
* We only support a single firmware slot which always is
* active, so we can zero out the whole firmware slot log and
* still claim to fully implement this mandatory log page.
*/
break;
default:
BUG();
}
status = nvmet_copy_to_sgl(req, 0, buf, data_len); if (req->cmd->get_log_page.nsid == cpu_to_le32(NVME_NSID_ALL))
status = nvmet_get_smart_log_all(req, log);
else
status = nvmet_get_smart_log_nsid(req, log);
if (status)
goto out;
err: status = nvmet_copy_to_sgl(req, 0, log, sizeof(*log));
kfree(buf);
out: out:
nvmet_req_complete(req, status); nvmet_req_complete(req, status);
} }
...@@ -566,9 +523,25 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req) ...@@ -566,9 +523,25 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
switch (cmd->get_log_page.lid) { switch (cmd->get_log_page.lid) {
case NVME_LOG_ERROR: case NVME_LOG_ERROR:
/*
* We currently never set the More bit in the status
* field, so all error log entries are invalid and can
* be zeroed out. This is called a minum viable
* implementation (TM) of this mandatory log page.
*/
req->execute = nvmet_execute_get_log_page_noop;
return 0;
case NVME_LOG_SMART: case NVME_LOG_SMART:
req->execute = nvmet_execute_get_log_page_smart;
return 0;
case NVME_LOG_FW_SLOT: case NVME_LOG_FW_SLOT:
req->execute = nvmet_execute_get_log_page; /*
* We only support a single firmware slot which always
* is active, so we can zero out the whole firmware slot
* log and still claim to fully implement this mandatory
* log page.
*/
req->execute = nvmet_execute_get_log_page_noop;
return 0; return 0;
} }
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册