Commit 0cea6b57 authored by Mike Gerdts's avatar Mike Gerdts Committed by Jim Harris
Browse files

lvol: add spdk_lvol_get_by_* API



spdk_lvol_get_by_uuid() allows lookup of lvols by the lvol's uuid.

spdk_lvol_get_by_names() allows lookup of lvols by the lvol's lvstore
name and lvol name.

Signed-off-by: default avatarMike Gerdts <mgerdts@nvidia.com>
Change-Id: Id165a3d17b76e5dde0616091dee5dff8327f44d0
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17546


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent b7d84562
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ New function `spdk_env_get_main_core` was added.

New API `spdk_lvol_iter_immediate_clones` was added to iterate the clones of an lvol.

New APIs `spdk_lvol_get_by_uuid` and `spdk_lvol_get_by_names` to get lvols by the lvol's UUID or
lvstore and lvol names.

### nvmf

New `spdk_nvmf_request_copy_to/from_buf()` APIs have been added, which support
+18 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@

#include "spdk/stdinc.h"
#include "spdk/blob.h"
#include "spdk/uuid.h"

#ifdef __cplusplus
extern "C" {
@@ -281,6 +282,23 @@ void spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *
 */
int spdk_lvol_iter_immediate_clones(struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn, void *cb_arg);

/**
 * Get the lvol that has a particular UUID.
 *
 * \param uuid The lvol's UUID.
 * \return A pointer to the requested lvol on success, else NULL.
 */
struct spdk_lvol *spdk_lvol_get_by_uuid(const struct spdk_uuid *uuid);

/**
 * Get the lvol that has the specified name in the specified lvolstore.
 *
 * \param lvs_name Name of the lvolstore.
 * \param lvol_name Name ofthe lvol.
 * \return A pointer to the requested lvol on success, else NULL.
 */
struct spdk_lvol *spdk_lvol_get_by_names(const char *lvs_name, const char *lvol_name);

/**
 * Get I/O channel of bdev associated with specified lvol.
 *
+45 −0
Original line number Diff line number Diff line
@@ -2114,3 +2114,48 @@ spdk_lvol_iter_immediate_clones(struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn,
	free(ids);
	return rc;
}

struct spdk_lvol *
spdk_lvol_get_by_uuid(const struct spdk_uuid *uuid)
{
	struct spdk_lvol_store *lvs;
	struct spdk_lvol *lvol;

	pthread_mutex_lock(&g_lvol_stores_mutex);

	TAILQ_FOREACH(lvs, &g_lvol_stores, link) {
		TAILQ_FOREACH(lvol, &lvs->lvols, link) {
			if (spdk_uuid_compare(uuid, &lvol->uuid) == 0) {
				pthread_mutex_unlock(&g_lvol_stores_mutex);
				return lvol;
			}
		}
	}

	pthread_mutex_unlock(&g_lvol_stores_mutex);
	return NULL;
}

struct spdk_lvol *
spdk_lvol_get_by_names(const char *lvs_name, const char *lvol_name)
{
	struct spdk_lvol_store *lvs;
	struct spdk_lvol *lvol;

	pthread_mutex_lock(&g_lvol_stores_mutex);

	TAILQ_FOREACH(lvs, &g_lvol_stores, link) {
		if (strcmp(lvs_name, lvs->name) != 0) {
			continue;
		}
		TAILQ_FOREACH(lvol, &lvs->lvols, link) {
			if (strcmp(lvol_name, lvol->name) == 0) {
				pthread_mutex_unlock(&g_lvol_stores_mutex);
				return lvol;
			}
		}
	}

	pthread_mutex_unlock(&g_lvol_stores_mutex);
	return NULL;
}
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
	spdk_lvol_decouple_parent;
	spdk_lvol_create_esnap_clone;
	spdk_lvol_iter_immediate_clones;
	spdk_lvol_get_by_uuid;
	spdk_lvol_get_by_names;

	# internal functions
	spdk_lvol_resize;
+113 −0
Original line number Diff line number Diff line
@@ -3167,6 +3167,118 @@ lvol_esnap_hotplug(void)
	}
}

static void
lvol_get_by(void)
{
	struct lvol_ut_bs_dev dev1, dev2;
	struct spdk_lvol_store *lvs1, *lvs2;
	struct spdk_lvol *lvol1, *lvol2, *lvol3;
	struct spdk_lvs_opts opts;
	int rc = 0;
	struct spdk_uuid uuid;

	init_dev(&dev1);

	spdk_lvs_opts_init(&opts);
	snprintf(opts.name, sizeof(opts.name), "lvs");

	g_lvserrno = -1;
	rc = spdk_lvs_init(&dev1.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
	lvs1 = g_lvol_store;

	/* Create lvol name "lvol" */
	spdk_lvol_create(lvs1, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT,
			 lvol_op_with_handle_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
	lvol1 = g_lvol;

	/* Should be able to look up lvol1 by its name and UUID */
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1);
	/* Be sure a pointer comparison isn't used. */
	memcpy(&uuid, &lvol1->uuid, sizeof(uuid));
	CU_ASSERT(spdk_lvol_get_by_uuid(&uuid) == lvol1);

	/* Shorter and longer values for lvol_name must not match. */
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvoll") == NULL);
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvo") == NULL);

	/* Shorter and longer values for lvs_name must not match. */
	CU_ASSERT(spdk_lvol_get_by_names("lvss", "lvol") == NULL);
	CU_ASSERT(spdk_lvol_get_by_names("lv", "lvol") == NULL);

	/* Create lvol name "lvol2" */
	spdk_lvol_create(lvs1, "lvol2", 10, true, LVOL_CLEAR_WITH_DEFAULT,
			 lvol_op_with_handle_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
	lvol2 = g_lvol;

	/* When there are multiple lvols, the right one is found */
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1);
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol2") == lvol2);

	/* Create a second lvolstore */
	init_dev(&dev2);
	snprintf(opts.name, sizeof(opts.name), "lvs2");
	g_lvserrno = -1;
	rc = spdk_lvs_init(&dev2.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
	lvs2 = g_lvol_store;

	/* Lookups that worked with one lvstore still work */
	memcpy(&uuid, &lvol1->uuid, sizeof(uuid));
	CU_ASSERT(spdk_lvol_get_by_uuid(&uuid) == lvol1);
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1);
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol2") == lvol2);

	/* Add an lvol name "lvol" in the second lvstore */
	spdk_lvol_create(lvs2, "lvol", 10, true, LVOL_CLEAR_WITH_DEFAULT,
			 lvol_op_with_handle_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
	lvol3 = g_lvol;

	/* Lookups by name find the lvols in the right lvstores */
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol") == lvol1);
	CU_ASSERT(spdk_lvol_get_by_names("lvs", "lvol2") == lvol2);
	CU_ASSERT(spdk_lvol_get_by_names("lvs2", "lvol") == lvol3);

	/* Clean up */
	g_lvserrno = -1;
	spdk_lvol_close(lvol1, op_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);

	g_lvserrno = -1;
	spdk_lvol_close(lvol2, op_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);

	g_lvserrno = -1;
	spdk_lvol_close(lvol3, op_complete, NULL);
	CU_ASSERT(g_lvserrno == 0);

	g_lvserrno = -1;
	rc = spdk_lvs_unload(lvs1, op_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvserrno == 0);

	g_lvserrno = -1;
	rc = spdk_lvs_unload(lvs2, op_complete, NULL);
	CU_ASSERT(rc == 0);
	CU_ASSERT(g_lvserrno == 0);

	g_lvol_store = NULL;
	g_lvol = NULL;

	free_dev(&dev1);
	free_dev(&dev2);
}

int
main(int argc, char **argv)
{
@@ -3212,6 +3324,7 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, lvol_esnap_load_esnaps);
	CU_ADD_TEST(suite, lvol_esnap_missing);
	CU_ADD_TEST(suite, lvol_esnap_hotplug);
	CU_ADD_TEST(suite, lvol_get_by);

	allocate_threads(1);
	set_thread(0);