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: Mike Gerdts <mgerdts@nvidia.com>
Change-Id: Id165a3d17b76e5dde0616091dee5dff8327f44d0
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17546
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Mike Gerdts 2023-04-11 17:02:42 -05:00 committed by Jim Harris
parent b7d84562cb
commit 0cea6b57f6
5 changed files with 181 additions and 0 deletions

View File

@ -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

View File

@ -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.
*

View File

@ -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;
}

View File

@ -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;

View File

@ -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);