Commit 3a1f7c79 authored by Chaitanya Kulkarni's avatar Chaitanya Kulkarni Committed by Christoph Hellwig
Browse files

nvmet: make nvmet_find_namespace() req based



The six callers of nvmet_find_namespace() duplicate the error log page
update and status setting code for each call on failure.

All callers are nvmet requests based functions, so we can pass req
to the nvmet_find_namesapce() & derive ctrl from req, that'll allow us
to update the error log page in nvmet_find_namespace(). Now that we
pass the request we can also get rid of the local variable in
nvmet_find_namespace() and use the req->ns and return the error code.

Replace the ctrl parameter with nvmet_req for nvmet_find_namespace(),
centralize the error log page update for non allocated namesapces, and
return uniform error for non-allocated namespace.

The nvmet_find_namespace() takes nsid parameter which is from NVMe
commands structures such as get_log_page, identify, rw and common. All
these commands have same offset for the nsid field.

Derive nsid from req->cmd->common.nsid) & remove the extra parameter
from the nvmet_find_namespace().

Lastly now we associate the ns to the req parameter that we pass to the
nvmet_find_namespace(), rename nvmet_find_namespace() to
nvmet_req_find_ns().

Signed-off-by: default avatarChaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent aa0aff60
Loading
Loading
Loading
Loading
+18 −28
Original line number Original line Diff line number Diff line
@@ -75,15 +75,11 @@ static u16 nvmet_get_smart_log_nsid(struct nvmet_req *req,
		struct nvme_smart_log *slog)
		struct nvme_smart_log *slog)
{
{
	u64 host_reads, host_writes, data_units_read, data_units_written;
	u64 host_reads, host_writes, data_units_read, data_units_written;
	u16 status;


	req->ns = nvmet_find_namespace(req->sq->ctrl,
	status = nvmet_req_find_ns(req);
				       req->cmd->get_log_page.nsid);
	if (status)
	if (!req->ns) {
		return status;
		pr_err("Could not find namespace id : %d\n",
				le32_to_cpu(req->cmd->get_log_page.nsid));
		req->error_loc = offsetof(struct nvme_rw_command, nsid);
		return NVME_SC_INVALID_NS | NVME_SC_DNR;
	}


	/* we don't have the right data for file backed ns */
	/* we don't have the right data for file backed ns */
	if (!req->ns->bdev)
	if (!req->ns->bdev)
@@ -468,7 +464,7 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
{
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvme_id_ns *id;
	struct nvme_id_ns *id;
	u16 status = 0;
	u16 status;


	if (le32_to_cpu(req->cmd->identify.nsid) == NVME_NSID_ALL) {
	if (le32_to_cpu(req->cmd->identify.nsid) == NVME_NSID_ALL) {
		req->error_loc = offsetof(struct nvme_identify, nsid);
		req->error_loc = offsetof(struct nvme_identify, nsid);
@@ -483,8 +479,8 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
	}
	}


	/* return an all zeroed buffer if we can't find an active namespace */
	/* return an all zeroed buffer if we can't find an active namespace */
	req->ns = nvmet_find_namespace(ctrl, req->cmd->identify.nsid);
	status = nvmet_req_find_ns(req);
	if (!req->ns) {
	if (status) {
		status = 0;
		status = 0;
		goto done;
		goto done;
	}
	}
@@ -604,15 +600,12 @@ static u16 nvmet_copy_ns_identifier(struct nvmet_req *req, u8 type, u8 len,


static void nvmet_execute_identify_desclist(struct nvmet_req *req)
static void nvmet_execute_identify_desclist(struct nvmet_req *req)
{
{
	u16 status = 0;
	off_t off = 0;
	off_t off = 0;
	u16 status;


	req->ns = nvmet_find_namespace(req->sq->ctrl, req->cmd->identify.nsid);
	status = nvmet_req_find_ns(req);
	if (!req->ns) {
	if (status)
		req->error_loc = offsetof(struct nvme_identify, nsid);
		status = NVME_SC_INVALID_NS | NVME_SC_DNR;
		goto out;
		goto out;
	}


	if (memchr_inv(&req->ns->uuid, 0, sizeof(req->ns->uuid))) {
	if (memchr_inv(&req->ns->uuid, 0, sizeof(req->ns->uuid))) {
		status = nvmet_copy_ns_identifier(req, NVME_NIDT_UUID,
		status = nvmet_copy_ns_identifier(req, NVME_NIDT_UUID,
@@ -692,13 +685,11 @@ static u16 nvmet_set_feat_write_protect(struct nvmet_req *req)
{
{
	u32 write_protect = le32_to_cpu(req->cmd->common.cdw11);
	u32 write_protect = le32_to_cpu(req->cmd->common.cdw11);
	struct nvmet_subsys *subsys = req->sq->ctrl->subsys;
	struct nvmet_subsys *subsys = req->sq->ctrl->subsys;
	u16 status = NVME_SC_FEATURE_NOT_CHANGEABLE;
	u16 status;


	req->ns = nvmet_find_namespace(req->sq->ctrl, req->cmd->rw.nsid);
	status = nvmet_req_find_ns(req);
	if (unlikely(!req->ns)) {
	if (status)
		req->error_loc = offsetof(struct nvme_common_command, nsid);
		return status;
		return status = NVME_SC_INVALID_NS | NVME_SC_DNR;
	}


	mutex_lock(&subsys->lock);
	mutex_lock(&subsys->lock);
	switch (write_protect) {
	switch (write_protect) {
@@ -799,11 +790,10 @@ static u16 nvmet_get_feat_write_protect(struct nvmet_req *req)
	struct nvmet_subsys *subsys = req->sq->ctrl->subsys;
	struct nvmet_subsys *subsys = req->sq->ctrl->subsys;
	u32 result;
	u32 result;


	req->ns = nvmet_find_namespace(req->sq->ctrl, req->cmd->common.nsid);
	result = nvmet_req_find_ns(req);
	if (!req->ns)  {
	if (result)
		req->error_loc = offsetof(struct nvme_common_command, nsid);
		return result;
		return NVME_SC_INVALID_NS | NVME_SC_DNR;

	}
	mutex_lock(&subsys->lock);
	mutex_lock(&subsys->lock);
	if (req->ns->readonly == true)
	if (req->ns->readonly == true)
		result = NVME_NS_WRITE_PROTECT;
		result = NVME_NS_WRITE_PROTECT;
+13 −11
Original line number Original line Diff line number Diff line
@@ -417,15 +417,18 @@ void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl)
	cancel_delayed_work_sync(&ctrl->ka_work);
	cancel_delayed_work_sync(&ctrl->ka_work);
}
}


struct nvmet_ns *nvmet_find_namespace(struct nvmet_ctrl *ctrl, __le32 nsid)
u16 nvmet_req_find_ns(struct nvmet_req *req)
{
{
	struct nvmet_ns *ns;
	u32 nsid = le32_to_cpu(req->cmd->common.nsid);


	ns = xa_load(&ctrl->subsys->namespaces, le32_to_cpu(nsid));
	req->ns = xa_load(&req->sq->ctrl->subsys->namespaces, nsid);
	if (ns)
	if (unlikely(!req->ns)) {
		percpu_ref_get(&ns->ref);
		req->error_loc = offsetof(struct nvme_common_command, nsid);
		return NVME_SC_INVALID_NS | NVME_SC_DNR;
	}


	return ns;
	percpu_ref_get(&req->ns->ref);
	return NVME_SC_SUCCESS;
}
}


static void nvmet_destroy_namespace(struct percpu_ref *ref)
static void nvmet_destroy_namespace(struct percpu_ref *ref)
@@ -862,11 +865,10 @@ static u16 nvmet_parse_io_cmd(struct nvmet_req *req)
	if (nvmet_req_passthru_ctrl(req))
	if (nvmet_req_passthru_ctrl(req))
		return nvmet_parse_passthru_io_cmd(req);
		return nvmet_parse_passthru_io_cmd(req);


	req->ns = nvmet_find_namespace(req->sq->ctrl, cmd->rw.nsid);
	ret = nvmet_req_find_ns(req);
	if (unlikely(!req->ns)) {
	if (unlikely(ret))
		req->error_loc = offsetof(struct nvme_common_command, nsid);
		return ret;
		return NVME_SC_INVALID_NS | NVME_SC_DNR;

	}
	ret = nvmet_check_ana_state(req->port, req->ns);
	ret = nvmet_check_ana_state(req->port, req->ns);
	if (unlikely(ret)) {
	if (unlikely(ret)) {
		req->error_loc = offsetof(struct nvme_common_command, nsid);
		req->error_loc = offsetof(struct nvme_common_command, nsid);
+1 −1
Original line number Original line Diff line number Diff line
@@ -443,7 +443,7 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
void nvmet_subsys_put(struct nvmet_subsys *subsys);
void nvmet_subsys_put(struct nvmet_subsys *subsys);
void nvmet_subsys_del_ctrls(struct nvmet_subsys *subsys);
void nvmet_subsys_del_ctrls(struct nvmet_subsys *subsys);


struct nvmet_ns *nvmet_find_namespace(struct nvmet_ctrl *ctrl, __le32 nsid);
u16 nvmet_req_find_ns(struct nvmet_req *req);
void nvmet_put_namespace(struct nvmet_ns *ns);
void nvmet_put_namespace(struct nvmet_ns *ns);
int nvmet_ns_enable(struct nvmet_ns *ns);
int nvmet_ns_enable(struct nvmet_ns *ns);
void nvmet_ns_disable(struct nvmet_ns *ns);
void nvmet_ns_disable(struct nvmet_ns *ns);