bdev_part: allow UUID to be specified
This introduces spdk_bdev_part_construct_ext(), which takes an options structure as an optional parameter. The options structure has one option: uuid. Signed-off-by: Mike Gerdts <mgerdts@nvidia.com> Change-Id: I5e9fdc8e88b78b303e60a0e721d7a74854ac37a9 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17835 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
51d7df517c
commit
9b687d7753
@ -53,6 +53,10 @@ receive and send the I/O management commands.
|
|||||||
New `spdk_nvmf_transport_create_async` was added, it accepts a callback and callback argument.
|
New `spdk_nvmf_transport_create_async` was added, it accepts a callback and callback argument.
|
||||||
`spdk_nvmf_transport_create` is marked deprecated.
|
`spdk_nvmf_transport_create` is marked deprecated.
|
||||||
|
|
||||||
|
### part
|
||||||
|
|
||||||
|
New API `spdk_bdev_part_construct_ext` is added and allows the bdev's UUID to be specified.
|
||||||
|
|
||||||
### examples
|
### examples
|
||||||
|
|
||||||
`examples/nvme/perf` application now accepts `--use-every-core` parameter that changes
|
`examples/nvme/perf` application now accepts `--use-every-core` parameter that changes
|
||||||
|
@ -1463,6 +1463,24 @@ int spdk_bdev_part_base_construct_ext(const char *bdev_name,
|
|||||||
spdk_io_channel_destroy_cb ch_destroy_cb,
|
spdk_io_channel_destroy_cb ch_destroy_cb,
|
||||||
struct spdk_bdev_part_base **base);
|
struct spdk_bdev_part_base **base);
|
||||||
|
|
||||||
|
/** Options used when constructing a part bdev. */
|
||||||
|
struct spdk_bdev_part_construct_opts {
|
||||||
|
/* Size of this structure in bytes */
|
||||||
|
uint64_t opts_size;
|
||||||
|
/** UUID of the bdev */
|
||||||
|
struct spdk_uuid uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
SPDK_STATIC_ASSERT(sizeof(struct spdk_bdev_part_construct_opts) == 24, "Incorrect size");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize options that will be passed to spdk_bdev_part_construct_ext().
|
||||||
|
*
|
||||||
|
* \param opts Options structure to initialize
|
||||||
|
* \param size Size of opts structure.
|
||||||
|
*/
|
||||||
|
void spdk_bdev_part_construct_opts_init(struct spdk_bdev_part_construct_opts *opts, uint64_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a logical spdk_bdev_part on top of a base.
|
* Create a logical spdk_bdev_part on top of a base.
|
||||||
*
|
*
|
||||||
@ -1480,6 +1498,25 @@ int spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_
|
|||||||
char *name, uint64_t offset_blocks, uint64_t num_blocks,
|
char *name, uint64_t offset_blocks, uint64_t num_blocks,
|
||||||
char *product_name);
|
char *product_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a logical spdk_bdev_part on top of a base with a non-NULL bdev UUID
|
||||||
|
*
|
||||||
|
* \param part The part object allocated by the user.
|
||||||
|
* \param base The base from which to create the part.
|
||||||
|
* \param name The name of the new spdk_bdev_part.
|
||||||
|
* \param offset_blocks The offset into the base bdev at which this part begins.
|
||||||
|
* \param num_blocks The number of blocks that this part will span.
|
||||||
|
* \param product_name Unique name for this type of block device.
|
||||||
|
* \param opts Additional options.
|
||||||
|
*
|
||||||
|
* \return 0 on success.
|
||||||
|
* \return -1 if the bases underlying bdev cannot be claimed by the current module.
|
||||||
|
*/
|
||||||
|
int spdk_bdev_part_construct_ext(struct spdk_bdev_part *part, struct spdk_bdev_part_base *base,
|
||||||
|
char *name, uint64_t offset_blocks, uint64_t num_blocks,
|
||||||
|
char *product_name,
|
||||||
|
const struct spdk_bdev_part_construct_opts *opts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forwards I/O from an spdk_bdev_part to the underlying base bdev.
|
* Forwards I/O from an spdk_bdev_part to the underlying base bdev.
|
||||||
*
|
*
|
||||||
|
@ -497,13 +497,68 @@ spdk_bdev_part_base_construct_ext(const char *bdev_name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_bdev_part_construct_opts_init(struct spdk_bdev_part_construct_opts *opts, uint64_t size)
|
||||||
|
{
|
||||||
|
if (opts == NULL) {
|
||||||
|
SPDK_ERRLOG("opts should not be NULL\n");
|
||||||
|
assert(opts != NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (size == 0) {
|
||||||
|
SPDK_ERRLOG("size should not be zero\n");
|
||||||
|
assert(size != 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(opts, 0, size);
|
||||||
|
opts->opts_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
part_construct_opts_copy(const struct spdk_bdev_part_construct_opts *src,
|
||||||
|
struct spdk_bdev_part_construct_opts *dst)
|
||||||
|
{
|
||||||
|
if (src->opts_size == 0) {
|
||||||
|
SPDK_ERRLOG("size should not be zero\n");
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(dst, 0, sizeof(*dst));
|
||||||
|
dst->opts_size = src->opts_size;
|
||||||
|
|
||||||
|
#define FIELD_OK(field) \
|
||||||
|
offsetof(struct spdk_bdev_part_construct_opts, field) + sizeof(src->field) <= src->opts_size
|
||||||
|
|
||||||
|
#define SET_FIELD(field) \
|
||||||
|
if (FIELD_OK(field)) { \
|
||||||
|
dst->field = src->field; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
SET_FIELD(uuid);
|
||||||
|
|
||||||
|
/* You should not remove this statement, but need to update the assert statement
|
||||||
|
* if you add a new field, and also add a corresponding SET_FIELD statement */
|
||||||
|
SPDK_STATIC_ASSERT(sizeof(struct spdk_bdev_part_construct_opts) == 24, "Incorrect size");
|
||||||
|
|
||||||
|
#undef FIELD_OK
|
||||||
|
#undef SET_FIELD
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base *base,
|
spdk_bdev_part_construct_ext(struct spdk_bdev_part *part, struct spdk_bdev_part_base *base,
|
||||||
char *name, uint64_t offset_blocks, uint64_t num_blocks,
|
char *name, uint64_t offset_blocks, uint64_t num_blocks,
|
||||||
char *product_name)
|
char *product_name, const struct spdk_bdev_part_construct_opts *_opts)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
bool first_claimed = false;
|
bool first_claimed = false;
|
||||||
|
struct spdk_bdev_part_construct_opts opts;
|
||||||
|
|
||||||
|
if (_opts == NULL) {
|
||||||
|
spdk_bdev_part_construct_opts_init(&opts, sizeof(opts));
|
||||||
|
} else {
|
||||||
|
part_construct_opts_copy(_opts, &opts);
|
||||||
|
}
|
||||||
|
|
||||||
part->internal.bdev.blocklen = base->bdev->blocklen;
|
part->internal.bdev.blocklen = base->bdev->blocklen;
|
||||||
part->internal.bdev.blockcnt = num_blocks;
|
part->internal.bdev.blockcnt = num_blocks;
|
||||||
@ -535,6 +590,8 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spdk_uuid_copy(&part->internal.bdev.uuid, &opts.uuid);
|
||||||
|
|
||||||
base->ref++;
|
base->ref++;
|
||||||
part->internal.base = base;
|
part->internal.base = base;
|
||||||
|
|
||||||
@ -575,3 +632,12 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base *base,
|
||||||
|
char *name, uint64_t offset_blocks, uint64_t num_blocks,
|
||||||
|
char *product_name)
|
||||||
|
{
|
||||||
|
return spdk_bdev_part_construct_ext(part, base, name, offset_blocks, num_blocks,
|
||||||
|
product_name, NULL);
|
||||||
|
}
|
||||||
|
@ -152,7 +152,9 @@
|
|||||||
spdk_bdev_part_free;
|
spdk_bdev_part_free;
|
||||||
spdk_bdev_part_base_hotremove;
|
spdk_bdev_part_base_hotremove;
|
||||||
spdk_bdev_part_base_construct_ext;
|
spdk_bdev_part_base_construct_ext;
|
||||||
|
spdk_bdev_part_construct_opts_init;
|
||||||
spdk_bdev_part_construct;
|
spdk_bdev_part_construct;
|
||||||
|
spdk_bdev_part_construct_ext;
|
||||||
spdk_bdev_part_submit_request;
|
spdk_bdev_part_submit_request;
|
||||||
spdk_bdev_part_submit_request_ext;
|
spdk_bdev_part_submit_request_ext;
|
||||||
spdk_bdev_part_get_bdev;
|
spdk_bdev_part_get_bdev;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: BSD-3-Clause
|
/* SPDX-License-Identifier: BSD-3-Clause
|
||||||
* Copyright (C) 2018 Intel Corporation.
|
* Copyright (C) 2018 Intel Corporation.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
* Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "spdk_cunit.h"
|
#include "spdk_cunit.h"
|
||||||
@ -393,6 +394,48 @@ part_get_io_channel_test(void)
|
|||||||
ut_fini_bdev();
|
ut_fini_bdev();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
part_construct_ext(void)
|
||||||
|
{
|
||||||
|
struct spdk_bdev_part_base *base;
|
||||||
|
struct spdk_bdev_part part1 = {};
|
||||||
|
struct spdk_bdev bdev_base = {};
|
||||||
|
SPDK_BDEV_PART_TAILQ tailq = TAILQ_HEAD_INITIALIZER(tailq);
|
||||||
|
const char *uuid = "7ed764b7-a841-41b1-ba93-6548d9335a44";
|
||||||
|
struct spdk_bdev_part_construct_opts opts;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
bdev_base.name = "base";
|
||||||
|
bdev_base.fn_table = &base_fn_table;
|
||||||
|
bdev_base.module = &bdev_ut_if;
|
||||||
|
rc = spdk_bdev_register(&bdev_base);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
rc = spdk_bdev_part_base_construct_ext("base", NULL, &vbdev_ut_if,
|
||||||
|
&part_fn_table, &tailq, NULL,
|
||||||
|
NULL, 0, NULL, NULL, &base);
|
||||||
|
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
SPDK_CU_ASSERT_FATAL(base != NULL);
|
||||||
|
|
||||||
|
/* Verify opts.uuid is used as bdev UUID */
|
||||||
|
spdk_bdev_part_construct_opts_init(&opts, sizeof(opts));
|
||||||
|
spdk_uuid_parse(&opts.uuid, uuid);
|
||||||
|
rc = spdk_bdev_part_construct_ext(&part1, base, "test1", 0, 100, "test", &opts);
|
||||||
|
SPDK_CU_ASSERT_FATAL(rc == 0);
|
||||||
|
SPDK_CU_ASSERT_FATAL(base->ref == 1);
|
||||||
|
SPDK_CU_ASSERT_FATAL(base->claimed == true);
|
||||||
|
CU_ASSERT(spdk_bdev_get_by_name(uuid) != NULL);
|
||||||
|
CU_ASSERT(spdk_bdev_get_by_name("test1") != NULL);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
spdk_bdev_part_base_hotremove(base, &tailq);
|
||||||
|
spdk_bdev_part_base_free(base);
|
||||||
|
_part_cleanup(&part1);
|
||||||
|
spdk_bdev_unregister(&bdev_base, NULL, NULL);
|
||||||
|
|
||||||
|
poll_threads();
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -407,6 +450,7 @@ main(int argc, char **argv)
|
|||||||
CU_ADD_TEST(suite, part_test);
|
CU_ADD_TEST(suite, part_test);
|
||||||
CU_ADD_TEST(suite, part_free_test);
|
CU_ADD_TEST(suite, part_free_test);
|
||||||
CU_ADD_TEST(suite, part_get_io_channel_test);
|
CU_ADD_TEST(suite, part_get_io_channel_test);
|
||||||
|
CU_ADD_TEST(suite, part_construct_ext);
|
||||||
|
|
||||||
allocate_cores(1);
|
allocate_cores(1);
|
||||||
allocate_threads(1);
|
allocate_threads(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user