bdev/rbd: add semi-functional reset handling
Implement a poor approximation of reset handling for the RBD bdev so it can pass the bdevio tests. This should be replaced with a solution similar to bdev_aio, which waits for all outstanding I/O to return before completing the reset. However, this should ideally be handled by the generic bdev layer rather than in each individual module. Change-Id: I1be2bf90875e23e05efdebb003e5412f3fc43793 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-on: https://review.gerrithub.io/401273 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
bd069288d3
commit
d5dd730ce8
@ -60,6 +60,8 @@ struct bdev_rbd {
|
|||||||
char *pool_name;
|
char *pool_name;
|
||||||
rbd_image_info_t info;
|
rbd_image_info_t info;
|
||||||
TAILQ_ENTRY(bdev_rbd) tailq;
|
TAILQ_ENTRY(bdev_rbd) tailq;
|
||||||
|
struct spdk_poller *reset_timer;
|
||||||
|
struct spdk_bdev_io *reset_bdev_io;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bdev_rbd_io_channel {
|
struct bdev_rbd_io_channel {
|
||||||
@ -267,6 +269,34 @@ bdev_rbd_flush(struct bdev_rbd *disk, struct spdk_io_channel *ch,
|
|||||||
return bdev_rbd_start_aio(rbdio_ch->image, bdev_io, NULL, offset, nbytes);
|
return bdev_rbd_start_aio(rbdio_ch->image, bdev_io, NULL, offset, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bdev_rbd_reset_timer(void *arg)
|
||||||
|
{
|
||||||
|
struct bdev_rbd *disk = arg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: This should check if any I/O is still in flight before completing the reset.
|
||||||
|
* For now, just complete after the timer expires.
|
||||||
|
*/
|
||||||
|
spdk_bdev_io_complete(disk->reset_bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
|
||||||
|
spdk_poller_unregister(&disk->reset_timer);
|
||||||
|
disk->reset_bdev_io = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bdev_rbd_reset(struct bdev_rbd *disk, struct spdk_bdev_io *bdev_io)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* HACK: Since librbd doesn't provide any way to cancel outstanding aio, just kick off a
|
||||||
|
* timer to wait for in-flight I/O to complete.
|
||||||
|
*/
|
||||||
|
assert(disk->reset_bdev_io == NULL);
|
||||||
|
disk->reset_bdev_io = bdev_io;
|
||||||
|
disk->reset_timer = spdk_poller_register(bdev_rbd_reset_timer, disk, 1 * 1000 * 1000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bdev_rbd_destruct(void *ctx)
|
bdev_rbd_destruct(void *ctx)
|
||||||
{
|
{
|
||||||
@ -316,6 +346,11 @@ static int _bdev_rbd_submit_request(struct spdk_io_channel *ch, struct spdk_bdev
|
|||||||
bdev_io,
|
bdev_io,
|
||||||
bdev_io->u.bdev.offset_blocks * bdev_io->bdev->blocklen,
|
bdev_io->u.bdev.offset_blocks * bdev_io->bdev->blocklen,
|
||||||
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||||
|
|
||||||
|
case SPDK_BDEV_IO_TYPE_RESET:
|
||||||
|
return bdev_rbd_reset((struct bdev_rbd *)bdev_io->bdev->ctxt,
|
||||||
|
bdev_io);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -336,6 +371,7 @@ bdev_rbd_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type)
|
|||||||
case SPDK_BDEV_IO_TYPE_READ:
|
case SPDK_BDEV_IO_TYPE_READ:
|
||||||
case SPDK_BDEV_IO_TYPE_WRITE:
|
case SPDK_BDEV_IO_TYPE_WRITE:
|
||||||
case SPDK_BDEV_IO_TYPE_FLUSH:
|
case SPDK_BDEV_IO_TYPE_FLUSH:
|
||||||
|
case SPDK_BDEV_IO_TYPE_RESET:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user