bdev.c: encapsulate members of spdk_bdev_part.

Change-Id: Ia3d04905d319c075a12726ca85c3aa1d3135db44
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/417176
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Seth Howell 2018-06-28 10:37:00 -07:00 committed by Jim Harris
parent 575a4025c5
commit 6b7609b639
6 changed files with 129 additions and 42 deletions

View File

@ -35,6 +35,11 @@ on each call. This allows multiple callers to query I/O statistics without confl
with each other. Existing users will need to adjust their code to record the previous
I/O statistics to calculate the delta between calls.
A new public header file bdev_module.h has been introduced to facilitate the development
of new bdev modules. This header includes an interface for the spdk_bdev_part and
spdk_bdev_part_base objects to enable the creation of multiple virtual bdevs on top of a
single base bdev.
### Env
The spdk_mem_map_translate() function now takes a size parameter to indicate the size of

View File

@ -736,10 +736,24 @@ uint32_t spdk_bdev_part_base_get_ref(struct spdk_bdev_part_base *part_base);
typedef void (*spdk_bdev_part_base_free_fn)(void *ctx);
struct spdk_bdev_part {
struct spdk_bdev bdev;
struct spdk_bdev_part_base *base;
uint64_t offset_blocks;
/* Entry into the module's global list of bdev parts */
TAILQ_ENTRY(spdk_bdev_part) tailq;
/**
* Fields that are used internally by part.c These fields should only
* be accessed from a module using any pertinent get and set methods.
*/
struct bdev_part_internal_fields {
/* This part's corresponding bdev object. Not to be confused with the base bdev */
struct spdk_bdev bdev;
/* The base to which this part belongs */
struct spdk_bdev_part_base *base;
/* number of blocks from the start of the base bdev to the start of this part */
uint64_t offset_blocks;
} internal;
};
struct spdk_bdev_part_channel {
@ -830,6 +844,47 @@ int spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_
*/
void spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io);
/**
* Return a pointer to this part's spdk_bdev.
*
* \param part An spdk_bdev_part object.
*
* \return A pointer to this part's spdk_bdev object.
*/
struct spdk_bdev *spdk_bdev_part_get_bdev(struct spdk_bdev_part *part);
/**
* Return a pointer to this part's base.
*
* \param part An spdk_bdev_part object.
*
* \return A pointer to this part's spdk_bdev_part_base object.
*/
struct spdk_bdev_part_base *spdk_bdev_part_get_base(struct spdk_bdev_part *part);
/**
* Return a pointer to this part's base bdev.
*
* The return value of this function is equivalent to calling
* spdk_bdev_part_base_get_bdev on this part's base.
*
* \param part An spdk_bdev_part object.
*
* \return A pointer to the bdev belonging to this part's base.
*/
struct spdk_bdev *spdk_bdev_part_get_base_bdev(struct spdk_bdev_part *part);
/**
* Return this part's offset from the beginning of the base bdev.
*
* This function should not be called in the I/O path. Any block
* translations to I/O will be handled in spdk_bdev_part_submit_request.
*
* \param part An spdk_bdev_part object.
*
* \return the block offset of this part from it's underlying bdev.
*/
uint64_t spdk_bdev_part_get_offset_blocks(struct spdk_bdev_part *part);
/*
* Macro used to register module for later initialization.

View File

@ -113,7 +113,7 @@ spdk_vbdev_inject_error(char *name, uint32_t io_type, uint32_t error_type, uint3
}
TAILQ_FOREACH(part, &g_error_disks, tailq) {
if (bdev == &part->bdev) {
if (bdev == spdk_bdev_part_get_bdev(part)) {
error_disk = (struct error_disk *)part;
break;
}
@ -206,7 +206,7 @@ static int
vbdev_error_destruct(void *ctx)
{
struct error_disk *error_disk = ctx;
struct spdk_bdev *base_bdev = spdk_bdev_part_base_get_bdev(error_disk->part.base);
struct spdk_bdev *base_bdev = spdk_bdev_part_get_base_bdev(&error_disk->part);
int rc;
rc = vbdev_error_config_remove(base_bdev->name);
@ -221,7 +221,7 @@ static int
vbdev_error_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
{
struct error_disk *error_disk = ctx;
struct spdk_bdev *base_bdev = spdk_bdev_part_base_get_bdev(error_disk->part.base);
struct spdk_bdev *base_bdev = spdk_bdev_part_get_base_bdev(&error_disk->part);
spdk_json_write_name(w, "error_disk");
spdk_json_write_object_begin(w);

View File

@ -193,10 +193,12 @@ static int
vbdev_gpt_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
{
struct gpt_disk *gpt_disk = SPDK_CONTAINEROF(ctx, struct gpt_disk, part);
struct gpt_base *gpt_base = spdk_bdev_part_base_get_ctx(gpt_disk->part.base);
struct spdk_bdev *part_base_bdev = spdk_bdev_part_base_get_bdev(gpt_disk->part.base);
struct spdk_bdev_part_base *base_bdev = spdk_bdev_part_get_base(&gpt_disk->part);
struct gpt_base *gpt_base = spdk_bdev_part_base_get_ctx(base_bdev);
struct spdk_bdev *part_base_bdev = spdk_bdev_part_base_get_bdev(base_bdev);
struct spdk_gpt *gpt = &gpt_base->gpt;
struct spdk_gpt_partition_entry *gpt_entry = &gpt->partitions[gpt_disk->partition_index];
uint64_t offset_blocks = spdk_bdev_part_get_offset_blocks(&gpt_disk->part);
spdk_json_write_name(w, "gpt");
spdk_json_write_object_begin(w);
@ -205,7 +207,7 @@ vbdev_gpt_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
spdk_json_write_string(w, spdk_bdev_get_name(part_base_bdev));
spdk_json_write_name(w, "offset_blocks");
spdk_json_write_uint64(w, gpt_disk->part.offset_blocks);
spdk_json_write_uint64(w, offset_blocks);
spdk_json_write_name(w, "partition_type_guid");
write_guid(w, &gpt_entry->part_type_guid);

View File

@ -107,9 +107,9 @@ spdk_bdev_part_free_cb(void *io_device)
struct spdk_bdev_part_base *base;
assert(part);
assert(part->base);
assert(part->internal.base);
base = part->base;
base = part->internal.base;
TAILQ_REMOVE(base->tailq, part, tailq);
@ -118,8 +118,8 @@ spdk_bdev_part_free_cb(void *io_device)
spdk_bdev_part_base_free(base);
}
spdk_bdev_destruct_done(&part->bdev, 0);
free(part->bdev.name);
spdk_bdev_destruct_done(&part->internal.bdev, 0);
free(part->internal.bdev.name);
free(part);
}
@ -139,8 +139,8 @@ spdk_bdev_part_base_hotremove(struct spdk_bdev *base_bdev, struct bdev_part_tail
struct spdk_bdev_part *part, *tmp;
TAILQ_FOREACH_SAFE(part, tailq, tailq, tmp) {
if (part->base->bdev == base_bdev) {
spdk_bdev_unregister(&part->bdev, NULL, NULL);
if (part->internal.base->bdev == base_bdev) {
spdk_bdev_unregister(&part->internal.bdev, NULL, NULL);
}
}
}
@ -150,7 +150,7 @@ spdk_bdev_part_io_type_supported(void *_part, enum spdk_bdev_io_type io_type)
{
struct spdk_bdev_part *part = _part;
return part->base->bdev->fn_table->io_type_supported(part->base->bdev, io_type);
return part->internal.base->bdev->fn_table->io_type_supported(part->internal.base->bdev, io_type);
}
static struct spdk_io_channel *
@ -161,6 +161,30 @@ spdk_bdev_part_get_io_channel(void *_part)
return spdk_get_io_channel(part);
}
struct spdk_bdev *
spdk_bdev_part_get_bdev(struct spdk_bdev_part *part)
{
return &part->internal.bdev;
}
struct spdk_bdev_part_base *
spdk_bdev_part_get_base(struct spdk_bdev_part *part)
{
return part->internal.base;
}
struct spdk_bdev *
spdk_bdev_part_get_base_bdev(struct spdk_bdev_part *part)
{
return part->internal.base->bdev;
}
uint64_t
spdk_bdev_part_get_offset_blocks(struct spdk_bdev_part *part)
{
return part->internal.offset_blocks;
}
static void
spdk_bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
{
@ -176,38 +200,38 @@ spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bde
{
struct spdk_bdev_part *part = ch->part;
struct spdk_io_channel *base_ch = ch->base_ch;
struct spdk_bdev_desc *base_desc = part->base->desc;
struct spdk_bdev_desc *base_desc = part->internal.base->desc;
uint64_t offset;
int rc = 0;
/* Modify the I/O to adjust for the offset within the base bdev. */
switch (bdev_io->type) {
case SPDK_BDEV_IO_TYPE_READ:
offset = bdev_io->u.bdev.offset_blocks + part->offset_blocks;
offset = bdev_io->u.bdev.offset_blocks + part->internal.offset_blocks;
rc = spdk_bdev_readv_blocks(base_desc, base_ch, bdev_io->u.bdev.iovs,
bdev_io->u.bdev.iovcnt, offset,
bdev_io->u.bdev.num_blocks, spdk_bdev_part_complete_io,
bdev_io);
break;
case SPDK_BDEV_IO_TYPE_WRITE:
offset = bdev_io->u.bdev.offset_blocks + part->offset_blocks;
offset = bdev_io->u.bdev.offset_blocks + part->internal.offset_blocks;
rc = spdk_bdev_writev_blocks(base_desc, base_ch, bdev_io->u.bdev.iovs,
bdev_io->u.bdev.iovcnt, offset,
bdev_io->u.bdev.num_blocks, spdk_bdev_part_complete_io,
bdev_io);
break;
case SPDK_BDEV_IO_TYPE_WRITE_ZEROES:
offset = bdev_io->u.bdev.offset_blocks + part->offset_blocks;
offset = bdev_io->u.bdev.offset_blocks + part->internal.offset_blocks;
rc = spdk_bdev_write_zeroes_blocks(base_desc, base_ch, offset, bdev_io->u.bdev.num_blocks,
spdk_bdev_part_complete_io, bdev_io);
break;
case SPDK_BDEV_IO_TYPE_UNMAP:
offset = bdev_io->u.bdev.offset_blocks + part->offset_blocks;
offset = bdev_io->u.bdev.offset_blocks + part->internal.offset_blocks;
rc = spdk_bdev_unmap_blocks(base_desc, base_ch, offset, bdev_io->u.bdev.num_blocks,
spdk_bdev_part_complete_io, bdev_io);
break;
case SPDK_BDEV_IO_TYPE_FLUSH:
offset = bdev_io->u.bdev.offset_blocks + part->offset_blocks;
offset = bdev_io->u.bdev.offset_blocks + part->internal.offset_blocks;
rc = spdk_bdev_flush_blocks(base_desc, base_ch, offset, bdev_io->u.bdev.num_blocks,
spdk_bdev_part_complete_io, bdev_io);
break;
@ -232,13 +256,13 @@ spdk_bdev_part_channel_create_cb(void *io_device, void *ctx_buf)
struct spdk_bdev_part_channel *ch = ctx_buf;
ch->part = part;
ch->base_ch = spdk_bdev_get_io_channel(part->base->desc);
ch->base_ch = spdk_bdev_get_io_channel(part->internal.base->desc);
if (ch->base_ch == NULL) {
return -1;
}
if (part->base->ch_create_cb) {
return part->base->ch_create_cb(io_device, ctx_buf);
if (part->internal.base->ch_create_cb) {
return part->internal.base->ch_create_cb(io_device, ctx_buf);
} else {
return 0;
}
@ -250,8 +274,8 @@ spdk_bdev_part_channel_destroy_cb(void *io_device, void *ctx_buf)
struct spdk_bdev_part *part = (struct spdk_bdev_part *)io_device;
struct spdk_bdev_part_channel *ch = ctx_buf;
if (part->base->ch_destroy_cb) {
part->base->ch_destroy_cb(io_device, ctx_buf);
if (part->internal.base->ch_destroy_cb) {
part->internal.base->ch_destroy_cb(io_device, ctx_buf);
}
spdk_put_io_channel(ch->base_ch);
}
@ -303,20 +327,20 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base
char *name, uint64_t offset_blocks, uint64_t num_blocks,
char *product_name)
{
part->bdev.name = name;
part->bdev.blocklen = base->bdev->blocklen;
part->bdev.blockcnt = num_blocks;
part->offset_blocks = offset_blocks;
part->internal.bdev.name = name;
part->internal.bdev.blocklen = base->bdev->blocklen;
part->internal.bdev.blockcnt = num_blocks;
part->internal.offset_blocks = offset_blocks;
part->bdev.write_cache = base->bdev->write_cache;
part->bdev.need_aligned_buffer = base->bdev->need_aligned_buffer;
part->bdev.product_name = product_name;
part->bdev.ctxt = part;
part->bdev.module = base->module;
part->bdev.fn_table = base->fn_table;
part->internal.bdev.write_cache = base->bdev->write_cache;
part->internal.bdev.need_aligned_buffer = base->bdev->need_aligned_buffer;
part->internal.bdev.product_name = product_name;
part->internal.bdev.ctxt = part;
part->internal.bdev.module = base->module;
part->internal.bdev.fn_table = base->fn_table;
__sync_fetch_and_add(&base->ref, 1);
part->base = base;
part->internal.base = base;
if (!base->claimed) {
int rc;
@ -324,7 +348,7 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base
rc = spdk_bdev_module_claim_bdev(base->bdev, base->desc, base->module);
if (rc) {
SPDK_ERRLOG("could not claim bdev %s\n", spdk_bdev_get_name(base->bdev));
free(part->bdev.name);
free(part->internal.bdev.name);
return -1;
}
base->claimed = true;
@ -333,7 +357,7 @@ spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_base
spdk_io_device_register(part, spdk_bdev_part_channel_create_cb,
spdk_bdev_part_channel_destroy_cb,
base->channel_size);
spdk_vbdev_register(&part->bdev, &base->bdev, 1);
spdk_vbdev_register(&part->internal.bdev, &base->bdev, 1);
TAILQ_INSERT_TAIL(base->tailq, part, tailq);
return 0;

View File

@ -121,7 +121,8 @@ static int
vbdev_split_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
{
struct spdk_bdev_part *part = ctx;
struct spdk_bdev *split_base_bdev = spdk_bdev_part_base_get_bdev(part->base);
struct spdk_bdev *split_base_bdev = spdk_bdev_part_get_base_bdev(part);
uint64_t offset_blocks = spdk_bdev_part_get_offset_blocks(part);
spdk_json_write_name(w, "split");
spdk_json_write_object_begin(w);
@ -129,7 +130,7 @@ vbdev_split_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
spdk_json_write_name(w, "base_bdev");
spdk_json_write_string(w, spdk_bdev_get_name(split_base_bdev));
spdk_json_write_name(w, "offset_blocks");
spdk_json_write_uint64(w, part->offset_blocks);
spdk_json_write_uint64(w, offset_blocks);
spdk_json_write_object_end(w);