bdev: add virtual to base bdev relationships

Each virtual bdev now has a pointer to its base
bdev, and a base bdev has a pointers to any virtual
bdevs built on top of it.

Also add a new set of leaf iterators, to get only
bdevs that have no virtual bdevs built on top of
them.  These iterators are now used by the bdevio and
bdevperf utilities, in advance of the claim/unclaim
semantics getting removed in a future patch.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I669783764407cdd4920b5ee121959e2a58c8d436

Reviewed-on: https://review.gerrithub.io/367610
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Jim Harris 2017-06-29 13:16:26 -07:00
parent 4ee51dcbc7
commit 7f6c737a25
7 changed files with 111 additions and 11 deletions

View File

@ -126,9 +126,19 @@ void spdk_bdev_config_text(FILE *fp);
struct spdk_bdev *spdk_bdev_get_by_name(const char *bdev_name);
/**
* These two functions iterate the full list of bdevs, including bdevs
* that have virtual bdevs on top of them.
*/
struct spdk_bdev *spdk_bdev_first(void);
struct spdk_bdev *spdk_bdev_next(struct spdk_bdev *prev);
/**
* These two functions only iterate over bdevs which have no virtual
* bdevs on top of them.
*/
struct spdk_bdev *spdk_bdev_first_leaf(void);
struct spdk_bdev *spdk_bdev_next_leaf(struct spdk_bdev *prev);
/**
* Claim ownership of a block device.
*

View File

@ -201,6 +201,16 @@ struct spdk_bdev {
/** The bdev status */
enum spdk_bdev_status status;
/** The list of block devices that this block device is built on top of (if any). */
TAILQ_HEAD(, spdk_bdev) base_bdevs;
TAILQ_ENTRY(spdk_bdev) base_bdev_link;
/** The list of virtual block devices built on top of this block device. */
TAILQ_HEAD(, spdk_bdev) vbdevs;
TAILQ_ENTRY(spdk_bdev) vbdev_link;
/** Remove callback function pointer to upper level stack */
spdk_bdev_remove_cb_t remove_cb;
@ -354,6 +364,10 @@ struct spdk_bdev_io {
void spdk_bdev_register(struct spdk_bdev *bdev);
void spdk_bdev_unregister(struct spdk_bdev *bdev);
void spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs,
int base_bdev_count);
void spdk_vbdev_unregister(struct spdk_bdev *vbdev);
void spdk_bdev_poller_start(struct spdk_bdev_poller **ppoller,
spdk_bdev_poller_fn fn,
void *arg,

View File

@ -147,6 +147,48 @@ spdk_bdev_next(struct spdk_bdev *prev)
return bdev;
}
static struct spdk_bdev *
_bdev_next_leaf(struct spdk_bdev *bdev)
{
while (bdev != NULL) {
if (TAILQ_EMPTY(&bdev->vbdevs)) {
return bdev;
} else {
bdev = TAILQ_NEXT(bdev, link);
}
}
return bdev;
}
struct spdk_bdev *
spdk_bdev_first_leaf(void)
{
struct spdk_bdev *bdev;
bdev = _bdev_next_leaf(TAILQ_FIRST(&g_bdev_mgr.bdevs));
if (bdev) {
SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Starting bdev iteration at %s\n", bdev->name);
}
return bdev;
}
struct spdk_bdev *
spdk_bdev_next_leaf(struct spdk_bdev *prev)
{
struct spdk_bdev *bdev;
bdev = _bdev_next_leaf(TAILQ_NEXT(prev, link));
if (bdev) {
SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Continuing bdev iteration at %s\n", bdev->name);
}
return bdev;
}
struct spdk_bdev *
spdk_bdev_get_by_name(const char *bdev_name)
{
@ -1313,14 +1355,17 @@ spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, int *sct, int *
}
}
void
spdk_bdev_register(struct spdk_bdev *bdev)
static void
_spdk_bdev_register(struct spdk_bdev *bdev)
{
struct spdk_bdev_module_if *vbdev_module;
/* initialize the reset generation value to zero */
bdev->gencnt = 0;
TAILQ_INIT(&bdev->vbdevs);
TAILQ_INIT(&bdev->base_bdevs);
bdev->reset_in_progress = false;
TAILQ_INIT(&bdev->queued_resets);
@ -1339,6 +1384,25 @@ spdk_bdev_register(struct spdk_bdev *bdev)
}
}
void
spdk_bdev_register(struct spdk_bdev *bdev)
{
_spdk_bdev_register(bdev);
}
void
spdk_vbdev_register(struct spdk_bdev *vbdev, struct spdk_bdev **base_bdevs, int base_bdev_count)
{
int i;
_spdk_bdev_register(vbdev);
for (i = 0; i < base_bdev_count; i++) {
assert(base_bdevs[i] != NULL);
TAILQ_INSERT_TAIL(&vbdev->base_bdevs, base_bdevs[i], base_bdev_link);
TAILQ_INSERT_TAIL(&base_bdevs[i]->vbdevs, vbdev, vbdev_link);
}
}
void
spdk_bdev_unregister(struct spdk_bdev *bdev)
{
@ -1372,6 +1436,18 @@ spdk_bdev_unregister(struct spdk_bdev *bdev)
}
}
void
spdk_vbdev_unregister(struct spdk_bdev *vbdev)
{
struct spdk_bdev *base_bdev;
assert(!TAILQ_EMPTY(&vbdev->base_bdevs));
TAILQ_FOREACH(base_bdev, &vbdev->base_bdevs, base_bdev_link) {
TAILQ_REMOVE(&base_bdev->vbdevs, vbdev, vbdev_link);
}
spdk_bdev_unregister(vbdev);
}
bool
spdk_bdev_claim(struct spdk_bdev *bdev, spdk_bdev_remove_cb_t remove_cb,
void *remove_ctx)

View File

@ -240,7 +240,7 @@ spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
disk->disk.ctxt = disk;
disk->disk.fn_table = &vbdev_error_fn_table;
spdk_bdev_register(&disk->disk);
spdk_vbdev_register(&disk->disk, &base_bdev, 1);
TAILQ_INSERT_TAIL(&g_vbdev_error_disks, disk, tailq);

View File

@ -319,7 +319,7 @@ vbdev_split_create(struct spdk_bdev *base_bdev, uint64_t split_count, uint64_t s
vbdev_split_base_get_ref(split_base, d);
spdk_bdev_register(&d->disk);
spdk_vbdev_register(&d->disk, &base_bdev, 1);
TAILQ_INSERT_TAIL(&g_split_disks, d, tailq);

View File

@ -106,13 +106,13 @@ bdevio_construct_targets(void)
printf("I/O targets:\n");
bdev = spdk_bdev_first();
bdev = spdk_bdev_first_leaf();
while (bdev != NULL) {
uint64_t num_blocks = spdk_bdev_get_num_blocks(bdev);
uint32_t block_size = spdk_bdev_get_block_size(bdev);
if (!spdk_bdev_claim(bdev, NULL, NULL)) {
bdev = spdk_bdev_next(bdev);
bdev = spdk_bdev_next_leaf(bdev);
continue;
}
@ -130,7 +130,7 @@ bdevio_construct_targets(void)
execute_spdk_function(__get_io_channel, target, NULL);
g_io_targets = target;
bdev = spdk_bdev_next(bdev);
bdev = spdk_bdev_next_leaf(bdev);
}
return 0;

View File

@ -117,17 +117,17 @@ bdevperf_construct_targets(void)
struct io_target *target;
size_t align;
bdev = spdk_bdev_first();
bdev = spdk_bdev_first_leaf();
while (bdev != NULL) {
if (!spdk_bdev_claim(bdev, NULL, NULL)) {
bdev = spdk_bdev_next(bdev);
bdev = spdk_bdev_next_leaf(bdev);
continue;
}
if (g_unmap && !spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)) {
printf("Skipping %s because it does not support unmap\n", spdk_bdev_get_name(bdev));
bdev = spdk_bdev_next(bdev);
bdev = spdk_bdev_next_leaf(bdev);
continue;
}
@ -161,7 +161,7 @@ bdevperf_construct_targets(void)
head[index] = target;
g_target_count++;
bdev = spdk_bdev_next(bdev);
bdev = spdk_bdev_next_leaf(bdev);
}
}