Commit a9593c79 authored by Evgeniy Kochetov's avatar Evgeniy Kochetov Committed by Tomasz Zawadzki
Browse files

bdev: Fail nvme passthru command if not supported by bdev



The originally detected problem is that SPDK NVMf target fails command
with invalid opcode with status code INTERNAL_DEVICE_ERROR instead of
INVALID_OPCODE. All unknown commands on IO queue are passed to
underlying block device layer as NVME_IO type. It is not checked if
this type of commands is supported and, when command fails,
INTERNAL_DEVICE_ERROR is set as status code. If command fails on
submission, status code is set to INVALID_OPCODE which is more
relevant.

This patch adds check if command type is supported to
bdev_nvme_*_passthru functions. If not supported, it is failed with
ENOTSUP.

Signed-off-by: default avatarEvgeniy Kochetov <evgeniik@nvidia.com>
Change-Id: I4d7f7639da17dd3b1dc3eee7eb1b4a4f876117a2
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8567


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
parent c9c7c281
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -4927,6 +4927,10 @@ spdk_bdev_nvme_admin_passthru(struct spdk_bdev_desc *desc, struct spdk_io_channe
		return -EBADF;
	}

	if (spdk_unlikely(!bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_ADMIN))) {
		return -ENOTSUP;
	}

	bdev_io = bdev_channel_get_io(channel);
	if (!bdev_io) {
		return -ENOMEM;
@@ -4965,6 +4969,10 @@ spdk_bdev_nvme_io_passthru(struct spdk_bdev_desc *desc, struct spdk_io_channel *
		return -EBADF;
	}

	if (spdk_unlikely(!bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_IO))) {
		return -ENOTSUP;
	}

	bdev_io = bdev_channel_get_io(channel);
	if (!bdev_io) {
		return -ENOMEM;
@@ -5003,6 +5011,10 @@ spdk_bdev_nvme_io_passthru_md(struct spdk_bdev_desc *desc, struct spdk_io_channe
		return -EBADF;
	}

	if (spdk_unlikely(!bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_NVME_IO_MD))) {
		return -ENOTSUP;
	}

	bdev_io = bdev_channel_get_io(channel);
	if (!bdev_io) {
		return -ENOMEM;
+14 −0
Original line number Diff line number Diff line
@@ -967,6 +967,20 @@ bdev_io_types_test(void)
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, true);
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE, true);

	/* NVME_IO, NVME_IO_MD and NVME_ADMIN are not supported */
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO, false);
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO_MD, false);
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_ADMIN, false);
	rc = spdk_bdev_nvme_io_passthru(desc, io_ch, NULL, NULL, 0, NULL, NULL);
	CU_ASSERT(rc == -ENOTSUP);
	rc = spdk_bdev_nvme_io_passthru_md(desc, io_ch, NULL, NULL, 0, NULL, 0, NULL, NULL);
	CU_ASSERT(rc == -ENOTSUP);
	rc = spdk_bdev_nvme_admin_passthru(desc, io_ch, NULL, NULL, 0, NULL, NULL);
	CU_ASSERT(rc == -ENOTSUP);
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO, true);
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_IO_MD, true);
	ut_enable_io_type(SPDK_BDEV_IO_TYPE_NVME_ADMIN, true);

	spdk_put_io_channel(io_ch);
	spdk_bdev_close(desc);
	free_bdev(bdev);