drivers/nvme/target/admin-cmd.c

Source file repositories/reference/linux-study-clean/drivers/nvme/target/admin-cmd.c

File Facts

System
Linux kernel
Corpus path
drivers/nvme/target/admin-cmd.c
Extension
.c
Size
44436 bytes
Lines
1690
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
			status = NVME_SC_INVALID_IO_CMD_SET;
			goto free;
		}
		nvmet_get_cmd_effects_admin(ctrl, log);
		nvmet_get_cmd_effects_nvm(log);
		nvmet_get_cmd_effects_zns(log);
		break;
	default:
		status = NVME_SC_INVALID_LOG_PAGE;
		goto free;
	}

	status = nvmet_copy_to_sgl(req, 0, log, sizeof(*log));
free:
	kfree(log);
out:
	nvmet_req_complete(req, status);
}

static void nvmet_execute_get_log_changed_ns(struct nvmet_req *req)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	u16 status = NVME_SC_INTERNAL;
	size_t len;

	if (req->transfer_len != NVME_MAX_CHANGED_NAMESPACES * sizeof(__le32))
		goto out;

	mutex_lock(&ctrl->lock);
	if (ctrl->nr_changed_ns == U32_MAX)
		len = sizeof(__le32);
	else
		len = ctrl->nr_changed_ns * sizeof(__le32);
	status = nvmet_copy_to_sgl(req, 0, ctrl->changed_ns_list, len);
	if (!status)
		status = nvmet_zero_sgl(req, len, req->transfer_len - len);
	ctrl->nr_changed_ns = 0;
	nvmet_clear_aen_bit(req, NVME_AEN_BIT_NS_ATTR);
	mutex_unlock(&ctrl->lock);
out:
	nvmet_req_complete(req, status);
}

static u32 nvmet_format_ana_group(struct nvmet_req *req, u32 grpid,
		struct nvme_ana_group_desc *desc)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvmet_ns *ns;
	unsigned long idx;
	u32 count = 0;

	if (!(req->cmd->get_log_page.lsp & NVME_ANA_LOG_RGO)) {
		nvmet_for_each_enabled_ns(&ctrl->subsys->namespaces, idx, ns) {
			if (ns->anagrpid == grpid)
				desc->nsids[count++] = cpu_to_le32(ns->nsid);
		}
	}

	desc->grpid = cpu_to_le32(grpid);
	desc->nnsids = cpu_to_le32(count);
	desc->chgcnt = cpu_to_le64(nvmet_ana_chgcnt);
	desc->state = req->port->ana_state[grpid];
	memset(desc->rsvd17, 0, sizeof(desc->rsvd17));
	return struct_size(desc, nsids, count);
}

static void nvmet_execute_get_log_page_endgrp(struct nvmet_req *req)
{
	u64 host_reads, host_writes, data_units_read, data_units_written;
	struct nvme_endurance_group_log *log;
	u16 status;

	/*
	 * The target driver emulates each endurance group as its own
	 * namespace, reusing the nsid as the endurance group identifier.
	 */
	req->cmd->common.nsid = cpu_to_le32(le16_to_cpu(
					    req->cmd->get_log_page.lsi));
	status = nvmet_req_find_ns(req);
	if (status)
		goto out;

	log = kzalloc_obj(*log);
	if (!log) {
		status = NVME_SC_INTERNAL;
		goto out;
	}

	if (!req->ns->bdev)

Annotation

Implementation Notes