Commit b89ad845 authored by Curt Bruns's avatar Curt Bruns Committed by Tomasz Zawadzki
Browse files

nvme: add support for NVME_IOCTL_IO_CMD for cuse



Nvme-cli uses NVME_IOCTL_IO_CMDs for "io-passthru"
commands to cuse devices.  This patch adds support
for that IOCTL.

Signed-off-by: default avatarCurt Bruns <curt.e.bruns@gmail.com>
Change-Id: I20e0ac91ba08fce91bc5da1f4a1e454058cdd1e7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7741


Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent f3edd7a3
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ cuse_nvme_passthru_cmd_execute(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, voi

static void
cuse_nvme_passthru_cmd_send(fuse_req_t req, struct nvme_passthru_cmd *passthru_cmd,
			    const void *data)
			    const void *data, int cmd)
{
	struct cuse_io_ctx *ctx;
	struct cuse_device *cuse_device = fuse_req_userdata(req);
@@ -185,7 +185,13 @@ cuse_nvme_passthru_cmd_send(fuse_req_t req, struct nvme_passthru_cmd *passthru_c
		}
	}

	if ((unsigned int)cmd != NVME_IOCTL_ADMIN_CMD) {
		/* Send NS for IO IOCTLs */
		rv = nvme_io_msg_send(cuse_device->ctrlr, passthru_cmd->nsid, cuse_nvme_passthru_cmd_execute, ctx);
	} else {
		/* NS == 0 for Admin IOCTLs */
		rv = nvme_io_msg_send(cuse_device->ctrlr, 0, cuse_nvme_passthru_cmd_execute, ctx);
	}
	if (rv) {
		SPDK_ERRLOG("Cannot send io msg to the controller\n");
		fuse_reply_err(req, -rv);
@@ -220,9 +226,9 @@ cuse_nvme_passthru_cmd(fuse_req_t req, int cmd, void *arg,
				fuse_reply_ioctl_retry(req, in_iov, 2, NULL, 0);
				return;
			}
			cuse_nvme_passthru_cmd_send(req, passthru_cmd, in_buf + sizeof(*passthru_cmd));
			cuse_nvme_passthru_cmd_send(req, passthru_cmd, in_buf + sizeof(*passthru_cmd), cmd);
		} else {
			cuse_nvme_passthru_cmd_send(req, passthru_cmd, NULL);
			cuse_nvme_passthru_cmd_send(req, passthru_cmd, NULL, cmd);
		}
		return;
	case SPDK_NVME_DATA_NONE:
@@ -240,7 +246,7 @@ cuse_nvme_passthru_cmd(fuse_req_t req, int cmd, void *arg,
			return;
		}

		cuse_nvme_passthru_cmd_send(req, passthru_cmd, NULL);
		cuse_nvme_passthru_cmd_send(req, passthru_cmd, NULL, cmd);

		return;
	case SPDK_NVME_DATA_BIDIRECTIONAL:
@@ -614,6 +620,11 @@ cuse_ns_ioctl(fuse_req_t req, int cmd, void *arg,
		cuse_nvme_submit_io(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
		break;

	case NVME_IOCTL_IO_CMD:
		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_IO_CMD\n");
		cuse_nvme_passthru_cmd(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
		break;

	case NVME_IOCTL_ID:
		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_ID\n");
		cuse_getid(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
+54 −0
Original line number Diff line number Diff line
@@ -101,6 +101,14 @@ nvme_io_msg_send(struct spdk_nvme_ctrlr *ctrlr,
	return 0;
}

struct cuse_device *g_cuse_device;
DEFINE_RETURN_MOCK(fuse_req_userdata, void *);
void *
fuse_req_userdata(fuse_req_t req)
{
	return g_cuse_device;
}

static void
test_cuse_nvme_submit_io_read_write(void)
{
@@ -151,6 +159,51 @@ test_cuse_nvme_submit_io_read_write(void)
	free(user_io);
}

static void
test_cuse_nvme_submit_passthru_cmd(void)
{
	struct nvme_passthru_cmd *passthru_cmd = NULL;
	fuse_req_t req = (void *)0xDEEACDFF;

	passthru_cmd = calloc(1, sizeof(struct nvme_passthru_cmd));
	g_cuse_device = calloc(1, sizeof(struct cuse_device));

	/* Use fatal or we'll segfault if we didn't get memory */
	SPDK_CU_ASSERT_FATAL(passthru_cmd != NULL);
	SPDK_CU_ASSERT_FATAL(g_cuse_device != NULL);
	g_cuse_device->ctrlr = (void *)0xDEADBEEF;

	g_ut_ctx = NULL;
	/* Passthrough command */
	passthru_cmd->opcode   = SPDK_NVME_DATA_CONTROLLER_TO_HOST;
	passthru_cmd->nsid     = 1;
	passthru_cmd->data_len = 512;
	passthru_cmd->cdw10    = 0xc0de1010;
	passthru_cmd->cdw11    = 0xc0de1111;
	passthru_cmd->cdw12    = 0xc0de1212;
	passthru_cmd->cdw13    = 0xc0de1313;
	passthru_cmd->cdw14    = 0xc0de1414;
	passthru_cmd->cdw15    = 0xc0de1515;

	/* Send IO Command IOCTL */
	cuse_nvme_passthru_cmd_send(req, passthru_cmd, NULL, NVME_IOCTL_IO_CMD);
	SPDK_CU_ASSERT_FATAL(g_ut_ctx != NULL);
	CU_ASSERT(g_ut_ctx->data != NULL);
	CU_ASSERT(g_ut_ctx->req               == req);
	CU_ASSERT(g_ut_ctx->data_len          == 512);
	CU_ASSERT(g_ut_ctx->nvme_cmd.opc      == SPDK_NVME_DATA_CONTROLLER_TO_HOST);
	CU_ASSERT(g_ut_ctx->nvme_cmd.nsid     == 1);
	CU_ASSERT(g_ut_ctx->nvme_cmd.cdw10    == 0xc0de1010);
	CU_ASSERT(g_ut_ctx->nvme_cmd.cdw11    == 0xc0de1111);
	CU_ASSERT(g_ut_ctx->nvme_cmd.cdw12    == 0xc0de1212);
	CU_ASSERT(g_ut_ctx->nvme_cmd.cdw13    == 0xc0de1313);
	CU_ASSERT(g_ut_ctx->nvme_cmd.cdw14    == 0xc0de1414);
	CU_ASSERT(g_ut_ctx->nvme_cmd.cdw15    == 0xc0de1515);

	cuse_io_ctx_free(g_ut_ctx);
	free(passthru_cmd);
}

int main(int argc, char **argv)
{
	CU_pSuite	suite = NULL;
@@ -161,6 +214,7 @@ int main(int argc, char **argv)

	suite = CU_add_suite("nvme_cuse", NULL, NULL);
	CU_ADD_TEST(suite, test_cuse_nvme_submit_io_read_write);
	CU_ADD_TEST(suite, test_cuse_nvme_submit_passthru_cmd);

	CU_basic_set_mode(CU_BRM_VERBOSE);
	CU_basic_run_tests();