diff --git a/module/bdev/ocf/vbdev_ocf.c b/module/bdev/ocf/vbdev_ocf.c index 58b67a161..aacf3ef06 100644 --- a/module/bdev/ocf/vbdev_ocf.c +++ b/module/bdev/ocf/vbdev_ocf.c @@ -339,8 +339,8 @@ flush_vbdev(struct vbdev_ocf *vbdev) vbdev_ocf_mngt_poll(vbdev, flush_vbdev_poll); } -/* Procedures called during unregister */ -vbdev_ocf_mngt_fn unregister_path[] = { +/* Procedures called during dirty unregister */ +vbdev_ocf_mngt_fn unregister_path_dirty[] = { flush_vbdev, wait_for_requests, stop_vbdev, @@ -352,13 +352,30 @@ vbdev_ocf_mngt_fn unregister_path[] = { NULL }; +/* Procedures called during clean unregister */ +vbdev_ocf_mngt_fn unregister_path_clean[] = { + flush_vbdev, + wait_for_requests, + detach_core, + close_core_bdev, + stop_vbdev, + detach_cache, + close_cache_bdev, + unregister_finish, + NULL +}; + /* Start asynchronous management operation using unregister_path */ static void unregister_cb(void *opaque) { struct vbdev_ocf *vbdev = opaque; + vbdev_ocf_mngt_fn *unregister_path; int rc; + unregister_path = vbdev->state.doing_clean_delete ? + unregister_path_clean : unregister_path_dirty; + rc = vbdev_ocf_mngt_start(vbdev, unregister_path, NULL, NULL); if (rc) { SPDK_ERRLOG("Unable to unregister OCF bdev: %d\n", rc); @@ -366,6 +383,38 @@ unregister_cb(void *opaque) } } +/* Clean remove case - remove core and then cache, this order + * will remove instance permanently */ +static void +_vbdev_ocf_destruct_clean(struct vbdev_ocf *vbdev) +{ + if (vbdev->core.attached) { + detach_core(vbdev); + close_core_bdev(vbdev); + } + + if (vbdev->cache.attached) { + detach_cache(vbdev); + close_cache_bdev(vbdev); + } +} + +/* Dirty shutdown/hot remove case - remove cache and then core, this order + * will allow us to recover this instance in the future */ +static void +_vbdev_ocf_destruct_dirty(struct vbdev_ocf *vbdev) +{ + if (vbdev->cache.attached) { + detach_cache(vbdev); + close_cache_bdev(vbdev); + } + + if (vbdev->core.attached) { + detach_core(vbdev); + close_core_bdev(vbdev); + } +} + /* Unregister io device with callback to unregister_cb * This function is called during spdk_bdev_unregister */ static int @@ -391,13 +440,10 @@ vbdev_ocf_destruct(void *opaque) return 1; } - if (vbdev->cache.attached) { - detach_cache(vbdev); - close_cache_bdev(vbdev); - } - if (vbdev->core.attached) { - detach_core(vbdev); - close_core_bdev(vbdev); + if (vbdev->state.doing_clean_delete) { + _vbdev_ocf_destruct_clean(vbdev); + } else { + _vbdev_ocf_destruct_dirty(vbdev); } return 0; @@ -421,6 +467,17 @@ vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg) return rc; } +/* Remove cores permanently and then stop OCF cache and unregister SPDK bdev */ +int +vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int), + void *cb_arg) +{ + vbdev->state.doing_clean_delete = true; + + return vbdev_ocf_delete(vbdev, cb, cb_arg); +} + + /* If vbdev is online, return its object */ struct vbdev_ocf * vbdev_ocf_get_by_name(const char *name) diff --git a/module/bdev/ocf/vbdev_ocf.h b/module/bdev/ocf/vbdev_ocf.h index 9666186b5..b0cf6fb49 100644 --- a/module/bdev/ocf/vbdev_ocf.h +++ b/module/bdev/ocf/vbdev_ocf.h @@ -63,6 +63,8 @@ struct vbdev_ocf_qcxt { /* Important states */ struct vbdev_ocf_state { + /* From the moment when clean delete started */ + bool doing_clean_delete; /* From the moment when finish started */ bool doing_finish; /* From the moment when reset IO recieved, until it is completed */ @@ -200,6 +202,8 @@ struct vbdev_ocf_base *vbdev_ocf_get_base_by_name(const char *name); /* Stop OCF cache and unregister SPDK bdev */ int vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg); +int vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg); + typedef void (*vbdev_ocf_foreach_fn)(struct vbdev_ocf *, void *); /* Execute fn for each OCF device that is online or waits for base devices */ diff --git a/module/bdev/ocf/vbdev_ocf_rpc.c b/module/bdev/ocf/vbdev_ocf_rpc.c index 649865159..5a1325062 100644 --- a/module/bdev/ocf/vbdev_ocf_rpc.c +++ b/module/bdev/ocf/vbdev_ocf_rpc.c @@ -160,7 +160,7 @@ spdk_rpc_bdev_ocf_delete(struct spdk_jsonrpc_request *request, goto end; } - status = vbdev_ocf_delete(vbdev, delete_cb, request); + status = vbdev_ocf_delete_clean(vbdev, delete_cb, request); if (status) { spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, "Could not delete OCF vbdev: %s",