bdev/rbd: Reset returns completion after all inflight I/Os complete
Previously, reset just set a long timer to wait until all inflight I/Os complete. As already noted as a TODO item, check if any I/O is still inflight before completing the reset by using a new API spdk_bdev_get_current_qd(). The RBD bdev module can count outstanding I/Os itself but is not efficient. Signed-off-by: liu-darong <liu.darong@xsky.com> Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Change-Id: Iecaf90b06cae8e21198ec3822b978b54f5404d2b Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13945 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Dong Yi <yidong0635@126.com> Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com> Reviewed-by: GangCao <gang.cao@intel.com>
This commit is contained in:
parent
cad6f55e33
commit
72cb529751
@ -458,18 +458,38 @@ static struct spdk_bdev_module rbd_if = {
|
||||
};
|
||||
SPDK_BDEV_MODULE_REGISTER(rbd, &rbd_if)
|
||||
|
||||
static int bdev_rbd_reset_timer(void *arg);
|
||||
|
||||
static void
|
||||
bdev_rbd_check_outstanding_ios(struct spdk_bdev *bdev, uint64_t current_qd,
|
||||
void *cb_arg, int rc)
|
||||
{
|
||||
struct bdev_rbd *disk = cb_arg;
|
||||
enum spdk_bdev_io_status bio_status;
|
||||
|
||||
if (rc == 0 && current_qd > 0) {
|
||||
disk->reset_timer = SPDK_POLLER_REGISTER(bdev_rbd_reset_timer, disk, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
bio_status = SPDK_BDEV_IO_STATUS_FAILED;
|
||||
} else {
|
||||
bio_status = SPDK_BDEV_IO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bdev_rbd_io_complete(disk->reset_bdev_io, bio_status);
|
||||
disk->reset_bdev_io = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
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.
|
||||
*/
|
||||
bdev_rbd_io_complete(disk->reset_bdev_io, SPDK_BDEV_IO_STATUS_SUCCESS);
|
||||
spdk_poller_unregister(&disk->reset_timer);
|
||||
disk->reset_bdev_io = NULL;
|
||||
|
||||
spdk_bdev_get_current_qd(&disk->disk, bdev_rbd_check_outstanding_ios, disk);
|
||||
|
||||
return SPDK_POLLER_BUSY;
|
||||
}
|
||||
@ -479,11 +499,12 @@ 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.
|
||||
* poller 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);
|
||||
|
||||
bdev_rbd_reset_timer(disk);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user