Commit 26541489 authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Jim Harris
Browse files

nvmf: implement Get Log Page - Changed NS List

parent 0f15edee
Loading
Loading
Loading
Loading
+54 −7
Original line number Diff line number Diff line
@@ -988,10 +988,59 @@ spdk_nvmf_get_firmware_slot_log_page(void *buffer, uint64_t offset, uint32_t len
	}
}

void
spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
{
	uint16_t max_changes = SPDK_COUNTOF(ctrlr->changed_ns_list.ns_list);
	uint16_t i;
	bool found = false;

	for (i = 0; i < ctrlr->changed_ns_list_count; i++) {
		if (ctrlr->changed_ns_list.ns_list[i] == nsid) {
			/* nsid is already in the list */
			found = true;
			break;
		}
	}

	if (!found) {
		if (ctrlr->changed_ns_list_count == max_changes) {
			/* Out of space - set first entry to FFFFFFFFh and zero-fill the rest. */
			ctrlr->changed_ns_list.ns_list[0] = 0xFFFFFFFFu;
			for (i = 1; i < max_changes; i++) {
				ctrlr->changed_ns_list.ns_list[i] = 0;
			}
		} else {
			ctrlr->changed_ns_list.ns_list[ctrlr->changed_ns_list_count++] = nsid;
		}
	}

	spdk_nvmf_ctrlr_async_event_ns_notice(ctrlr);
}

static void
spdk_nvmf_get_changed_ns_list_log_page(struct spdk_nvmf_ctrlr *ctrlr,
				       void *buffer, uint64_t offset, uint32_t length)
{
	size_t copy_length;

	if (offset < sizeof(ctrlr->changed_ns_list)) {
		copy_length = spdk_min(length, sizeof(ctrlr->changed_ns_list) - offset);
		if (copy_length) {
			memcpy(buffer, (char *)&ctrlr->changed_ns_list + offset, copy_length);
		}
	}

	/* Clear log page each time it is read */
	ctrlr->changed_ns_list_count = 0;
	memset(&ctrlr->changed_ns_list, 0, sizeof(ctrlr->changed_ns_list));
}

static int
spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
{
	struct spdk_nvmf_subsystem *subsystem = req->qpair->ctrlr->subsys;
	struct spdk_nvmf_ctrlr *ctrlr = req->qpair->ctrlr;
	struct spdk_nvmf_subsystem *subsystem = ctrlr->subsys;
	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
	struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl;
	uint64_t offset, len;
@@ -1048,6 +1097,9 @@ spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
		case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG:
			spdk_nvmf_get_cmds_and_effects_log_page(req->data, offset, len);
			return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
		case SPDK_NVME_LOG_CHANGED_NS_LIST:
			spdk_nvmf_get_changed_ns_list_log_page(ctrlr, req->data, offset, len);
			return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
		default:
			goto invalid_log_page;
		}
@@ -1568,12 +1620,7 @@ spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr)

	event.bits.async_event_type = SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE;
	event.bits.async_event_info = SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED;
	/* Alternatively, host may request Changed Namespace List log(04h)
	 * to determine which namespaces have changed. While here, we
	 * set invalid log page identifier to indicate that host doesn't
	 * need to send such log page.
	 */
	event.bits.log_page_identifier = 0;
	event.bits.log_page_identifier = SPDK_NVME_LOG_CHANGED_NS_LIST;

	/* If there is no outstanding AER request, queue the event.  Then
	 * if an AER is later submitted, this event can be sent as a
+4 −0
Original line number Diff line number Diff line
@@ -189,6 +189,9 @@ struct spdk_nvmf_ctrlr {
	union spdk_nvme_async_event_completion notice_event;
	uint8_t hostid[16];

	uint16_t changed_ns_list_count;
	struct spdk_nvme_ns_list changed_ns_list;

	TAILQ_ENTRY(spdk_nvmf_ctrlr)		link;
};

@@ -252,6 +255,7 @@ int spdk_nvmf_ctrlr_process_admin_cmd(struct spdk_nvmf_request *req);
int spdk_nvmf_ctrlr_process_io_cmd(struct spdk_nvmf_request *req);
bool spdk_nvmf_ctrlr_dsm_supported(struct spdk_nvmf_ctrlr *ctrlr);
bool spdk_nvmf_ctrlr_write_zeroes_supported(struct spdk_nvmf_ctrlr *ctrlr);
void spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid);

int spdk_nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata);

+1 −1
Original line number Diff line number Diff line
@@ -816,7 +816,7 @@ spdk_nvmf_subsystem_ns_changed(struct spdk_nvmf_subsystem *subsystem, uint32_t n
	struct spdk_nvmf_ctrlr *ctrlr;

	TAILQ_FOREACH(ctrlr, &subsystem->ctrlrs, link) {
		spdk_nvmf_ctrlr_async_event_ns_notice(ctrlr);
		spdk_nvmf_ctrlr_ns_changed(ctrlr, nsid);
	}
}

+5 −6
Original line number Diff line number Diff line
@@ -153,6 +153,11 @@ spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1,
	return 0;
}

void
spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
{
}

void
spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
{
@@ -186,12 +191,6 @@ spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group,
	return 0;
}

int
spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr)
{
	return 0;
}

static void
test_discovery_log(void)
{
+5 −6
Original line number Diff line number Diff line
@@ -183,6 +183,11 @@ spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
{
}

void
spdk_nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
{
}

int
spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb,
	       void *remove_ctx, struct spdk_bdev_desc **desc)
@@ -207,12 +212,6 @@ spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
	return &bdev->uuid;
}

int
spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr)
{
	return 0;
}

static void
test_spdk_nvmf_subsystem_add_ns(void)
{