per Intel policy to include file commit date using git cmd below. The policy does not apply to non-Intel (C) notices. git log --follow -C90% --format=%ad --date default <file> | tail -1 and then pull just the 4 digit year from the result. Intel copyrights were not added to files where Intel either had no contribution ot the contribution lacked substance (ie license header updates, formatting changes, etc). Contribution date used "--follow -C95%" to get the most accurate date. Note that several files in this patch didn't end the license/(c) block with a blank comment line so these were added as the vast majority of files do have this last blank line. Simply there for consistency. Signed-off-by: paul luse <paul.e.luse@intel.com> Change-Id: Id5b7ce4f658fe87132f14139ead58d6e285c04d4 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15192 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Community-CI: Mellanox Build Bot
565 lines
16 KiB
C
565 lines
16 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright (C) 2022 Intel Corporation.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include "spdk/stdinc.h"
|
|
#include "spdk_cunit.h"
|
|
#include "spdk/env.h"
|
|
#include "thread/thread_internal.h"
|
|
#include "spdk_internal/mock.h"
|
|
|
|
#include "bdev/raid/bdev_raid.h"
|
|
#include "bdev/raid/concat.c"
|
|
|
|
#define BLOCK_LEN (4096)
|
|
|
|
enum CONCAT_IO_TYPE {
|
|
CONCAT_NONE = 0,
|
|
CONCAT_WRITEV,
|
|
CONCAT_READV,
|
|
CONCAT_FLUSH,
|
|
CONCAT_UNMAP,
|
|
};
|
|
|
|
struct spdk_bdev_desc {
|
|
struct spdk_bdev *bdev;
|
|
};
|
|
|
|
#define MAX_RECORDS (10)
|
|
/*
|
|
* Store the information of io requests sent to the underlying bdevs.
|
|
* For a single null payload request to the concat bdev,
|
|
* we may send multiple requests to the underling bdevs,
|
|
* so we store the io request information to arrays.
|
|
*/
|
|
struct req_records {
|
|
uint64_t offset_blocks[MAX_RECORDS];
|
|
uint64_t num_blocks[MAX_RECORDS];
|
|
enum CONCAT_IO_TYPE io_type[MAX_RECORDS];
|
|
int count;
|
|
void *md;
|
|
} g_req_records;
|
|
|
|
/*
|
|
* g_succeed is true means the spdk_bdev_readv/writev/unmap/flush_blocks
|
|
* functions will return 0.
|
|
* g_succeed is false means the spdk_bdev_readv/writev/unmap/flush_blocks
|
|
* functions will return -ENOMEM.
|
|
* We always set it to false before an IO request, then the raid_bdev_queue_io_wait
|
|
* function will re-submit the request, and the raid_bdev_queue_io_wait function will
|
|
* set g_succeed to true, then the IO will succeed next time.
|
|
*/
|
|
bool g_succeed;
|
|
|
|
DEFINE_STUB_V(raid_bdev_module_list_add, (struct raid_bdev_module *raid_module));
|
|
DEFINE_STUB_V(raid_bdev_io_complete, (struct raid_bdev_io *raid_io,
|
|
enum spdk_bdev_io_status status));
|
|
DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io));
|
|
DEFINE_STUB(raid_bdev_io_complete_part, bool,
|
|
(struct raid_bdev_io *raid_io, uint64_t completed,
|
|
enum spdk_bdev_io_status status),
|
|
true);
|
|
|
|
int
|
|
spdk_bdev_readv_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks,
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg, struct spdk_bdev_ext_io_opts *opts)
|
|
{
|
|
if (g_succeed) {
|
|
int i = g_req_records.count;
|
|
|
|
g_req_records.offset_blocks[i] = offset_blocks;
|
|
g_req_records.num_blocks[i] = num_blocks;
|
|
g_req_records.io_type[i] = CONCAT_READV;
|
|
g_req_records.count++;
|
|
cb(NULL, true, cb_arg);
|
|
g_req_records.md = opts->metadata;
|
|
return 0;
|
|
} else {
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
int
|
|
spdk_bdev_writev_blocks_ext(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks,
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg, struct spdk_bdev_ext_io_opts *opts)
|
|
{
|
|
if (g_succeed) {
|
|
int i = g_req_records.count;
|
|
|
|
g_req_records.offset_blocks[i] = offset_blocks;
|
|
g_req_records.num_blocks[i] = num_blocks;
|
|
g_req_records.io_type[i] = CONCAT_WRITEV;
|
|
g_req_records.count++;
|
|
cb(NULL, true, cb_arg);
|
|
g_req_records.md = opts->metadata;
|
|
return 0;
|
|
} else {
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
int
|
|
spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
uint64_t offset_blocks, uint64_t num_blocks,
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
|
{
|
|
if (g_succeed) {
|
|
int i = g_req_records.count;
|
|
|
|
g_req_records.offset_blocks[i] = offset_blocks;
|
|
g_req_records.num_blocks[i] = num_blocks;
|
|
g_req_records.io_type[i] = CONCAT_UNMAP;
|
|
g_req_records.count++;
|
|
cb(NULL, true, cb_arg);
|
|
return 0;
|
|
} else {
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
int
|
|
spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
|
|
uint64_t offset_blocks, uint64_t num_blocks,
|
|
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
|
{
|
|
if (g_succeed) {
|
|
int i = g_req_records.count;
|
|
|
|
g_req_records.offset_blocks[i] = offset_blocks;
|
|
g_req_records.num_blocks[i] = num_blocks;
|
|
g_req_records.io_type[i] = CONCAT_FLUSH;
|
|
g_req_records.count++;
|
|
cb(NULL, true, cb_arg);
|
|
return 0;
|
|
} else {
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
void
|
|
raid_bdev_queue_io_wait(struct raid_bdev_io *raid_io, struct spdk_bdev *bdev,
|
|
struct spdk_io_channel *ch, spdk_bdev_io_wait_cb cb_fn)
|
|
{
|
|
g_succeed = true;
|
|
cb_fn(raid_io);
|
|
}
|
|
|
|
static void
|
|
init_globals(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_RECORDS; i++) {
|
|
g_req_records.offset_blocks[i] = 0;
|
|
g_req_records.num_blocks[i] = 0;
|
|
g_req_records.io_type[i] = CONCAT_NONE;
|
|
}
|
|
g_req_records.count = 0;
|
|
g_succeed = false;
|
|
}
|
|
|
|
struct concat_params {
|
|
uint8_t num_base_bdevs;
|
|
uint64_t base_bdev_blockcnt;
|
|
uint32_t base_bdev_blocklen;
|
|
uint32_t strip_size;
|
|
};
|
|
|
|
static struct concat_params *g_params;
|
|
static size_t g_params_count;
|
|
|
|
#define ARRAY_FOR_EACH(a, e) \
|
|
for (e = a; e < a + SPDK_COUNTOF(a); e++)
|
|
|
|
#define CONCAT_PARAMS_FOR_EACH(p) \
|
|
for (p = g_params; p < g_params + g_params_count; p++)
|
|
|
|
static int
|
|
test_setup(void)
|
|
{
|
|
uint8_t num_base_bdevs_values[] = { 3, 4, 5 };
|
|
uint64_t base_bdev_blockcnt_values[] = { 1, 1024, 1024 * 1024 };
|
|
uint32_t base_bdev_blocklen_values[] = { 512, 4096 };
|
|
uint32_t strip_size_kb_values[] = { 1, 4, 128 };
|
|
uint8_t *num_base_bdevs;
|
|
uint64_t *base_bdev_blockcnt;
|
|
uint32_t *base_bdev_blocklen;
|
|
uint32_t *strip_size_kb;
|
|
struct concat_params *params;
|
|
|
|
g_params_count = SPDK_COUNTOF(num_base_bdevs_values) *
|
|
SPDK_COUNTOF(base_bdev_blockcnt_values) *
|
|
SPDK_COUNTOF(base_bdev_blocklen_values) *
|
|
SPDK_COUNTOF(strip_size_kb_values);
|
|
g_params = calloc(g_params_count, sizeof(*g_params));
|
|
if (!g_params) {
|
|
return -ENOMEM;
|
|
}
|
|
|
|
params = g_params;
|
|
|
|
ARRAY_FOR_EACH(num_base_bdevs_values, num_base_bdevs) {
|
|
ARRAY_FOR_EACH(base_bdev_blockcnt_values, base_bdev_blockcnt) {
|
|
ARRAY_FOR_EACH(base_bdev_blocklen_values, base_bdev_blocklen) {
|
|
ARRAY_FOR_EACH(strip_size_kb_values, strip_size_kb) {
|
|
params->num_base_bdevs = *num_base_bdevs;
|
|
params->base_bdev_blockcnt = *base_bdev_blockcnt;
|
|
params->base_bdev_blocklen = *base_bdev_blocklen;
|
|
params->strip_size = *strip_size_kb * 1024 / *base_bdev_blocklen;
|
|
if (params->strip_size == 0 ||
|
|
params->strip_size > *base_bdev_blockcnt) {
|
|
g_params_count--;
|
|
continue;
|
|
}
|
|
params++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_cleanup(void)
|
|
{
|
|
free(g_params);
|
|
return 0;
|
|
}
|
|
|
|
static struct raid_bdev *
|
|
create_raid_bdev(struct concat_params *params)
|
|
{
|
|
struct raid_bdev *raid_bdev;
|
|
struct raid_base_bdev_info *base_info;
|
|
|
|
raid_bdev = calloc(1, sizeof(*raid_bdev));
|
|
SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
|
|
|
|
raid_bdev->module = &g_concat_module;
|
|
raid_bdev->num_base_bdevs = params->num_base_bdevs;
|
|
raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs,
|
|
sizeof(struct raid_base_bdev_info));
|
|
SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL);
|
|
|
|
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
|
|
base_info->bdev = calloc(1, sizeof(*base_info->bdev));
|
|
SPDK_CU_ASSERT_FATAL(base_info->bdev != NULL);
|
|
base_info->desc = calloc(1, sizeof(*base_info->desc));
|
|
SPDK_CU_ASSERT_FATAL(base_info->desc != NULL);
|
|
|
|
base_info->bdev->blockcnt = params->base_bdev_blockcnt;
|
|
base_info->bdev->blocklen = params->base_bdev_blocklen;
|
|
}
|
|
|
|
raid_bdev->strip_size = params->strip_size;
|
|
raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size);
|
|
raid_bdev->bdev.blocklen = params->base_bdev_blocklen;
|
|
|
|
return raid_bdev;
|
|
}
|
|
|
|
static void
|
|
delete_raid_bdev(struct raid_bdev *raid_bdev)
|
|
{
|
|
struct raid_base_bdev_info *base_info;
|
|
|
|
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
|
|
free(base_info->bdev);
|
|
free(base_info->desc);
|
|
}
|
|
free(raid_bdev->base_bdev_info);
|
|
free(raid_bdev);
|
|
}
|
|
|
|
static struct raid_bdev *
|
|
create_concat(struct concat_params *params)
|
|
{
|
|
struct raid_bdev *raid_bdev = create_raid_bdev(params);
|
|
|
|
CU_ASSERT(concat_start(raid_bdev) == 0);
|
|
return raid_bdev;
|
|
}
|
|
|
|
static void
|
|
delete_concat(struct raid_bdev *raid_bdev)
|
|
{
|
|
concat_stop(raid_bdev);
|
|
delete_raid_bdev(raid_bdev);
|
|
}
|
|
|
|
static void
|
|
test_concat_start(void)
|
|
{
|
|
struct raid_bdev *raid_bdev;
|
|
struct concat_params *params;
|
|
struct concat_block_range *block_range;
|
|
uint64_t total_blockcnt;
|
|
int i;
|
|
|
|
CONCAT_PARAMS_FOR_EACH(params) {
|
|
raid_bdev = create_concat(params);
|
|
block_range = raid_bdev->module_private;
|
|
total_blockcnt = 0;
|
|
for (i = 0; i < params->num_base_bdevs; i++) {
|
|
CU_ASSERT(block_range[i].start == total_blockcnt);
|
|
CU_ASSERT(block_range[i].length == params->base_bdev_blockcnt);
|
|
total_blockcnt += params->base_bdev_blockcnt;
|
|
}
|
|
delete_concat(raid_bdev);
|
|
}
|
|
}
|
|
|
|
static void
|
|
bdev_io_cleanup(struct spdk_bdev_io *bdev_io)
|
|
{
|
|
if (bdev_io->u.bdev.iovs) {
|
|
if (bdev_io->u.bdev.iovs->iov_base) {
|
|
free(bdev_io->u.bdev.iovs->iov_base);
|
|
}
|
|
free(bdev_io->u.bdev.iovs);
|
|
}
|
|
|
|
if (bdev_io->u.bdev.ext_opts) {
|
|
if (bdev_io->u.bdev.ext_opts->metadata) {
|
|
bdev_io->u.bdev.ext_opts->metadata = NULL;
|
|
}
|
|
free(bdev_io->u.bdev.ext_opts);
|
|
}
|
|
free(bdev_io);
|
|
}
|
|
|
|
static void
|
|
bdev_io_initialize(struct spdk_bdev_io *bdev_io, struct spdk_io_channel *ch, struct spdk_bdev *bdev,
|
|
uint64_t lba, uint64_t blocks, int16_t iotype)
|
|
{
|
|
struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
|
|
|
|
bdev_io->bdev = bdev;
|
|
bdev_io->u.bdev.offset_blocks = lba;
|
|
bdev_io->u.bdev.num_blocks = blocks;
|
|
bdev_io->type = iotype;
|
|
|
|
if (bdev_io->type == SPDK_BDEV_IO_TYPE_UNMAP || bdev_io->type == SPDK_BDEV_IO_TYPE_FLUSH) {
|
|
return;
|
|
}
|
|
|
|
bdev_io->u.bdev.iovcnt = 1;
|
|
bdev_io->u.bdev.iovs = calloc(1, sizeof(struct iovec));
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs != NULL);
|
|
bdev_io->u.bdev.iovs->iov_base = calloc(1, bdev_io->u.bdev.num_blocks * 4096);
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.iovs->iov_base != NULL);
|
|
bdev_io->u.bdev.iovs->iov_len = bdev_io->u.bdev.num_blocks * BLOCK_LEN;
|
|
bdev_io->internal.ch = channel;
|
|
bdev_io->u.bdev.ext_opts = calloc(1, sizeof(struct spdk_bdev_ext_io_opts));
|
|
SPDK_CU_ASSERT_FATAL(bdev_io->u.bdev.ext_opts != NULL);
|
|
bdev_io->u.bdev.ext_opts->metadata = (void *)0xAEDFEBAC;
|
|
}
|
|
|
|
static void
|
|
submit_and_verify_rw(enum CONCAT_IO_TYPE io_type, struct concat_params *params)
|
|
{
|
|
struct raid_bdev *raid_bdev;
|
|
struct spdk_bdev_io *bdev_io;
|
|
struct spdk_io_channel *ch;
|
|
struct raid_bdev_io *raid_io;
|
|
struct raid_bdev_io_channel *raid_ch;
|
|
uint64_t lba, blocks;
|
|
int i;
|
|
|
|
lba = 0;
|
|
blocks = 1;
|
|
for (i = 0; i < params->num_base_bdevs; i++) {
|
|
init_globals();
|
|
raid_bdev = create_concat(params);
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
|
raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
|
|
raid_ch = calloc(1, sizeof(struct raid_bdev_io_channel));
|
|
SPDK_CU_ASSERT_FATAL(raid_ch != NULL);
|
|
raid_ch->base_channel = calloc(params->num_base_bdevs,
|
|
sizeof(struct spdk_io_channel));
|
|
SPDK_CU_ASSERT_FATAL(raid_ch->base_channel != NULL);
|
|
raid_io->raid_ch = raid_ch;
|
|
raid_io->raid_bdev = raid_bdev;
|
|
ch = calloc(1, sizeof(struct spdk_io_channel));
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
switch (io_type) {
|
|
case CONCAT_WRITEV:
|
|
bdev_io_initialize(bdev_io, ch, &raid_bdev->bdev, lba, blocks, SPDK_BDEV_IO_TYPE_WRITE);
|
|
concat_submit_rw_request(raid_io);
|
|
break;
|
|
case CONCAT_READV:
|
|
bdev_io_initialize(bdev_io, ch, &raid_bdev->bdev, lba, blocks, SPDK_BDEV_IO_TYPE_READ);
|
|
concat_submit_rw_request(raid_io);
|
|
break;
|
|
case CONCAT_UNMAP:
|
|
bdev_io_initialize(bdev_io, ch, &raid_bdev->bdev, lba, blocks, SPDK_BDEV_IO_TYPE_UNMAP);
|
|
concat_submit_null_payload_request(raid_io);
|
|
break;
|
|
case CONCAT_FLUSH:
|
|
bdev_io_initialize(bdev_io, ch, &raid_bdev->bdev, lba, blocks, SPDK_BDEV_IO_TYPE_FLUSH);
|
|
concat_submit_null_payload_request(raid_io);
|
|
break;
|
|
default:
|
|
CU_ASSERT(false);
|
|
}
|
|
|
|
/*
|
|
* We submit request to the first lba of each underlying device,
|
|
* so the offset of the underling device should always be 0.
|
|
*/
|
|
CU_ASSERT(g_req_records.offset_blocks[0] == 0);
|
|
CU_ASSERT(g_req_records.num_blocks[0] == blocks);
|
|
CU_ASSERT(g_req_records.io_type[0] == io_type);
|
|
CU_ASSERT(g_req_records.count == 1);
|
|
CU_ASSERT(g_req_records.md == (void *)0xAEDFEBAC);
|
|
bdev_io_cleanup(bdev_io);
|
|
free(ch);
|
|
free(raid_ch->base_channel);
|
|
free(raid_ch);
|
|
delete_concat(raid_bdev);
|
|
lba += params->base_bdev_blockcnt;
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_concat_rw(void)
|
|
{
|
|
struct concat_params *params;
|
|
enum CONCAT_IO_TYPE io_type_list[] = {CONCAT_WRITEV, CONCAT_READV};
|
|
enum CONCAT_IO_TYPE io_type;
|
|
int i;
|
|
|
|
CONCAT_PARAMS_FOR_EACH(params) {
|
|
for (i = 0; i < 2; i ++) {
|
|
io_type = io_type_list[i];
|
|
submit_and_verify_rw(io_type, params);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
submit_and_verify_null_payload(enum CONCAT_IO_TYPE io_type, struct concat_params *params)
|
|
{
|
|
struct raid_bdev *raid_bdev;
|
|
struct spdk_bdev_io *bdev_io;
|
|
struct spdk_io_channel *ch;
|
|
struct raid_bdev_io *raid_io;
|
|
struct raid_bdev_io_channel *raid_ch;
|
|
uint64_t lba, blocks;
|
|
|
|
/*
|
|
* In this unittest, all base bdevs have the same blockcnt.
|
|
* If the base_bdev_blockcnt > 1, the request will start from
|
|
* the second bdev, and across two bdevs.
|
|
* If the base_bdev_blockcnt == 1, the request will start from
|
|
* the third bdev. In this case, if there are only 3 bdevs,
|
|
* we can not set blocks to base_bdev_blockcnt + 1 because the request
|
|
* will be beyond the end of the last bdev, so we set the blocks to 1
|
|
*/
|
|
lba = params->base_bdev_blockcnt + 1;
|
|
if (params->base_bdev_blockcnt == 1 && params->num_base_bdevs == 3) {
|
|
blocks = 1;
|
|
} else {
|
|
blocks = params->base_bdev_blockcnt + 1;
|
|
}
|
|
init_globals();
|
|
raid_bdev = create_concat(params);
|
|
bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct raid_bdev_io));
|
|
SPDK_CU_ASSERT_FATAL(bdev_io != NULL);
|
|
raid_io = (struct raid_bdev_io *)bdev_io->driver_ctx;
|
|
raid_ch = calloc(1, sizeof(struct raid_bdev_io_channel));
|
|
SPDK_CU_ASSERT_FATAL(raid_ch != NULL);
|
|
raid_ch->base_channel = calloc(params->num_base_bdevs,
|
|
sizeof(struct spdk_io_channel));
|
|
SPDK_CU_ASSERT_FATAL(raid_ch->base_channel != NULL);
|
|
raid_io->raid_ch = raid_ch;
|
|
raid_io->raid_bdev = raid_bdev;
|
|
ch = calloc(1, sizeof(struct spdk_io_channel));
|
|
SPDK_CU_ASSERT_FATAL(ch != NULL);
|
|
|
|
switch (io_type) {
|
|
case CONCAT_UNMAP:
|
|
bdev_io_initialize(bdev_io, ch, &raid_bdev->bdev, lba, blocks, SPDK_BDEV_IO_TYPE_UNMAP);
|
|
concat_submit_null_payload_request(raid_io);
|
|
break;
|
|
case CONCAT_FLUSH:
|
|
bdev_io_initialize(bdev_io, ch, &raid_bdev->bdev, lba, blocks, SPDK_BDEV_IO_TYPE_FLUSH);
|
|
concat_submit_null_payload_request(raid_io);
|
|
break;
|
|
default:
|
|
CU_ASSERT(false);
|
|
}
|
|
|
|
if (params->base_bdev_blockcnt == 1) {
|
|
if (params->num_base_bdevs == 3) {
|
|
CU_ASSERT(g_req_records.count == 1);
|
|
CU_ASSERT(g_req_records.offset_blocks[0] == 0);
|
|
CU_ASSERT(g_req_records.num_blocks[0] == 1);
|
|
} else {
|
|
CU_ASSERT(g_req_records.count == 2);
|
|
CU_ASSERT(g_req_records.offset_blocks[0] == 0);
|
|
CU_ASSERT(g_req_records.num_blocks[0] == 1);
|
|
CU_ASSERT(g_req_records.io_type[0] == io_type);
|
|
CU_ASSERT(g_req_records.offset_blocks[1] == 0);
|
|
CU_ASSERT(g_req_records.num_blocks[1] == 1);
|
|
CU_ASSERT(g_req_records.io_type[1] == io_type);
|
|
}
|
|
} else {
|
|
CU_ASSERT(g_req_records.count == 2);
|
|
CU_ASSERT(g_req_records.offset_blocks[0] == 1);
|
|
CU_ASSERT(g_req_records.num_blocks[0] == params->base_bdev_blockcnt - 1);
|
|
CU_ASSERT(g_req_records.io_type[0] == io_type);
|
|
CU_ASSERT(g_req_records.offset_blocks[1] == 0);
|
|
CU_ASSERT(g_req_records.num_blocks[1] == 2);
|
|
CU_ASSERT(g_req_records.io_type[1] == io_type);
|
|
}
|
|
bdev_io_cleanup(bdev_io);
|
|
free(ch);
|
|
free(raid_ch->base_channel);
|
|
free(raid_ch);
|
|
delete_concat(raid_bdev);
|
|
}
|
|
|
|
static void
|
|
test_concat_null_payload(void)
|
|
{
|
|
struct concat_params *params;
|
|
enum CONCAT_IO_TYPE io_type_list[] = {CONCAT_FLUSH, CONCAT_UNMAP};
|
|
enum CONCAT_IO_TYPE io_type;
|
|
int i;
|
|
|
|
CONCAT_PARAMS_FOR_EACH(params) {
|
|
for (i = 0; i < 2; i ++) {
|
|
io_type = io_type_list[i];
|
|
submit_and_verify_null_payload(io_type, params);
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
CU_pSuite suite = NULL;
|
|
unsigned int num_failures;
|
|
|
|
CU_set_error_action(CUEA_ABORT);
|
|
CU_initialize_registry();
|
|
|
|
suite = CU_add_suite("concat", test_setup, test_cleanup);
|
|
CU_ADD_TEST(suite, test_concat_start);
|
|
CU_ADD_TEST(suite, test_concat_rw);
|
|
CU_ADD_TEST(suite, test_concat_null_payload);
|
|
|
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
|
CU_basic_run_tests();
|
|
num_failures = CU_get_number_of_failures();
|
|
CU_cleanup_registry();
|
|
return num_failures;
|
|
}
|