Commit 526cd580 authored by Sebastian Basierski's avatar Sebastian Basierski Committed by Jim Harris
Browse files

bdev: Added functions allowing logical volume rename.

parent 119ccada
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -151,6 +151,17 @@ int spdk_lvs_destroy(struct spdk_lvol_store *lvol_store,
int spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
		     bool thin_provisioned, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg);

/**
 * \brief Renames lvol with new_name.
 * \param lvol Handle to lvol
 * \param new_name new name for lvol
 * \param cb_fn Completion callback
 * \param cb_arg Completion callback custom arguments
 */
void
spdk_lvol_rename(struct spdk_lvol *lvol, const char *new_name,
		 spdk_lvol_op_complete cb_fn, void *cb_arg);

/**
 * \brief Closes lvol and removes information about lvol from its lvolstore.
 * \param lvol Handle to lvol
+2 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct spdk_lvol_req {
	spdk_lvol_op_complete   cb_fn;
	void                    *cb_arg;
	struct spdk_lvol	*lvol;
	char			name[SPDK_LVOL_NAME_MAX];
};

struct spdk_lvs_with_handle_req {
+118 −2
Original line number Diff line number Diff line
@@ -66,6 +66,56 @@ vbdev_get_lvs_bdev_by_lvs(struct spdk_lvol_store *lvs_orig)
	return NULL;
}

static int
_vbdev_lvol_change_bdev_alias(struct spdk_lvol *lvol, const char *new_lvol_name)
{
	struct spdk_bdev_alias *tmp;
	char *old_alias;
	char *alias;
	int rc;
	int alias_number = 0;

	/* bdev representing lvols have only one alias,
	 * while we changed lvs name earlier, we have to iterate alias list to get one,
	 * and check if there is only one alias */

	TAILQ_FOREACH(tmp, &lvol->bdev->aliases, tailq) {
		if (++alias_number > 1) {
			SPDK_ERRLOG("There is more than 1 alias in bdev %s\n", lvol->bdev->name);
			return -EINVAL;
		}

		old_alias = tmp->alias;
	}

	if (alias_number == 0) {
		SPDK_ERRLOG("There are no aliases in bdev %s\n", lvol->bdev->name);
		return -EINVAL;
	}

	alias = spdk_sprintf_alloc("%s/%s", lvol->lvol_store->name, new_lvol_name);
	if (alias == NULL) {
		SPDK_ERRLOG("Cannot alloc memory for alias\n");
		return -ENOMEM;
	}

	rc = spdk_bdev_alias_add(lvol->bdev, alias);
	if (rc != 0) {
		SPDK_ERRLOG("cannot add alias '%s'\n", alias);
		free(alias);
		return rc;
	}
	free(alias);

	rc = spdk_bdev_alias_del(lvol->bdev, old_alias);
	if (rc != 0) {
		SPDK_ERRLOG("cannot remove alias '%s'\n", old_alias);
		return rc;
	}

	return 0;
}

static struct lvol_store_bdev *
vbdev_get_lvs_bdev_by_bdev(struct spdk_bdev *bdev_orig)
{
@@ -442,9 +492,18 @@ static int
vbdev_lvol_destruct(void *ctx)
{
	struct spdk_lvol *lvol = ctx;
	char *alias;

	assert(lvol != NULL);

	alias = spdk_sprintf_alloc("%s/%s", lvol->lvol_store->name, lvol->name);
	if (alias != NULL) {
		spdk_bdev_alias_del(lvol->bdev, alias);
		free(alias);
	} else {
		SPDK_ERRLOG("Cannot alloc memory for alias\n");
	}

	if (lvol->close_only) {
		free(lvol->bdev->name);
		free(lvol->bdev);
@@ -660,6 +719,7 @@ _create_lvol_disk(struct spdk_lvol *lvol)
	struct spdk_bdev *bdev;
	struct lvol_store_bdev *lvs_bdev;
	uint64_t total_size;
	unsigned char *alias;
	int rc;

	if (!lvol->unique_id) {
@@ -678,8 +738,8 @@ _create_lvol_disk(struct spdk_lvol *lvol)
		return NULL;
	}

	bdev->name = spdk_sprintf_alloc("%s/%s", lvs_bdev->lvs->name, lvol->name);
	if (bdev->name == NULL) {
	bdev->name = strdup(lvol->unique_id);
	if (!bdev->name) {
		SPDK_ERRLOG("Cannot alloc memory for bdev name\n");
		free(bdev);
		return NULL;
@@ -701,6 +761,24 @@ _create_lvol_disk(struct spdk_lvol *lvol)
		return NULL;
	}

	alias = spdk_sprintf_alloc("%s/%s", lvs_bdev->lvs->name, lvol->name);
	if (alias == NULL) {
		SPDK_ERRLOG("Cannot alloc memory for alias\n");
		free(bdev->name);
		free(bdev);
		return NULL;
	}

	rc = spdk_bdev_alias_add(bdev, alias);
	if (rc != 0) {
		SPDK_ERRLOG("Cannot add alias to lvol bdev\n");
		free(bdev->name);
		free(bdev);
		free(alias);
		return NULL;
	}
	free(alias);

	return bdev;
}

@@ -748,6 +826,44 @@ vbdev_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
	return rc;
}

static void
_vbdev_lvol_rename_cb(void *cb_arg, int lvolerrno)
{
	struct spdk_lvol_req *req = cb_arg;

	if (lvolerrno != 0) {
		SPDK_ERRLOG("Renaming lvol failed\n");
	}

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

void
vbdev_lvol_rename(struct spdk_lvol *lvol, const char *new_lvol_name,
		  spdk_lvol_op_complete cb_fn, void *cb_arg)
{
	struct spdk_lvol_req *req;
	int rc;

	rc = _vbdev_lvol_change_bdev_alias(lvol, new_lvol_name);
	if (rc != 0) {
		SPDK_ERRLOG("renaming lvol to '%s' does not succeed\n", new_lvol_name);
		cb_fn(cb_arg, rc);
		return;
	}

	req = calloc(1, sizeof(*req));
	if (req == NULL) {
		cb_fn(cb_arg, -ENOMEM);
		return;
	}
	req->cb_fn = cb_fn;
	req->cb_arg = cb_arg;

	spdk_lvol_rename(lvol, new_lvol_name, _vbdev_lvol_rename_cb, req);
}

static void
_vbdev_lvol_resize_cb(void *cb_arg, int lvolerrno)
{
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ int vbdev_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,

int vbdev_lvol_resize(char *name, size_t sz, spdk_lvol_op_complete cb_fn, void *cb_arg);

void vbdev_lvol_rename(struct spdk_lvol *lvol, const char *new_lvol_name,
		       spdk_lvol_op_complete cb_fn, void *cb_arg);

/**
 * \brief Search for handle lvolstore
 * \param uuid_str UUID of lvolstore
+86 −0
Original line number Diff line number Diff line
@@ -342,6 +342,92 @@ invalid:

SPDK_RPC_REGISTER("construct_lvol_bdev", spdk_rpc_construct_lvol_bdev)

struct rpc_rename_lvol_bdev {
	char *old_name;
	char *new_name;
};

static void
free_rpc_rename_lvol_bdev(struct rpc_rename_lvol_bdev *req)
{
	free(req->old_name);
	free(req->new_name);
}

static const struct spdk_json_object_decoder rpc_rename_lvol_bdev_decoders[] = {
	{"old_name", offsetof(struct rpc_rename_lvol_bdev, old_name), spdk_json_decode_string, true},
	{"new_name", offsetof(struct rpc_rename_lvol_bdev, new_name), spdk_json_decode_string, true},
};

static void
_spdk_rpc_rename_lvol_bdev_cb(void *cb_arg, int lvolerrno)
{
	struct spdk_json_write_ctx *w;
	struct spdk_jsonrpc_request *request = cb_arg;

	if (lvolerrno != 0) {
		goto invalid;
	}

	w = spdk_jsonrpc_begin_result(request);
	if (w == NULL) {
		return;
	}

	spdk_json_write_bool(w, true);
	spdk_jsonrpc_end_result(request, w);
	return;

invalid:
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
					 spdk_strerror(-lvolerrno));
}

static void
spdk_rpc_rename_lvol_bdev(struct spdk_jsonrpc_request *request,
			  const struct spdk_json_val *params)
{
	struct rpc_rename_lvol_bdev req = {};
	struct spdk_bdev *bdev;
	struct spdk_lvol *lvol;
	int rc = 0;

	SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "Renaming lvol\n");

	if (spdk_json_decode_object(params, rpc_rename_lvol_bdev_decoders,
				    SPDK_COUNTOF(rpc_rename_lvol_bdev_decoders),
				    &req)) {
		SPDK_INFOLOG(SPDK_LOG_LVOL_RPC, "spdk_json_decode_object failed\n");
		rc = -EINVAL;
		goto invalid;
	}

	bdev = spdk_bdev_get_by_name(req.old_name);
	if (bdev == NULL) {
		SPDK_ERRLOG("bdev '%s' does not exist\n", req.old_name);
		rc = -ENODEV;
		goto invalid;
	}

	lvol = vbdev_lvol_get_from_bdev(bdev);
	if (lvol == NULL) {
		SPDK_ERRLOG("lvol does not exist\n");
		rc = -ENODEV;
		goto invalid;
	}

	vbdev_lvol_rename(lvol, req.new_name, _spdk_rpc_rename_lvol_bdev_cb, request);

	free_rpc_rename_lvol_bdev(&req);
	return;

invalid:
	spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_strerror(-rc));
	free_rpc_rename_lvol_bdev(&req);
}

SPDK_RPC_REGISTER("rename_lvol_bdev", spdk_rpc_rename_lvol_bdev)

struct rpc_resize_lvol_bdev {
	char *name;
	uint64_t size;
Loading