Commit 1ee2e81b authored by Marcin Dziegielewski's avatar Marcin Dziegielewski Committed by Darek Stojaczyk
Browse files

lib/bdev/ocf: add possibility to remove ocf instance



In current code there is no possibility to remove ocf instance
permanently, even we call delete_ocf_bdev rpc command, on next examine
this instance will be loaded.

This patch introduces changes to delete_ocf_bdev rpc command. When we call
this command via rpc, core related to particular vbdev will be removed
from ocf cache before removing this cache instance. Thanks to that, on
next examine we will not detect this core in cache metadata and therefore
we will not create this instance on next load.

However, in any other situation, we will not touch metadata, so in case of
dirty shutdown/hot remove, on next load, we will recovery this instance.

Signed-off-by: default avatarMarcin Dziegielewski <marcin.dziegielewski@intel.com>
Change-Id: Iebef80989ea22ccea7f1b6ba4d734a40c1d5cc5d
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465675


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
parent 7ed0ec68
Loading
Loading
Loading
Loading
+66 −9
Original line number Diff line number Diff line
@@ -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)
+4 −0
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -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",