Commit 54db60cd authored by Mike Gerdts's avatar Mike Gerdts Committed by Ben Walker
Browse files

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: default avatarMike Gerdts <mgerdts@nvidia.com>
Change-Id: I5e9fdc8e88b78b303e60a0e721d7a74854ac37a9
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/17835


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent a347d3e7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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.
`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/nvme/perf` application now accepts `--use-every-core` parameter that changes
+37 −0
Original line number Diff line number Diff line
@@ -1463,6 +1463,24 @@ int spdk_bdev_part_base_construct_ext(const char *bdev_name,
				      spdk_io_channel_destroy_cb ch_destroy_cb,
				      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.
 *
@@ -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 *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.
 *
+69 −3
Original line number Diff line number Diff line
@@ -497,13 +497,68 @@ spdk_bdev_part_base_construct_ext(const char *bdev_name,
	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
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 *product_name)
			     char *product_name, const struct spdk_bdev_part_construct_opts *_opts)
{
	int rc;
	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.blockcnt = num_blocks;
@@ -535,6 +590,8 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base
		return -1;
	}

	spdk_uuid_copy(&part->internal.bdev.uuid, &opts.uuid);

	base->ref++;
	part->internal.base = base;

@@ -575,3 +632,12 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base

	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);
}
+2 −0
Original line number Diff line number Diff line
@@ -152,7 +152,9 @@
	spdk_bdev_part_free;
	spdk_bdev_part_base_hotremove;
	spdk_bdev_part_base_construct_ext;
	spdk_bdev_part_construct_opts_init;
	spdk_bdev_part_construct;
	spdk_bdev_part_construct_ext;
	spdk_bdev_part_submit_request;
	spdk_bdev_part_submit_request_ext;
	spdk_bdev_part_get_bdev;
+44 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright (C) 2018 Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 */

#include "spdk_cunit.h"
@@ -393,6 +394,48 @@ part_get_io_channel_test(void)
	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
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_free_test);
	CU_ADD_TEST(suite, part_get_io_channel_test);
	CU_ADD_TEST(suite, part_construct_ext);

	allocate_cores(1);
	allocate_threads(1);