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 <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-08-24 10:25:49 -07:00
parent 1b957fa58e
commit 9272088d93
5 changed files with 87 additions and 21 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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 {