From 9272088d931c05f4f650a9696986108453e91540 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Wed, 24 Aug 2016 10:25:49 -0700 Subject: [PATCH] bdev: add API to query supported I/O types Some block devices do not support the unmap operation, and we may add other optional I/O types in the future. Add a method to check which I/O types a specific block device supports. Change-Id: I6e6414bf6b6482ea0224022d8326b252bd363c7f Signed-off-by: Daniel Verkamp --- include/spdk/bdev.h | 23 ++++++++++++++--------- lib/bdev/aio/blockdev_aio.c | 24 ++++++++++++++++++++---- lib/bdev/bdev.c | 6 ++++++ lib/bdev/malloc/blockdev_malloc.c | 24 ++++++++++++++++++++---- lib/bdev/nvme/blockdev_nvme.c | 31 +++++++++++++++++++++++++++---- 5 files changed, 87 insertions(+), 21 deletions(-) diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index 51274707dc..bc08812147 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -154,6 +154,16 @@ struct spdk_bdev { TAILQ_ENTRY(spdk_bdev) link; }; +/** Blockdev I/O type */ +enum spdk_bdev_io_type { + SPDK_BDEV_IO_TYPE_INVALID, + SPDK_BDEV_IO_TYPE_READ, + SPDK_BDEV_IO_TYPE_WRITE, + SPDK_BDEV_IO_TYPE_UNMAP, + SPDK_BDEV_IO_TYPE_FLUSH, + SPDK_BDEV_IO_TYPE_RESET, +}; + /** * Function table for a block device backend. * @@ -173,16 +183,9 @@ struct spdk_bdev_fn_table { /** Release buf for read command. */ void (*free_request)(struct spdk_bdev_io *); -}; -/** Blockdev I/O type */ -enum spdk_bdev_io_type { - SPDK_BDEV_IO_TYPE_INVALID, - SPDK_BDEV_IO_TYPE_READ, - SPDK_BDEV_IO_TYPE_WRITE, - SPDK_BDEV_IO_TYPE_UNMAP, - SPDK_BDEV_IO_TYPE_FLUSH, - SPDK_BDEV_IO_TYPE_RESET, + /** Check if the block device supports a specific I/O type. */ + bool (*io_type_supported)(struct spdk_bdev *bdev, enum spdk_bdev_io_type); }; /** Blockdev I/O completion status */ @@ -369,6 +372,8 @@ struct spdk_bdev *spdk_bdev_get_by_name(const char *bdev_name); struct spdk_bdev *spdk_bdev_first(void); struct spdk_bdev *spdk_bdev_next(struct spdk_bdev *prev); +bool spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type); + struct spdk_bdev_io *spdk_bdev_read(struct spdk_bdev *bdev, void *buf, uint64_t nbytes, uint64_t offset, spdk_bdev_io_completion_cb cb, void *cb_arg); diff --git a/lib/bdev/aio/blockdev_aio.c b/lib/bdev/aio/blockdev_aio.c index a50e735e3b..a9f71fc47c 100644 --- a/lib/bdev/aio/blockdev_aio.c +++ b/lib/bdev/aio/blockdev_aio.c @@ -277,11 +277,27 @@ static void blockdev_aio_free_request(struct spdk_bdev_io *bdev_io) { } +static bool +blockdev_aio_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type) +{ + switch (io_type) { + case SPDK_BDEV_IO_TYPE_READ: + case SPDK_BDEV_IO_TYPE_WRITE: + case SPDK_BDEV_IO_TYPE_FLUSH: + case SPDK_BDEV_IO_TYPE_RESET: + return true; + + default: + return false; + } +} + static struct spdk_bdev_fn_table aio_fn_table = { - .destruct = blockdev_aio_destruct, - .check_io = blockdev_aio_check_io, - .submit_request = blockdev_aio_submit_request, - .free_request = blockdev_aio_free_request, + .destruct = blockdev_aio_destruct, + .check_io = blockdev_aio_check_io, + .submit_request = blockdev_aio_submit_request, + .free_request = blockdev_aio_free_request, + .io_type_supported = blockdev_aio_io_type_supported, }; static void aio_free_disk(struct file_disk *fdisk) diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index b4fd9dfa3f..aadfdbb27e 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -515,6 +515,12 @@ spdk_bdev_get_child_io(struct spdk_bdev_io *parent, return child; } +bool +spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type) +{ + return bdev->fn_table->io_type_supported(bdev, io_type); +} + struct spdk_bdev_io * spdk_bdev_read(struct spdk_bdev *bdev, void *buf, uint64_t nbytes, uint64_t offset, diff --git a/lib/bdev/malloc/blockdev_malloc.c b/lib/bdev/malloc/blockdev_malloc.c index f882494b88..622f7ae9e0 100644 --- a/lib/bdev/malloc/blockdev_malloc.c +++ b/lib/bdev/malloc/blockdev_malloc.c @@ -214,11 +214,27 @@ static void blockdev_malloc_free_request(struct spdk_bdev_io *bdev_io) { } +static bool +blockdev_malloc_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type) +{ + switch (io_type) { + case SPDK_BDEV_IO_TYPE_READ: + case SPDK_BDEV_IO_TYPE_WRITE: + case SPDK_BDEV_IO_TYPE_FLUSH: + case SPDK_BDEV_IO_TYPE_RESET: + return true; + + default: + return false; + } +} + static struct spdk_bdev_fn_table malloc_fn_table = { - .destruct = blockdev_malloc_destruct, - .check_io = blockdev_malloc_check_io, - .submit_request = blockdev_malloc_submit_request, - .free_request = blockdev_malloc_free_request, + .destruct = blockdev_malloc_destruct, + .check_io = blockdev_malloc_check_io, + .submit_request = blockdev_malloc_submit_request, + .free_request = blockdev_malloc_free_request, + .io_type_supported = blockdev_malloc_io_type_supported, }; struct malloc_disk *create_malloc_disk(uint64_t num_blocks, uint32_t block_size) diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index d09e92fa04..8139088de7 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -274,11 +274,34 @@ static void blockdev_nvme_free_request(struct spdk_bdev_io *bdev_io) { } +static bool +blockdev_nvme_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type) +{ + struct nvme_blockdev *nbdev = (struct nvme_blockdev *)bdev; + const struct spdk_nvme_ctrlr_data *cdata; + + switch (io_type) { + case SPDK_BDEV_IO_TYPE_READ: + case SPDK_BDEV_IO_TYPE_WRITE: + case SPDK_BDEV_IO_TYPE_RESET: + case SPDK_BDEV_IO_TYPE_FLUSH: + return true; + + case SPDK_BDEV_IO_TYPE_UNMAP: + cdata = spdk_nvme_ctrlr_get_data(nbdev->ctrlr); + return cdata->oncs.dsm; + + default: + return false; + } +} + static struct spdk_bdev_fn_table nvmelib_fn_table = { - .destruct = blockdev_nvme_destruct, - .check_io = blockdev_nvme_check_io, - .submit_request = blockdev_nvme_submit_request, - .free_request = blockdev_nvme_free_request, + .destruct = blockdev_nvme_destruct, + .check_io = blockdev_nvme_check_io, + .submit_request = blockdev_nvme_submit_request, + .free_request = blockdev_nvme_free_request, + .io_type_supported = blockdev_nvme_io_type_supported, }; struct nvme_probe_ctx {