From f84d1a53be885c605ca6ee6375fc09bbcb7e91d2 Mon Sep 17 00:00:00 2001 From: Dariusz Stojaczyk Date: Wed, 3 Jan 2018 12:43:38 +0100 Subject: [PATCH] bdev/virtio/blk: implement read-only Support the virtio RO flag, so that read-only devices will successfully initialize now. Also do not allow issuing any writes on a read-only device, so we don't flood it with requests that are to fail. Change-Id: I6b77f2338e4478a9abf2d5286344f6412d79284c Signed-off-by: Dariusz Stojaczyk Reviewed-on: https://review.gerrithub.io/393461 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Changpeng Liu --- lib/bdev/virtio/bdev_virtio_blk.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/bdev/virtio/bdev_virtio_blk.c b/lib/bdev/virtio/bdev_virtio_blk.c index aabe423ff..8fdcdd6c0 100644 --- a/lib/bdev/virtio/bdev_virtio_blk.c +++ b/lib/bdev/virtio/bdev_virtio_blk.c @@ -54,6 +54,7 @@ struct virtio_blk_dev { struct virtio_dev vdev; struct spdk_bdev bdev; + bool readonly; }; struct virtio_blk_io_ctx { @@ -77,7 +78,8 @@ struct bdev_virtio_blk_io_channel { #define VIRTIO_BLK_DEV_SUPPORTED_FEATURES \ (1ULL << VIRTIO_BLK_F_BLK_SIZE | \ 1ULL << VIRTIO_BLK_F_TOPOLOGY | \ - 1ULL << VIRTIO_BLK_F_MQ) + 1ULL << VIRTIO_BLK_F_MQ | \ + 1ULL << VIRTIO_BLK_F_RO) static int bdev_virtio_initialize(void); static int bdev_virtio_blk_get_ctx_size(void); @@ -157,13 +159,19 @@ bdev_virtio_rw(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) static int _bdev_virtio_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io) { + struct virtio_blk_dev *bvdev = bdev_io->bdev->ctxt; + switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: spdk_bdev_io_get_buf(bdev_io, bdev_virtio_rw, bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); return 0; case SPDK_BDEV_IO_TYPE_WRITE: - bdev_virtio_rw(ch, bdev_io); + if (bvdev->readonly) { + spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); + } else { + bdev_virtio_rw(ch, bdev_io); + } return 0; case SPDK_BDEV_IO_TYPE_RESET: spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS); @@ -188,11 +196,14 @@ bdev_virtio_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev static bool bdev_virtio_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type) { + struct virtio_blk_dev *bvdev = ctx; + switch (io_type) { case SPDK_BDEV_IO_TYPE_READ: - case SPDK_BDEV_IO_TYPE_WRITE: case SPDK_BDEV_IO_TYPE_RESET: return true; + case SPDK_BDEV_IO_TYPE_WRITE: + return !bvdev->readonly; case SPDK_BDEV_IO_TYPE_FLUSH: case SPDK_BDEV_IO_TYPE_UNMAP: default: @@ -352,6 +363,10 @@ virtio_blk_dev_init(struct virtio_blk_dev *bvdev, uint16_t max_queues) host_max_queues = 1; } + if (virtio_dev_has_feature(vdev, VIRTIO_BLK_F_RO)) { + bvdev->readonly = true; + } + if (max_queues == 0) { SPDK_ERRLOG("%s: requested 0 request queues (%"PRIu16" available).\n", vdev->name, host_max_queues);