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:
parent
4ee51dcbc7
commit
7f6c737a25
@ -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.
|
||||
*
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user