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 with each other. Existing users will need to adjust their code to record the previous
I/O statistics to calculate the delta between calls. 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 ### Env
The spdk_mem_map_translate() function now takes a size parameter to indicate the size of 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); typedef void (*spdk_bdev_part_base_free_fn)(void *ctx);
struct spdk_bdev_part { struct spdk_bdev_part {
struct spdk_bdev bdev; /* Entry into the module's global list of bdev parts */
struct spdk_bdev_part_base *base;
uint64_t offset_blocks;
TAILQ_ENTRY(spdk_bdev_part) tailq; 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 { 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); 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. * 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) { 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; error_disk = (struct error_disk *)part;
break; break;
} }
@ -206,7 +206,7 @@ static int
vbdev_error_destruct(void *ctx) vbdev_error_destruct(void *ctx)
{ {
struct error_disk *error_disk = 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; int rc;
rc = vbdev_error_config_remove(base_bdev->name); 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) vbdev_error_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
{ {
struct error_disk *error_disk = 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);
spdk_json_write_name(w, "error_disk"); spdk_json_write_name(w, "error_disk");
spdk_json_write_object_begin(w); 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) 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_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 *base_bdev = spdk_bdev_part_get_base(&gpt_disk->part);
struct spdk_bdev *part_base_bdev = spdk_bdev_part_base_get_bdev(gpt_disk->part.base); 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 *gpt = &gpt_base->gpt;
struct spdk_gpt_partition_entry *gpt_entry = &gpt->partitions[gpt_disk->partition_index]; 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_name(w, "gpt");
spdk_json_write_object_begin(w); 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_string(w, spdk_bdev_get_name(part_base_bdev));
spdk_json_write_name(w, "offset_blocks"); 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"); spdk_json_write_name(w, "partition_type_guid");
write_guid(w, &gpt_entry->part_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; struct spdk_bdev_part_base *base;
assert(part); assert(part);
assert(part->base); assert(part->internal.base);
base = part->base; base = part->internal.base;
TAILQ_REMOVE(base->tailq, part, tailq); 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_part_base_free(base);
} }
spdk_bdev_destruct_done(&part->bdev, 0); spdk_bdev_destruct_done(&part->internal.bdev, 0);
free(part->bdev.name); free(part->internal.bdev.name);
free(part); 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; struct spdk_bdev_part *part, *tmp;
TAILQ_FOREACH_SAFE(part, tailq, tailq, tmp) { TAILQ_FOREACH_SAFE(part, tailq, tailq, tmp) {
if (part->base->bdev == base_bdev) { if (part->internal.base->bdev == base_bdev) {
spdk_bdev_unregister(&part->bdev, NULL, NULL); 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; 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 * static struct spdk_io_channel *
@ -161,6 +161,30 @@ spdk_bdev_part_get_io_channel(void *_part)
return spdk_get_io_channel(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 static void
spdk_bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 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_bdev_part *part = ch->part;
struct spdk_io_channel *base_ch = ch->base_ch; 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; uint64_t offset;
int rc = 0; int rc = 0;
/* Modify the I/O to adjust for the offset within the base bdev. */ /* Modify the I/O to adjust for the offset within the base bdev. */
switch (bdev_io->type) { switch (bdev_io->type) {
case SPDK_BDEV_IO_TYPE_READ: 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, rc = spdk_bdev_readv_blocks(base_desc, base_ch, bdev_io->u.bdev.iovs,
bdev_io->u.bdev.iovcnt, offset, bdev_io->u.bdev.iovcnt, offset,
bdev_io->u.bdev.num_blocks, spdk_bdev_part_complete_io, bdev_io->u.bdev.num_blocks, spdk_bdev_part_complete_io,
bdev_io); bdev_io);
break; break;
case SPDK_BDEV_IO_TYPE_WRITE: 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, rc = spdk_bdev_writev_blocks(base_desc, base_ch, bdev_io->u.bdev.iovs,
bdev_io->u.bdev.iovcnt, offset, bdev_io->u.bdev.iovcnt, offset,
bdev_io->u.bdev.num_blocks, spdk_bdev_part_complete_io, bdev_io->u.bdev.num_blocks, spdk_bdev_part_complete_io,
bdev_io); bdev_io);
break; break;
case SPDK_BDEV_IO_TYPE_WRITE_ZEROES: 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, rc = spdk_bdev_write_zeroes_blocks(base_desc, base_ch, offset, bdev_io->u.bdev.num_blocks,
spdk_bdev_part_complete_io, bdev_io); spdk_bdev_part_complete_io, bdev_io);
break; break;
case SPDK_BDEV_IO_TYPE_UNMAP: 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, rc = spdk_bdev_unmap_blocks(base_desc, base_ch, offset, bdev_io->u.bdev.num_blocks,
spdk_bdev_part_complete_io, bdev_io); spdk_bdev_part_complete_io, bdev_io);
break; break;
case SPDK_BDEV_IO_TYPE_FLUSH: 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, rc = spdk_bdev_flush_blocks(base_desc, base_ch, offset, bdev_io->u.bdev.num_blocks,
spdk_bdev_part_complete_io, bdev_io); spdk_bdev_part_complete_io, bdev_io);
break; 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; struct spdk_bdev_part_channel *ch = ctx_buf;
ch->part = part; 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) { if (ch->base_ch == NULL) {
return -1; return -1;
} }
if (part->base->ch_create_cb) { if (part->internal.base->ch_create_cb) {
return part->base->ch_create_cb(io_device, ctx_buf); return part->internal.base->ch_create_cb(io_device, ctx_buf);
} else { } else {
return 0; 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 *part = (struct spdk_bdev_part *)io_device;
struct spdk_bdev_part_channel *ch = ctx_buf; struct spdk_bdev_part_channel *ch = ctx_buf;
if (part->base->ch_destroy_cb) { if (part->internal.base->ch_destroy_cb) {
part->base->ch_destroy_cb(io_device, ctx_buf); part->internal.base->ch_destroy_cb(io_device, ctx_buf);
} }
spdk_put_io_channel(ch->base_ch); 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 *name, uint64_t offset_blocks, uint64_t num_blocks,
char *product_name) char *product_name)
{ {
part->bdev.name = name; part->internal.bdev.name = name;
part->bdev.blocklen = base->bdev->blocklen; part->internal.bdev.blocklen = base->bdev->blocklen;
part->bdev.blockcnt = num_blocks; part->internal.bdev.blockcnt = num_blocks;
part->offset_blocks = offset_blocks; part->internal.offset_blocks = offset_blocks;
part->bdev.write_cache = base->bdev->write_cache; part->internal.bdev.write_cache = base->bdev->write_cache;
part->bdev.need_aligned_buffer = base->bdev->need_aligned_buffer; part->internal.bdev.need_aligned_buffer = base->bdev->need_aligned_buffer;
part->bdev.product_name = product_name; part->internal.bdev.product_name = product_name;
part->bdev.ctxt = part; part->internal.bdev.ctxt = part;
part->bdev.module = base->module; part->internal.bdev.module = base->module;
part->bdev.fn_table = base->fn_table; part->internal.bdev.fn_table = base->fn_table;
__sync_fetch_and_add(&base->ref, 1); __sync_fetch_and_add(&base->ref, 1);
part->base = base; part->internal.base = base;
if (!base->claimed) { if (!base->claimed) {
int rc; 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); rc = spdk_bdev_module_claim_bdev(base->bdev, base->desc, base->module);
if (rc) { if (rc) {
SPDK_ERRLOG("could not claim bdev %s\n", spdk_bdev_get_name(base->bdev)); 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; return -1;
} }
base->claimed = true; 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_io_device_register(part, spdk_bdev_part_channel_create_cb,
spdk_bdev_part_channel_destroy_cb, spdk_bdev_part_channel_destroy_cb,
base->channel_size); 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); TAILQ_INSERT_TAIL(base->tailq, part, tailq);
return 0; return 0;

View File

@ -121,7 +121,8 @@ static int
vbdev_split_dump_info_json(void *ctx, struct spdk_json_write_ctx *w) vbdev_split_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
{ {
struct spdk_bdev_part *part = ctx; 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_name(w, "split");
spdk_json_write_object_begin(w); 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_name(w, "base_bdev");
spdk_json_write_string(w, spdk_bdev_get_name(split_base_bdev)); spdk_json_write_string(w, spdk_bdev_get_name(split_base_bdev));
spdk_json_write_name(w, "offset_blocks"); 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); spdk_json_write_object_end(w);