Commit 94cf9837 authored by Maciej Szwed's avatar Maciej Szwed Committed by Jim Harris
Browse files

lvol: support callbacks in lvol close/destroy functions



Close and destroy lvol functions should support callback
functions so that they can be processed sequentially
and also give user result.

Signed-off-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Change-Id: I9e87fb281916c65c17b2b7e54e91228844962048

Reviewed-on: https://review.gerrithub.io/383230


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent c5f83bd8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -64,8 +64,8 @@ int spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
int spdk_lvs_unload(struct spdk_lvol_store *lvol_store, spdk_lvs_op_complete cb_fn, void *cb_arg);
int spdk_lvol_create(struct spdk_lvol_store *lvs, uint64_t sz,
		     spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg);
void spdk_lvol_destroy(struct spdk_lvol *lvol);
void spdk_lvol_close(struct spdk_lvol *lvol);
void spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg);
void spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg);
struct spdk_io_channel *spdk_lvol_get_io_channel(struct spdk_lvol *lvol);
struct lvol_store_bdev *vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs_orig);
struct spdk_lvol *vbdev_get_lvol_by_name(const char *name);
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ struct spdk_lvs_req {
struct spdk_lvol_req {
	spdk_lvol_op_complete    cb_fn;
	void                    *cb_arg;
	struct spdk_lvol	*lvol;
};

struct spdk_lvs_with_handle_req {
+14 −2
Original line number Diff line number Diff line
@@ -276,6 +276,18 @@ vbdev_get_lvol_by_name(const char *name)
	return NULL;
}

static void
_vbdev_lvol_close_cb(void *cb_arg, int lvserrno)
{
	SPDK_INFOLOG(SPDK_TRACE_VBDEV_LVOL, "Lvol closed\n");
}

static void
_vbdev_lvol_destroy_cb(void *cb_arg, int lvserrno)
{
	SPDK_INFOLOG(SPDK_TRACE_VBDEV_LVOL, "Lvol destroyed\n");
}

static int
vbdev_lvol_destruct(void *ctx)
{
@@ -284,9 +296,9 @@ vbdev_lvol_destruct(void *ctx)
	assert(lvol != NULL);
	free(lvol->bdev);
	if (lvol->close_only) {
		spdk_lvol_close(lvol);
		spdk_lvol_close(lvol, _vbdev_lvol_close_cb, NULL);
	} else {
		spdk_lvol_destroy(lvol);
		spdk_lvol_destroy(lvol, _vbdev_lvol_destroy_cb, NULL);
	}

	return 0;
+93 −10
Original line number Diff line number Diff line
@@ -301,41 +301,82 @@ _spdk_lvs_destruct_cb(void *cb_arg, int lvserrno)
static void
_spdk_lvol_close_blob_cb(void *cb_arg, int lvolerrno)
{
	struct spdk_lvol *lvol = cb_arg;
	struct spdk_lvol_req *req = cb_arg;
	struct spdk_lvol *lvol = req->lvol;

	if (lvolerrno < 0) {
		SPDK_ERRLOG("Could not close blob on lvol\n");
		free(lvol->name);
		free(lvol);
		return;
		goto end;
	}

	if (lvol->lvol_store->destruct_req && TAILQ_EMPTY(&lvol->lvol_store->lvols)) {
		spdk_lvs_unload(lvol->lvol_store, _spdk_lvs_destruct_cb, lvol->lvol_store->destruct_req);
	}

	SPDK_INFOLOG(SPDK_TRACE_LVOL, "Lvol %s closed\n", lvol->name) ;

	free(lvol->name);
	free(lvol);

	SPDK_INFOLOG(SPDK_TRACE_LVOL, "Blob closed on lvol\n");
end:
	req->cb_fn(req->cb_arg, lvolerrno);
	free(req);
}

static void
_spdk_lvol_delete_blob_cb(void *cb_arg, int lvolerrno)
{
	struct spdk_lvol *lvol = cb_arg;
	struct spdk_lvol_with_handle_req *req = cb_arg;
	struct spdk_lvol_req *lvol_req = req->cb_arg;
	struct spdk_lvol *lvol = req->lvol;

	if (lvolerrno < 0) {
		SPDK_ERRLOG("Could not delete blob on lvol\n");
		free(lvol->name);
		free(lvol);
		goto end;
	}

	if (lvol->lvol_store->destruct_req && TAILQ_EMPTY(&lvol->lvol_store->lvols)) {
		spdk_lvs_unload(lvol->lvol_store, _spdk_lvs_destruct_cb, lvol->lvol_store->destruct_req);
	}

	SPDK_INFOLOG(SPDK_TRACE_LVOL, "Lvol %s deleted\n", lvol->name);

	free(lvol->name);
	free(lvol);

end:
	lvol_req->cb_fn(lvol_req->cb_arg, lvolerrno);
	free(lvol_req);
	free(req);
}

static void
_spdk_lvol_destroy_cb(void *cb_arg, int lvolerrno)
{
	struct spdk_lvol_with_handle_req *req = cb_arg;
	struct spdk_lvol_req *lvol_req = req->cb_arg;
	struct spdk_lvol *lvol = req->lvol;
	struct spdk_blob_store *bs = lvol->lvol_store->blobstore;

	if (lvolerrno < 0) {
		SPDK_ERRLOG("Could not delete blob on lvol\n");
		free(lvol->name);
		free(lvol);
		lvol_req->cb_fn(lvol_req->cb_arg, lvolerrno);
		free(lvol_req);
		free(req);
		return;
	}
	SPDK_INFOLOG(SPDK_TRACE_LVOL, "Blob closed on lvol\n");
	spdk_bs_md_delete_blob(bs, lvol->blob_id, _spdk_lvol_close_blob_cb, lvol);
	SPDK_INFOLOG(SPDK_TRACE_LVOL, "Blob closed on lvol %s\n", lvol->name);

	spdk_bs_md_delete_blob(bs, lvol->blob_id, _spdk_lvol_delete_blob_cb, req);
}


static void
_spdk_lvol_create_open_cb(void *cb_arg, struct spdk_blob *blob, int lvolerrno)
{
@@ -504,27 +545,69 @@ invalid:
}

void
spdk_lvol_destroy(struct spdk_lvol *lvol)
spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	struct spdk_lvol_with_handle_req *req;
	struct spdk_lvol_req *lvol_req;

	assert(cb_fn != NULL);

	if (lvol == NULL) {
		SPDK_ERRLOG("lvol does not exist\n");
		cb_fn(cb_arg, -ENODEV);
		return;
	}

	req = calloc(1, sizeof(*req));
	if (!req) {
		SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
		cb_fn(cb_arg, -ENOMEM);
		return;
	}

	lvol_req = calloc(1, sizeof(*lvol_req));
	if (!req) {
		SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
		cb_fn(cb_arg, -ENOMEM);
		free(req);
		return;
	}

	lvol_req->cb_fn = cb_fn;
	lvol_req->cb_arg = cb_arg;
	req->cb_arg = lvol_req;
	req->lvol = lvol;

	TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link);
	spdk_bs_md_close_blob(&(lvol->blob), _spdk_lvol_delete_blob_cb, lvol);
	spdk_bs_md_close_blob(&(lvol->blob), _spdk_lvol_destroy_cb, req);
}

void
spdk_lvol_close(struct spdk_lvol *lvol)
spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	struct spdk_lvol_req *req;

	assert(cb_fn != NULL);

	if (lvol == NULL) {
		SPDK_ERRLOG("lvol does not exist\n");
		cb_fn(cb_arg, -ENODEV);
		return;
	}

	req = calloc(1, sizeof(*req));
	if (!req) {
		SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
		cb_fn(cb_arg, -ENOMEM);
		return;
	}

	req->cb_fn = cb_fn;
	req->cb_arg = cb_arg;
	req->lvol = lvol;

	TAILQ_REMOVE(&lvol->lvol_store->lvols, lvol, link);
	spdk_bs_md_close_blob(&(lvol->blob), _spdk_lvol_close_blob_cb, lvol);
	spdk_bs_md_close_blob(&(lvol->blob), _spdk_lvol_close_blob_cb, req);
}

struct spdk_io_channel *
+10 −3
Original line number Diff line number Diff line
@@ -175,8 +175,13 @@ spdk_bdev_get_by_name(const char *bdev_name)
	return NULL;
}

static void
close_cb(void *cb_arg, int lvolerrno)
{
}

void
spdk_lvol_close(struct spdk_lvol *lvol)
spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	struct spdk_lvs_req *destruct_req;

@@ -193,13 +198,15 @@ spdk_lvol_close(struct spdk_lvol *lvol)
	free(lvol->name);
	free(lvol);
	g_lvol = NULL;
	cb_fn(NULL, 0);
}

void
spdk_lvol_destroy(struct spdk_lvol *lvol)
spdk_lvol_destroy(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	/* Lvol destroy and close are effectively the same from UT perspective */
	spdk_lvol_close(lvol);
	spdk_lvol_close(lvol, close_cb, NULL);
	cb_fn(NULL, 0);
}

void
Loading