drivers/nvme/target/pr.c

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

File Facts

System
Linux kernel
Corpus path
drivers/nvme/target/pr.c
Extension
.c
Size
29720 bytes
Lines
1156
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

nvmet_pr_find_registrant(pr, &ctrl->hostid)) {
			nvmet_pr_add_resv_log(ctrl,
				NVME_PR_LOG_RESERVATION_RELEASED, ns->nsid);
			nvmet_add_async_event(ctrl, NVME_AER_CSS,
				NVME_AEN_RESV_LOG_PAGE_AVALIABLE,
				NVME_LOG_RESERVATION);
		}
	}
	mutex_unlock(&subsys->lock);
}

static void nvmet_pr_send_event_to_host(struct nvmet_pr *pr, uuid_t *hostid,
					  u8 log_type)
{
	struct nvmet_ns *ns = nvmet_pr_to_ns(pr);
	struct nvmet_subsys *subsys = ns->subsys;
	struct nvmet_ctrl *ctrl;

	mutex_lock(&subsys->lock);
	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
		if (uuid_equal(hostid, &ctrl->hostid)) {
			nvmet_pr_add_resv_log(ctrl, log_type, ns->nsid);
			nvmet_add_async_event(ctrl, NVME_AER_CSS,
				NVME_AEN_RESV_LOG_PAGE_AVALIABLE,
				NVME_LOG_RESERVATION);
		}
	}
	mutex_unlock(&subsys->lock);
}

static void nvmet_pr_resv_preempted(struct nvmet_pr *pr, uuid_t *hostid)
{
	if (test_bit(NVME_PR_NOTIFY_BIT_RESV_PREEMPTED, &pr->notify_mask))
		return;

	nvmet_pr_send_event_to_host(pr, hostid,
		NVME_PR_LOG_RESERVATOIN_PREEMPTED);
}

static void nvmet_pr_registration_preempted(struct nvmet_pr *pr,
					    uuid_t *hostid)
{
	if (test_bit(NVME_PR_NOTIFY_BIT_REG_PREEMPTED, &pr->notify_mask))
		return;

	nvmet_pr_send_event_to_host(pr, hostid,
		NVME_PR_LOG_REGISTRATION_PREEMPTED);
}

static inline void nvmet_pr_set_new_holder(struct nvmet_pr *pr, u8 new_rtype,
					   struct nvmet_pr_registrant *reg)
{
	reg->rtype = new_rtype;
	rcu_assign_pointer(pr->holder, reg);
}

static u16 nvmet_pr_register(struct nvmet_req *req,
			     struct nvmet_pr_register_data *d)
{
	struct nvmet_ctrl *ctrl = req->sq->ctrl;
	struct nvmet_pr_registrant *new, *reg;
	struct nvmet_pr *pr = &req->ns->pr;
	u16 status = NVME_SC_SUCCESS;
	u64 nrkey = le64_to_cpu(d->nrkey);

	new = kmalloc_obj(*new);
	if (!new)
		return NVME_SC_INTERNAL;

	down(&pr->pr_sem);
	reg = nvmet_pr_find_registrant(pr, &ctrl->hostid);
	if (reg) {
		if (reg->rkey != nrkey)
			status = NVME_SC_RESERVATION_CONFLICT | NVME_STATUS_DNR;
		kfree(new);
		goto out;
	}

	memset(new, 0, sizeof(*new));
	INIT_LIST_HEAD(&new->entry);
	new->rkey = nrkey;
	uuid_copy(&new->hostid, &ctrl->hostid);
	list_add_tail_rcu(&new->entry, &pr->registrant_list);

out:
	up(&pr->pr_sem);
	return status;
}

static void nvmet_pr_unregister_one(struct nvmet_pr *pr,

Annotation

Implementation Notes