From 3559bec4f93e81d0a96bafddf67b2d042e72bc07 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Mon, 26 Feb 2018 13:22:38 -0700 Subject: [PATCH] bdev: move part helper code into its own file Change-Id: I05505c469cac96a5e4812f2f65a7342ceec0a28c Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/401511 Tested-by: SPDK Automated Test System Reviewed-by: Changpeng Liu Reviewed-by: Dariusz Stojaczyk Reviewed-by: Jim Harris --- lib/bdev/Makefile | 2 +- lib/bdev/bdev.c | 229 ----------------------- lib/bdev/part.c | 270 +++++++++++++++++++++++++++ test/unit/lib/bdev/Makefile | 2 +- test/unit/lib/bdev/bdev.c/bdev_ut.c | 55 ------ test/unit/lib/bdev/part.c/.gitignore | 1 + test/unit/lib/bdev/part.c/Makefile | 40 ++++ test/unit/lib/bdev/part.c/part_ut.c | 140 ++++++++++++++ unittest.sh | 1 + 9 files changed, 454 insertions(+), 286 deletions(-) create mode 100644 lib/bdev/part.c create mode 100644 test/unit/lib/bdev/part.c/.gitignore create mode 100644 test/unit/lib/bdev/part.c/Makefile create mode 100644 test/unit/lib/bdev/part.c/part_ut.c diff --git a/lib/bdev/Makefile b/lib/bdev/Makefile index 78652dbb7d..bc0d97b6e5 100644 --- a/lib/bdev/Makefile +++ b/lib/bdev/Makefile @@ -38,7 +38,7 @@ ifeq ($(CONFIG_VTUNE),y) CFLAGS += -I$(VTUNE_SOURCE_DIR)/include -I$(VTUNE_SOURCE_DIR)/sdk/src/ittnotify endif -C_SRCS = bdev.c scsi_nvme.c +C_SRCS = bdev.c part.c scsi_nvme.c C_SRCS-$(CONFIG_VTUNE) += vtune.c LIBNAME = bdev diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index e52d939b91..4392cbd825 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -2363,74 +2363,6 @@ spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module) } } -void -spdk_bdev_part_base_free(struct spdk_bdev_part_base *base) -{ - if (base->desc) { - spdk_bdev_close(base->desc); - base->desc = NULL; - } - base->base_free_fn(base); -} - -void -spdk_bdev_part_free(struct spdk_bdev_part *part) -{ - struct spdk_bdev_part_base *base; - - assert(part); - assert(part->base); - - base = part->base; - spdk_io_device_unregister(part, NULL); - TAILQ_REMOVE(base->tailq, part, tailq); - free(part->bdev.name); - free(part); - - if (__sync_sub_and_fetch(&base->ref, 1) == 0) { - spdk_bdev_module_release_bdev(base->bdev); - spdk_bdev_part_base_free(base); - } -} - -void -spdk_bdev_part_base_hotremove(struct spdk_bdev *base_bdev, struct bdev_part_tailq *tailq) -{ - 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); - } - } -} - -static bool -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); -} - -static struct spdk_io_channel * -spdk_bdev_part_get_io_channel(void *_part) -{ - struct spdk_bdev_part *part = _part; - - return spdk_get_io_channel(part); -} - -static void -spdk_bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) -{ - struct spdk_bdev_io *part_io = cb_arg; - int status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; - - spdk_bdev_io_complete(part_io, status); - spdk_bdev_free_io(bdev_io); -} - static void spdk_bdev_write_zeroes_split(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) { @@ -2461,165 +2393,4 @@ spdk_bdev_write_zeroes_split(struct spdk_bdev_io *bdev_io, bool success, void *c spdk_bdev_io_submit(bdev_io); } -void -spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io) -{ - 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; - 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; - 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; - 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; - 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; - 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; - rc = spdk_bdev_flush_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_RESET: - rc = spdk_bdev_reset(base_desc, base_ch, - spdk_bdev_part_complete_io, bdev_io); - break; - default: - SPDK_ERRLOG("split: unknown I/O type %d\n", bdev_io->type); - spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); - return; - } - - if (rc != 0) { - spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); - } -} -static int -spdk_bdev_part_channel_create_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; - - ch->part = part; - ch->base_ch = spdk_bdev_get_io_channel(part->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); - } else { - return 0; - } -} - -static void -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); - } - spdk_put_io_channel(ch->base_ch); -} - -int -spdk_bdev_part_base_construct(struct spdk_bdev_part_base *base, struct spdk_bdev *bdev, - spdk_bdev_remove_cb_t remove_cb, struct spdk_bdev_module_if *module, - struct spdk_bdev_fn_table *fn_table, struct bdev_part_tailq *tailq, - spdk_bdev_part_base_free_fn free_fn, - uint32_t channel_size, spdk_io_channel_create_cb ch_create_cb, - spdk_io_channel_destroy_cb ch_destroy_cb) -{ - int rc; - - fn_table->get_io_channel = spdk_bdev_part_get_io_channel; - fn_table->io_type_supported = spdk_bdev_part_io_type_supported; - - base->bdev = bdev; - base->desc = NULL; - base->ref = 0; - base->module = module; - base->fn_table = fn_table; - base->tailq = tailq; - base->claimed = false; - base->channel_size = channel_size; - base->ch_create_cb = ch_create_cb; - base->ch_destroy_cb = ch_destroy_cb; - base->base_free_fn = free_fn; - - rc = spdk_bdev_open(bdev, false, remove_cb, bdev, &base->desc); - if (rc) { - spdk_bdev_part_base_free(base); - SPDK_ERRLOG("could not open bdev %s\n", spdk_bdev_get_name(bdev)); - return -1; - } - - return 0; -} - -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) -{ - part->bdev.name = name; - part->bdev.blocklen = base->bdev->blocklen; - part->bdev.blockcnt = num_blocks; - part->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; - - __sync_fetch_and_add(&base->ref, 1); - part->base = base; - - if (!base->claimed) { - int rc; - - 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); - return -1; - } - base->claimed = true; - } - - 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); - TAILQ_INSERT_TAIL(base->tailq, part, tailq); - - return 0; -} - SPDK_LOG_REGISTER_COMPONENT("bdev", SPDK_LOG_BDEV) diff --git a/lib/bdev/part.c b/lib/bdev/part.c new file mode 100644 index 0000000000..52552cc75f --- /dev/null +++ b/lib/bdev/part.c @@ -0,0 +1,270 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Common code for partition-like virtual bdevs. + */ + +#include "spdk/bdev.h" +#include "spdk/log.h" + +#include "spdk_internal/bdev.h" + +void +spdk_bdev_part_base_free(struct spdk_bdev_part_base *base) +{ + if (base->desc) { + spdk_bdev_close(base->desc); + base->desc = NULL; + } + base->base_free_fn(base); +} + +void +spdk_bdev_part_free(struct spdk_bdev_part *part) +{ + struct spdk_bdev_part_base *base; + + assert(part); + assert(part->base); + + base = part->base; + spdk_io_device_unregister(part, NULL); + TAILQ_REMOVE(base->tailq, part, tailq); + free(part->bdev.name); + free(part); + + if (__sync_sub_and_fetch(&base->ref, 1) == 0) { + spdk_bdev_module_release_bdev(base->bdev); + spdk_bdev_part_base_free(base); + } +} + +void +spdk_bdev_part_base_hotremove(struct spdk_bdev *base_bdev, struct bdev_part_tailq *tailq) +{ + 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); + } + } +} + +static bool +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); +} + +static struct spdk_io_channel * +spdk_bdev_part_get_io_channel(void *_part) +{ + struct spdk_bdev_part *part = _part; + + return spdk_get_io_channel(part); +} + +static void +spdk_bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) +{ + struct spdk_bdev_io *part_io = cb_arg; + int status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; + + spdk_bdev_io_complete(part_io, status); + spdk_bdev_free_io(bdev_io); +} + +void +spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io) +{ + 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; + 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; + 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; + 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; + 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; + 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; + rc = spdk_bdev_flush_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_RESET: + rc = spdk_bdev_reset(base_desc, base_ch, + spdk_bdev_part_complete_io, bdev_io); + break; + default: + SPDK_ERRLOG("split: unknown I/O type %d\n", bdev_io->type); + spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); + return; + } + + if (rc != 0) { + spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); + } +} +static int +spdk_bdev_part_channel_create_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; + + ch->part = part; + ch->base_ch = spdk_bdev_get_io_channel(part->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); + } else { + return 0; + } +} + +static void +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); + } + spdk_put_io_channel(ch->base_ch); +} + +int +spdk_bdev_part_base_construct(struct spdk_bdev_part_base *base, struct spdk_bdev *bdev, + spdk_bdev_remove_cb_t remove_cb, struct spdk_bdev_module_if *module, + struct spdk_bdev_fn_table *fn_table, struct bdev_part_tailq *tailq, + spdk_bdev_part_base_free_fn free_fn, + uint32_t channel_size, spdk_io_channel_create_cb ch_create_cb, + spdk_io_channel_destroy_cb ch_destroy_cb) +{ + int rc; + + fn_table->get_io_channel = spdk_bdev_part_get_io_channel; + fn_table->io_type_supported = spdk_bdev_part_io_type_supported; + + base->bdev = bdev; + base->desc = NULL; + base->ref = 0; + base->module = module; + base->fn_table = fn_table; + base->tailq = tailq; + base->claimed = false; + base->channel_size = channel_size; + base->ch_create_cb = ch_create_cb; + base->ch_destroy_cb = ch_destroy_cb; + base->base_free_fn = free_fn; + + rc = spdk_bdev_open(bdev, false, remove_cb, bdev, &base->desc); + if (rc) { + spdk_bdev_part_base_free(base); + SPDK_ERRLOG("could not open bdev %s\n", spdk_bdev_get_name(bdev)); + return -1; + } + + return 0; +} + +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) +{ + part->bdev.name = name; + part->bdev.blocklen = base->bdev->blocklen; + part->bdev.blockcnt = num_blocks; + part->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; + + __sync_fetch_and_add(&base->ref, 1); + part->base = base; + + if (!base->claimed) { + int rc; + + 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); + return -1; + } + base->claimed = true; + } + + 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); + TAILQ_INSERT_TAIL(base->tailq, part, tailq); + + return 0; +} diff --git a/test/unit/lib/bdev/Makefile b/test/unit/lib/bdev/Makefile index a5a75ee727..e77b5f04d4 100644 --- a/test/unit/lib/bdev/Makefile +++ b/test/unit/lib/bdev/Makefile @@ -34,7 +34,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk -DIRS-y = bdev.c scsi_nvme.c gpt vbdev_lvol.c mt +DIRS-y = bdev.c part.c scsi_nvme.c gpt vbdev_lvol.c mt DIRS-$(CONFIG_NVML) += pmem diff --git a/test/unit/lib/bdev/bdev.c/bdev_ut.c b/test/unit/lib/bdev/bdev.c/bdev_ut.c index 35f01cd02f..c21b235268 100644 --- a/test/unit/lib/bdev/bdev.c/bdev_ut.c +++ b/test/unit/lib/bdev/bdev.c/bdev_ut.c @@ -342,60 +342,6 @@ io_valid_test(void) CU_ASSERT(spdk_bdev_io_valid_blocks(&bdev, 18446744073709551615ULL, 1) == false); } -static int -__destruct(void *ctx) -{ - return 0; -} - -static struct spdk_bdev_fn_table base_fn_table = { - .destruct = __destruct, -}; -static struct spdk_bdev_fn_table part_fn_table = { - .destruct = __destruct, -}; - -static void -__base_free(struct spdk_bdev_part_base *base) -{ - free(base); -} - -static void -part_test(void) -{ - struct spdk_bdev_part_base *base; - struct spdk_bdev_part part1, part2; - struct spdk_bdev bdev_base = {}; - SPDK_BDEV_PART_TAILQ tailq = TAILQ_HEAD_INITIALIZER(tailq); - int rc; - - base = calloc(1, sizeof(*base)); - SPDK_CU_ASSERT_FATAL(base != NULL); - - bdev_base.name = "base"; - bdev_base.fn_table = &base_fn_table; - bdev_base.module = SPDK_GET_BDEV_MODULE(bdev_ut); - rc = spdk_bdev_register(&bdev_base); - CU_ASSERT(rc == 0); - spdk_bdev_part_base_construct(base, &bdev_base, NULL, SPDK_GET_BDEV_MODULE(vbdev_ut), - &part_fn_table, &tailq, __base_free, 0, NULL, NULL); - - spdk_bdev_part_construct(&part1, base, "test1", 0, 100, "test"); - spdk_bdev_part_construct(&part2, base, "test2", 100, 100, "test"); - - spdk_bdev_part_base_hotremove(&bdev_base, &tailq); - - /* - * The base device was removed - ensure that the partition vbdevs were - * removed from the base's vbdev list. - */ - CU_ASSERT(TAILQ_EMPTY(&bdev_base.vbdevs)); - - spdk_bdev_part_base_free(base); - spdk_bdev_unregister(&bdev_base, NULL, NULL); -} - static void alias_add_del_test(void) { @@ -484,7 +430,6 @@ main(int argc, char **argv) CU_add_test(suite, "num_blocks_test", num_blocks_test) == NULL || CU_add_test(suite, "io_valid", io_valid_test) == NULL || CU_add_test(suite, "open_write", open_write_test) == NULL || - CU_add_test(suite, "part", part_test) == NULL || CU_add_test(suite, "alias_add_del", alias_add_del_test) == NULL ) { CU_cleanup_registry(); diff --git a/test/unit/lib/bdev/part.c/.gitignore b/test/unit/lib/bdev/part.c/.gitignore new file mode 100644 index 0000000000..c8302779be --- /dev/null +++ b/test/unit/lib/bdev/part.c/.gitignore @@ -0,0 +1 @@ +part_ut diff --git a/test/unit/lib/bdev/part.c/Makefile b/test/unit/lib/bdev/part.c/Makefile new file mode 100644 index 0000000000..9073c5cde6 --- /dev/null +++ b/test/unit/lib/bdev/part.c/Makefile @@ -0,0 +1,40 @@ +# +# BSD LICENSE +# +# Copyright (c) Intel Corporation. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../../../..) +include $(SPDK_ROOT_DIR)/mk/spdk.common.mk +include $(SPDK_ROOT_DIR)/mk/spdk.app.mk + +TEST_FILE = part_ut.c + +include $(SPDK_ROOT_DIR)/mk/spdk.unittest.mk diff --git a/test/unit/lib/bdev/part.c/part_ut.c b/test/unit/lib/bdev/part.c/part_ut.c new file mode 100644 index 0000000000..ffa8aa7185 --- /dev/null +++ b/test/unit/lib/bdev/part.c/part_ut.c @@ -0,0 +1,140 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "spdk_cunit.h" + +#include "lib/test_env.c" + +#include "bdev/bdev.c" +#include "bdev/part.c" + +void +spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, + int *sc, int *sk, int *asc, int *ascq) +{ +} + +SPDK_DECLARE_BDEV_MODULE(vbdev_ut); + +static void +vbdev_ut_examine(struct spdk_bdev *bdev) +{ + spdk_bdev_module_examine_done(SPDK_GET_BDEV_MODULE(vbdev_ut)); +} + +SPDK_BDEV_MODULE_REGISTER(bdev_ut, NULL, NULL, NULL, NULL, NULL) +SPDK_BDEV_MODULE_REGISTER(vbdev_ut, NULL, NULL, NULL, NULL, vbdev_ut_examine) + +static int +__destruct(void *ctx) +{ + return 0; +} + +static struct spdk_bdev_fn_table base_fn_table = { + .destruct = __destruct, +}; +static struct spdk_bdev_fn_table part_fn_table = { + .destruct = __destruct, +}; + +static void +__base_free(struct spdk_bdev_part_base *base) +{ + free(base); +} + +static void +part_test(void) +{ + struct spdk_bdev_part_base *base; + struct spdk_bdev_part part1, part2; + struct spdk_bdev bdev_base = {}; + SPDK_BDEV_PART_TAILQ tailq = TAILQ_HEAD_INITIALIZER(tailq); + int rc; + + base = calloc(1, sizeof(*base)); + SPDK_CU_ASSERT_FATAL(base != NULL); + + bdev_base.name = "base"; + bdev_base.fn_table = &base_fn_table; + bdev_base.module = SPDK_GET_BDEV_MODULE(bdev_ut); + rc = spdk_bdev_register(&bdev_base); + CU_ASSERT(rc == 0); + spdk_bdev_part_base_construct(base, &bdev_base, NULL, SPDK_GET_BDEV_MODULE(vbdev_ut), + &part_fn_table, &tailq, __base_free, 0, NULL, NULL); + + spdk_bdev_part_construct(&part1, base, "test1", 0, 100, "test"); + spdk_bdev_part_construct(&part2, base, "test2", 100, 100, "test"); + + spdk_bdev_part_base_hotremove(&bdev_base, &tailq); + + /* + * The base device was removed - ensure that the partition vbdevs were + * removed from the base's vbdev list. + */ + CU_ASSERT(TAILQ_EMPTY(&bdev_base.vbdevs)); + + spdk_bdev_part_base_free(base); + spdk_bdev_unregister(&bdev_base, NULL, NULL); +} + +int +main(int argc, char **argv) +{ + CU_pSuite suite = NULL; + unsigned int num_failures; + + if (CU_initialize_registry() != CUE_SUCCESS) { + return CU_get_error(); + } + + suite = CU_add_suite("bdev_part", NULL, NULL); + if (suite == NULL) { + CU_cleanup_registry(); + return CU_get_error(); + } + + if ( + CU_add_test(suite, "part", part_test) == NULL + ) { + CU_cleanup_registry(); + return CU_get_error(); + } + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + num_failures = CU_get_number_of_failures(); + CU_cleanup_registry(); + return num_failures; +} diff --git a/unittest.sh b/unittest.sh index 8721a37b5a..6097db8c20 100755 --- a/unittest.sh +++ b/unittest.sh @@ -44,6 +44,7 @@ fi $valgrind test/unit/include/spdk/histogram_data.h/histogram_ut $valgrind test/unit/lib/bdev/bdev.c/bdev_ut +$valgrind test/unit/lib/bdev/part.c/part_ut $valgrind test/unit/lib/bdev/scsi_nvme.c/scsi_nvme_ut $valgrind test/unit/lib/bdev/gpt/gpt.c/gpt_ut $valgrind test/unit/lib/bdev/vbdev_lvol.c/vbdev_lvol_ut