[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC Patch v3 14/22] switch to unprotected mode before closing
If the user wants to stop tapdisk2, he will do the following thing: 1. close the image 2. detach from blktap device If there is some pending I/O request, close will fail. But the I/O request is pended in remus until the connection is established. Introduce a new callback td_pre_close() to flush these I/O requests. Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> Cc: Shriram Rajagopalan <rshriram@xxxxxxxxx> --- tools/blktap2/drivers/block-remus.c | 15 +++++++++++++++ tools/blktap2/drivers/tapdisk-control.c | 6 ++++++ tools/blktap2/drivers/tapdisk-interface.c | 18 ++++++++++++++++++ tools/blktap2/drivers/tapdisk-interface.h | 1 + tools/blktap2/drivers/tapdisk-vbd.c | 9 +++++++++ tools/blktap2/drivers/tapdisk-vbd.h | 1 + tools/blktap2/drivers/tapdisk.h | 1 + 7 files changed, 51 insertions(+) diff --git a/tools/blktap2/drivers/block-remus.c b/tools/blktap2/drivers/block-remus.c index c21f851..5d27d41 100644 --- a/tools/blktap2/drivers/block-remus.c +++ b/tools/blktap2/drivers/block-remus.c @@ -96,6 +96,7 @@ enum { ERROR_INTERNAL = -1, ERROR_IO = -2, ERROR_CONNECTION = -3, + ERROR_CLOSE = -4, }; struct tdremus_req { @@ -810,6 +811,8 @@ static void primary_failed(struct tdremus_state *s, int rc) close_stream_fd(s); if (rc == ERROR_INTERNAL) RPRINTF("switch to unprotected mode due to internal error"); + if (rc == ERROR_CLOSE) + RPRINTF("switch to unprotected mode before closing"); switch_mode(s->tdremus_driver, mode_unprotected); } @@ -1910,6 +1913,17 @@ static int tdremus_open(td_driver_t *driver, td_image_t *image, td_uuid_t uuid) return -EIO; } +static int tdremus_pre_close(td_driver_t *driver) +{ + struct tdremus_state *s = (struct tdremus_state *)driver->data; + + if (s->mode != mode_primary) + return 0; + + primary_failed(s, ERROR_CLOSE); + return 0; +} + static int tdremus_close(td_driver_t *driver) { struct tdremus_state *s = (struct tdremus_state *)driver->data; @@ -1944,6 +1958,7 @@ struct tap_disk tapdisk_remus = { .td_open = tdremus_open, .td_queue_read = unprotected_queue_read, .td_queue_write = unprotected_queue_write, + .td_pre_close = tdremus_pre_close, .td_close = tdremus_close, .td_get_parent_id = tdremus_get_parent_id, .td_validate_parent = tdremus_validate_parent, diff --git a/tools/blktap2/drivers/tapdisk-control.c b/tools/blktap2/drivers/tapdisk-control.c index 4e5f748..2fa4cbe 100644 --- a/tools/blktap2/drivers/tapdisk-control.c +++ b/tools/blktap2/drivers/tapdisk-control.c @@ -508,6 +508,12 @@ tapdisk_control_close_image(struct tapdisk_control_connection *connection, goto out; } + /* + * Some I/O requests are pended in the driver, and + * flush these requests first. + */ + tapdisk_vbd_pre_close_vdi(vbd); + if (!list_empty(&vbd->pending_requests)) { err = -EAGAIN; goto out; diff --git a/tools/blktap2/drivers/tapdisk-interface.c b/tools/blktap2/drivers/tapdisk-interface.c index a29de64..ed92e12 100644 --- a/tools/blktap2/drivers/tapdisk-interface.c +++ b/tools/blktap2/drivers/tapdisk-interface.c @@ -105,6 +105,24 @@ td_open(td_image_t *image) } int +td_pre_close(td_image_t *image) +{ + td_driver_t *driver; + + driver = image->driver; + if (!driver) + return -ENODEV; + + if (!driver->ops->td_pre_close) + return 0; + + if (driver->refcnt && td_flag_test(driver->state, TD_DRIVER_OPEN)) + driver->ops->td_pre_close(driver); + + return 0; +} + +int td_close(td_image_t *image) { td_driver_t *driver; diff --git a/tools/blktap2/drivers/tapdisk-interface.h b/tools/blktap2/drivers/tapdisk-interface.h index adc4376..ba9b3ea 100644 --- a/tools/blktap2/drivers/tapdisk-interface.h +++ b/tools/blktap2/drivers/tapdisk-interface.h @@ -34,6 +34,7 @@ int td_open(td_image_t *); int __td_open(td_image_t *, td_disk_info_t *); int td_load(td_image_t *); +int td_pre_close(td_image_t *); int td_close(td_image_t *); int td_get_parent_id(td_image_t *, td_disk_id_t *); int td_validate_parent(td_image_t *, td_image_t *); diff --git a/tools/blktap2/drivers/tapdisk-vbd.c b/tools/blktap2/drivers/tapdisk-vbd.c index c665f27..aba545b 100644 --- a/tools/blktap2/drivers/tapdisk-vbd.c +++ b/tools/blktap2/drivers/tapdisk-vbd.c @@ -180,6 +180,15 @@ tapdisk_vbd_validate_chain(td_vbd_t *vbd) } void +tapdisk_vbd_pre_close_vdi(td_vbd_t *vbd) +{ + td_image_t *image, *tmp; + + tapdisk_vbd_for_each_image(vbd, image, tmp) + td_pre_close(image); +} + +void tapdisk_vbd_close_vdi(td_vbd_t *vbd) { td_image_t *image, *tmp; diff --git a/tools/blktap2/drivers/tapdisk-vbd.h b/tools/blktap2/drivers/tapdisk-vbd.h index be084b2..040f2b8 100644 --- a/tools/blktap2/drivers/tapdisk-vbd.h +++ b/tools/blktap2/drivers/tapdisk-vbd.h @@ -181,6 +181,7 @@ void tapdisk_vbd_free_stack(td_vbd_t *); int tapdisk_vbd_open_stack(td_vbd_t *, uint16_t, td_flag_t); int tapdisk_vbd_open_vdi(td_vbd_t *, const char *, uint16_t, uint16_t, td_flag_t); +void tapdisk_vbd_pre_close_vdi(td_vbd_t *); void tapdisk_vbd_close_vdi(td_vbd_t *); int tapdisk_vbd_attach(td_vbd_t *, const char *, int); diff --git a/tools/blktap2/drivers/tapdisk.h b/tools/blktap2/drivers/tapdisk.h index 3c3b51d..16efd07 100644 --- a/tools/blktap2/drivers/tapdisk.h +++ b/tools/blktap2/drivers/tapdisk.h @@ -158,6 +158,7 @@ struct tap_disk { td_flag_t flags; int private_data_size; int (*td_open) (td_driver_t *, td_image_t *, td_uuid_t); + int (*td_pre_close) (td_driver_t *); int (*td_close) (td_driver_t *); int (*td_get_parent_id) (td_driver_t *, td_disk_id_t *); int (*td_validate_parent) (td_driver_t *, td_driver_t *, td_flag_t); -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |