module/raid: data offset and data size implementation

When raid bdev is created with superblock parameter then all data on
this bdev should be shifted by some offset. Such space at the beginning
of bdev will be used to store on-disk raid metadata.

Signed-off-by: Krzysztof Smolinski <krzysztof.smolinski@intel.com>
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: I2545a2b00a651ef5332ca1757da0110a63914a43
This commit is contained in:
Krzysztof Smolinski 2022-11-17 11:40:49 +01:00 committed by David Ko
parent 19c79b0d01
commit 8c591e2d4f
9 changed files with 224 additions and 58 deletions

View File

@ -595,6 +595,7 @@ raid_bdev_write_info_json(struct raid_bdev *raid_bdev, struct spdk_json_write_ct
spdk_json_write_named_uint32(w, "strip_size_kb", raid_bdev->strip_size_kb);
spdk_json_write_named_string(w, "state", raid_bdev_state_to_str(raid_bdev->state));
spdk_json_write_named_string(w, "raid_level", raid_bdev_level_to_str(raid_bdev->level));
spdk_json_write_named_bool(w, "superblock", raid_bdev->superblock_enabled);
spdk_json_write_named_uint32(w, "num_base_bdevs", raid_bdev->num_base_bdevs);
spdk_json_write_named_uint32(w, "num_base_bdevs_discovered", raid_bdev->num_base_bdevs_discovered);
spdk_json_write_name(w, "base_bdevs_list");
@ -659,6 +660,7 @@ raid_bdev_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *
spdk_json_write_named_string(w, "name", bdev->name);
spdk_json_write_named_uint32(w, "strip_size_kb", raid_bdev->strip_size_kb);
spdk_json_write_named_string(w, "raid_level", raid_bdev_level_to_str(raid_bdev->level));
spdk_json_write_named_bool(w, "superblock", raid_bdev->superblock_enabled);
spdk_json_write_named_array_begin(w, "base_bdevs");
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
@ -919,7 +921,8 @@ raid_bdev_init(void)
*/
int
raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs,
enum raid_level level, struct raid_bdev **raid_bdev_out, const struct spdk_uuid *uuid)
enum raid_level level, struct raid_bdev **raid_bdev_out,
const struct spdk_uuid *uuid, bool superblock)
{
struct raid_bdev *raid_bdev;
struct spdk_bdev *raid_bdev_gen;
@ -1007,6 +1010,7 @@ raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs,
raid_bdev->state = RAID_BDEV_STATE_CONFIGURING;
raid_bdev->level = level;
raid_bdev->min_base_bdevs_operational = min_operational;
raid_bdev->superblock_enabled = superblock;
raid_bdev_gen = &raid_bdev->bdev;
@ -1417,9 +1421,29 @@ raid_bdev_configure_base_bdev(struct raid_bdev *raid_bdev, struct raid_base_bdev
base_info->bdev = bdev;
base_info->desc = desc;
base_info->blockcnt = bdev->blockcnt;
base_info->data_offset = 0;
base_info->data_size = base_info->bdev->blockcnt;
raid_bdev->num_base_bdevs_discovered++;
assert(raid_bdev->num_base_bdevs_discovered <= raid_bdev->num_base_bdevs);
if (raid_bdev->superblock_enabled) {
assert((RAID_BDEV_MIN_DATA_OFFSET_SIZE % bdev->blocklen) == 0);
base_info->data_offset = RAID_BDEV_MIN_DATA_OFFSET_SIZE / bdev->blocklen;
if (bdev->optimal_io_boundary) {
base_info->data_offset = spdk_divide_round_up(base_info->data_offset,
bdev->optimal_io_boundary) * bdev->optimal_io_boundary;
}
base_info->data_size = base_info->bdev->blockcnt - base_info->data_offset;
if (base_info->data_offset > bdev->blockcnt) {
SPDK_ERRLOG("Data offset %lu exceeds base bdev capacity %lu on bdev '%s'\n",
base_info->data_offset, bdev->blockcnt, base_info->name);
return -EINVAL;
}
}
if (raid_bdev->num_base_bdevs_discovered == raid_bdev->num_base_bdevs) {
rc = raid_bdev_configure(raid_bdev);
if (rc != 0) {

View File

@ -9,6 +9,8 @@
#include "spdk/bdev_module.h"
#include "spdk/uuid.h"
#define RAID_BDEV_MIN_DATA_OFFSET_SIZE (1024*1024) /* 1 MiB */
enum raid_level {
INVALID_RAID_LEVEL = -1,
RAID0 = 0,
@ -56,6 +58,12 @@ struct raid_base_bdev_info {
/* pointer to base bdev descriptor opened by raid bdev */
struct spdk_bdev_desc *desc;
/* data offset for raid bdev [blocks] */
uint64_t data_offset;
/* data size of for raid bdev [blocks] */
uint64_t data_size;
/*
* When underlying base device calls the hot plug function on drive removal,
* this flag will be set and later after doing some processing, base device
@ -135,6 +143,9 @@ struct raid_bdev {
/* Set to true if destroy of this raid bdev is started. */
bool destroy_started;
/* Set to true if superblock metadata is enabled on this raid bdev */
bool superblock_enabled;
/* Module for RAID-level specific operations */
struct raid_bdev_module *module;
@ -168,7 +179,8 @@ extern struct raid_all_tailq g_raid_bdev_list;
typedef void (*raid_bdev_destruct_cb)(void *cb_ctx, int rc);
int raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs,
enum raid_level level, struct raid_bdev **raid_bdev_out, const struct spdk_uuid *uuid);
enum raid_level level, struct raid_bdev **raid_bdev_out,
const struct spdk_uuid *uuid, bool superblock);
void raid_bdev_delete(struct raid_bdev *raid_bdev, raid_bdev_destruct_cb cb_fn, void *cb_ctx);
int raid_bdev_add_base_device(struct raid_bdev *raid_bdev, const char *name, uint8_t slot);
struct raid_bdev *raid_bdev_find_by_name(const char *name);
@ -263,4 +275,62 @@ void raid_bdev_queue_io_wait(struct raid_bdev_io *raid_io, struct spdk_bdev *bde
void raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status);
void raid_bdev_module_stop_done(struct raid_bdev *raid_bdev);
/**
* Raid bdev I/O read/write wrapper for spdk_bdev_readv_blocks_ext function.
*/
static inline int
raid_bdev_readv_blocks_ext(struct raid_base_bdev_info *base_info, 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)
{
struct spdk_bdev_desc *desc = base_info->desc;
uint64_t offset = base_info->data_offset + offset_blocks;
return spdk_bdev_readv_blocks_ext(desc, ch, iov, iovcnt, offset, num_blocks, cb, cb_arg, opts);
}
/**
* Raid bdev I/O read/write wrapper for spdk_bdev_writev_blocks_ext function.
*/
static inline int
raid_bdev_writev_blocks_ext(struct raid_base_bdev_info *base_info, 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)
{
struct spdk_bdev_desc *desc = base_info->desc;
uint64_t offset = base_info->data_offset + offset_blocks;
return spdk_bdev_writev_blocks_ext(desc, ch, iov, iovcnt, offset, num_blocks, cb, cb_arg, opts);
}
/**
* Raid bdev I/O read/write wrapper for spdk_bdev_unmap_blocks function.
*/
static inline int
raid_bdev_unmap_blocks(struct raid_base_bdev_info *base_info, struct spdk_io_channel *ch,
uint64_t offset_blocks, uint64_t num_blocks,
spdk_bdev_io_completion_cb cb, void *cb_arg)
{
struct spdk_bdev_desc *desc = base_info->desc;
uint64_t offset = base_info->data_offset + offset_blocks;
return spdk_bdev_unmap_blocks(desc, ch, offset, num_blocks, cb, cb_arg);
}
/**
* Raid bdev I/O read/write wrapper for spdk_bdev_flush_blocks function.
*/
static inline int
raid_bdev_flush_blocks(struct raid_base_bdev_info *base_info, struct spdk_io_channel *ch,
uint64_t offset_blocks, uint64_t num_blocks,
spdk_bdev_io_completion_cb cb, void *cb_arg)
{
struct spdk_bdev_desc *desc = base_info->desc;
uint64_t offset = base_info->data_offset + offset_blocks;
return spdk_bdev_flush_blocks(desc, ch, offset, num_blocks, cb, cb_arg);
}
#endif /* SPDK_BDEV_RAID_INTERNAL_H */

View File

@ -241,7 +241,7 @@ rpc_bdev_raid_create(struct spdk_jsonrpc_request *request,
}
rc = raid_bdev_create(req.name, req.strip_size_kb, req.base_bdevs.num_base_bdevs,
req.level, &raid_bdev, uuid);
req.level, &raid_bdev, uuid, req.superblock);
if (rc != 0) {
spdk_jsonrpc_send_error_response_fmt(request, rc,
"Failed to create RAID bdev %s: %s",

View File

@ -110,12 +110,12 @@ concat_submit_rw_request(struct raid_bdev_io *raid_io)
io_opts.metadata = bdev_io->u.bdev.md_buf;
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ) {
ret = spdk_bdev_readv_blocks_ext(base_info->desc, base_ch,
ret = raid_bdev_readv_blocks_ext(base_info, base_ch,
bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
pd_lba, pd_blocks, concat_bdev_io_completion,
raid_io, &io_opts);
} else if (bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) {
ret = spdk_bdev_writev_blocks_ext(base_info->desc, base_ch,
ret = raid_bdev_writev_blocks_ext(base_info, base_ch,
bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
pd_lba, pd_blocks, concat_bdev_io_completion,
raid_io, &io_opts);
@ -242,12 +242,12 @@ concat_submit_null_payload_request(struct raid_bdev_io *raid_io)
base_ch = raid_io->raid_ch->base_channel[i];
switch (bdev_io->type) {
case SPDK_BDEV_IO_TYPE_UNMAP:
ret = spdk_bdev_unmap_blocks(base_info->desc, base_ch,
ret = raid_bdev_unmap_blocks(base_info, base_ch,
pd_lba, pd_blocks,
concat_base_io_complete, raid_io);
break;
case SPDK_BDEV_IO_TYPE_FLUSH:
ret = spdk_bdev_flush_blocks(base_info->desc, base_ch,
ret = raid_bdev_flush_blocks(base_info, base_ch,
pd_lba, pd_blocks,
concat_base_io_complete, raid_io);
break;
@ -287,9 +287,11 @@ concat_start(struct raid_bdev *raid_bdev)
int idx = 0;
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
uint64_t strip_cnt = base_info->bdev->blockcnt >> raid_bdev->strip_size_shift;
uint64_t strip_cnt = base_info->data_size >> raid_bdev->strip_size_shift;
uint64_t pd_block_cnt = strip_cnt << raid_bdev->strip_size_shift;
base_info->data_size = pd_block_cnt;
block_range[idx].start = total_blockcnt;
block_range[idx].length = pd_block_cnt;
total_blockcnt += pd_block_cnt;

View File

@ -111,12 +111,12 @@ raid0_submit_rw_request(struct raid_bdev_io *raid_io)
io_opts.metadata = bdev_io->u.bdev.md_buf;
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ) {
ret = spdk_bdev_readv_blocks_ext(base_info->desc, base_ch,
ret = raid_bdev_readv_blocks_ext(base_info, base_ch,
bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
pd_lba, pd_blocks, raid0_bdev_io_completion,
raid_io, &io_opts);
} else if (bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) {
ret = spdk_bdev_writev_blocks_ext(base_info->desc, base_ch,
ret = raid_bdev_writev_blocks_ext(base_info, base_ch,
bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
pd_lba, pd_blocks, raid0_bdev_io_completion,
raid_io, &io_opts);
@ -303,13 +303,13 @@ raid0_submit_null_payload_request(struct raid_bdev_io *raid_io)
switch (bdev_io->type) {
case SPDK_BDEV_IO_TYPE_UNMAP:
ret = spdk_bdev_unmap_blocks(base_info->desc, base_ch,
ret = raid_bdev_unmap_blocks(base_info, base_ch,
offset_in_disk, nblocks_in_disk,
raid0_base_io_complete, raid_io);
break;
case SPDK_BDEV_IO_TYPE_FLUSH:
ret = spdk_bdev_flush_blocks(base_info->desc, base_ch,
ret = raid_bdev_flush_blocks(base_info, base_ch,
offset_in_disk, nblocks_in_disk,
raid0_base_io_complete, raid_io);
break;
@ -335,15 +335,22 @@ raid0_submit_null_payload_request(struct raid_bdev_io *raid_io)
}
}
static uint64_t
raid0_calculate_blockcnt(struct raid_bdev *raid_bdev)
static int
raid0_start(struct raid_bdev *raid_bdev)
{
uint64_t min_blockcnt = UINT64_MAX;
uint64_t base_bdev_data_size;
struct raid_base_bdev_info *base_info;
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
/* Calculate minimum block count from all base bdevs */
min_blockcnt = spdk_min(min_blockcnt, base_info->bdev->blockcnt);
min_blockcnt = spdk_min(min_blockcnt, base_info->data_size);
}
base_bdev_data_size = (min_blockcnt >> raid_bdev->strip_size_shift) << raid_bdev->strip_size_shift;
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
base_info->data_size = base_bdev_data_size;
}
/*
@ -354,14 +361,7 @@ raid0_calculate_blockcnt(struct raid_bdev *raid_bdev)
SPDK_DEBUGLOG(bdev_raid0, "min blockcount %" PRIu64 ", numbasedev %u, strip size shift %u\n",
min_blockcnt, raid_bdev->num_base_bdevs, raid_bdev->strip_size_shift);
return ((min_blockcnt >> raid_bdev->strip_size_shift) <<
raid_bdev->strip_size_shift) * raid_bdev->num_base_bdevs;
}
static int
raid0_start(struct raid_bdev *raid_bdev)
{
raid_bdev->bdev.blockcnt = raid0_calculate_blockcnt(raid_bdev);
raid_bdev->bdev.blockcnt = base_bdev_data_size * raid_bdev->num_base_bdevs;
if (raid_bdev->num_base_bdevs > 1) {
raid_bdev->bdev.optimal_io_boundary = raid_bdev->strip_size;
@ -380,8 +380,16 @@ raid0_resize(struct raid_bdev *raid_bdev)
{
uint64_t blockcnt;
int rc;
uint64_t min_blockcnt = UINT64_MAX;
struct raid_base_bdev_info *base_info;
uint64_t base_bdev_data_size;
blockcnt = raid0_calculate_blockcnt(raid_bdev);
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
min_blockcnt = spdk_min(min_blockcnt, base_info->bdev->blockcnt - base_info->data_offset);
}
base_bdev_data_size = (min_blockcnt >> raid_bdev->strip_size_shift) << raid_bdev->strip_size_shift;
blockcnt = base_bdev_data_size * raid_bdev->num_base_bdevs;
if (blockcnt == raid_bdev->bdev.blockcnt) {
return;
@ -395,6 +403,11 @@ raid0_resize(struct raid_bdev *raid_bdev)
rc = spdk_bdev_notify_blockcnt_change(&raid_bdev->bdev, blockcnt);
if (rc != 0) {
SPDK_ERRLOG("Failed to notify blockcount change\n");
return;
}
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
base_info->data_size = base_bdev_data_size;
}
}

View File

@ -63,7 +63,7 @@ raid1_submit_read_request(struct raid_bdev_io *raid_io)
raid_io->base_bdev_io_remaining = 1;
raid1_init_ext_io_opts(bdev_io, &io_opts);
ret = spdk_bdev_readv_blocks_ext(base_info->desc, base_ch,
ret = raid_bdev_readv_blocks_ext(base_info, base_ch,
bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
pd_lba, pd_blocks, raid1_bdev_io_completion,
raid_io, &io_opts);
@ -104,7 +104,7 @@ raid1_submit_write_request(struct raid_bdev_io *raid_io)
base_info = &raid_bdev->base_bdev_info[idx];
base_ch = raid_io->raid_ch->base_channel[idx];
ret = spdk_bdev_writev_blocks_ext(base_info->desc, base_ch,
ret = raid_bdev_writev_blocks_ext(base_info, base_ch,
bdev_io->u.bdev.iovs, bdev_io->u.bdev.iovcnt,
pd_lba, pd_blocks, raid1_bdev_io_completion,
raid_io, &io_opts);
@ -166,7 +166,11 @@ raid1_start(struct raid_bdev *raid_bdev)
r1info->raid_bdev = raid_bdev;
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
min_blockcnt = spdk_min(min_blockcnt, base_info->bdev->blockcnt);
min_blockcnt = spdk_min(min_blockcnt, base_info->data_size);
}
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
base_info->data_size = min_blockcnt;
}
raid_bdev->bdev.blockcnt = min_blockcnt;

View File

@ -387,7 +387,7 @@ raid5f_chunk_write(struct chunk *chunk)
raid5f_init_ext_io_opts(bdev_io, &chunk->ext_opts);
chunk->ext_opts.metadata = chunk->md_buf;
ret = spdk_bdev_writev_blocks_ext(base_info->desc, base_ch, chunk->iovs, chunk->iovcnt,
ret = raid_bdev_writev_blocks_ext(base_info, base_ch, chunk->iovs, chunk->iovcnt,
base_offset_blocks, raid_bdev->strip_size, raid5f_chunk_write_complete_bdev_io,
chunk, &chunk->ext_opts);
@ -577,7 +577,7 @@ raid5f_submit_read_request(struct raid_bdev_io *raid_io, uint64_t stripe_index,
int ret;
raid5f_init_ext_io_opts(bdev_io, &io_opts);
ret = spdk_bdev_readv_blocks_ext(base_info->desc, base_ch, bdev_io->u.bdev.iovs,
ret = raid_bdev_readv_blocks_ext(base_info, base_ch, bdev_io->u.bdev.iovs,
bdev_io->u.bdev.iovcnt,
base_offset_blocks, bdev_io->u.bdev.num_blocks, raid5f_chunk_read_complete, raid_io,
&io_opts);
@ -765,6 +765,7 @@ static int
raid5f_start(struct raid_bdev *raid_bdev)
{
uint64_t min_blockcnt = UINT64_MAX;
uint64_t base_bdev_data_size;
struct raid_base_bdev_info *base_info;
struct raid5f_info *r5f_info;
size_t alignment = 0;
@ -777,11 +778,17 @@ raid5f_start(struct raid_bdev *raid_bdev)
r5f_info->raid_bdev = raid_bdev;
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
min_blockcnt = spdk_min(min_blockcnt, base_info->bdev->blockcnt);
min_blockcnt = spdk_min(min_blockcnt, base_info->data_size);
alignment = spdk_max(alignment, spdk_bdev_get_buf_align(base_info->bdev));
}
r5f_info->total_stripes = min_blockcnt / raid_bdev->strip_size;
base_bdev_data_size = (min_blockcnt / raid_bdev->strip_size) * raid_bdev->strip_size;
RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
base_info->data_size = base_bdev_data_size;
}
r5f_info->total_stripes = base_bdev_data_size / raid_bdev->strip_size;
r5f_info->stripe_blocks = raid_bdev->strip_size * raid5f_stripe_data_chunks_num(raid_bdev);
r5f_info->buf_alignment = alignment;

View File

@ -445,6 +445,18 @@ spdk_json_write_named_string(struct spdk_json_write_ctx *w, const char *name, co
return 0;
}
int
spdk_json_write_named_bool(struct spdk_json_write_ctx *w, const char *name, bool val)
{
if (!g_test_multi_raids) {
struct rpc_bdev_raid_create *req = g_rpc_req;
if (strcmp(name, "superblock") == 0) {
CU_ASSERT(val == req->superblock);
}
}
return 0;
}
void
spdk_bdev_free_io(struct spdk_bdev_io *bdev_io)
{
@ -542,6 +554,7 @@ spdk_json_decode_object(const struct spdk_json_val *values,
SPDK_CU_ASSERT_FATAL(_out->name != NULL);
_out->strip_size_kb = req->strip_size_kb;
_out->level = req->level;
_out->superblock = req->superblock;
_out->base_bdevs.num_base_bdevs = req->base_bdevs.num_base_bdevs;
for (i = 0; i < req->base_bdevs.num_base_bdevs; i++) {
_out->base_bdevs.base_bdevs[i] = strdup(req->base_bdevs.base_bdevs[i]);
@ -867,9 +880,12 @@ verify_raid_bdev(struct rpc_bdev_raid_create *r, bool presence, uint32_t raid_st
bdev = spdk_bdev_get_by_name(base_info->bdev->name);
CU_ASSERT(bdev != NULL);
CU_ASSERT(base_info->remove_scheduled == false);
CU_ASSERT((pbdev->superblock_enabled == true && base_info->data_offset != 0) ||
(pbdev->superblock_enabled == false && base_info->data_offset == 0));
CU_ASSERT(base_info->data_offset + base_info->data_size == bdev->blockcnt);
if (bdev && bdev->blockcnt < min_blockcnt) {
min_blockcnt = bdev->blockcnt;
if (bdev && base_info->data_size < min_blockcnt) {
min_blockcnt = base_info->data_size;
}
}
CU_ASSERT((((min_blockcnt / (r->strip_size_kb * 1024 / g_block_len)) *
@ -943,7 +959,7 @@ create_base_bdevs(uint32_t bbdev_start_idx)
static void
create_test_req(struct rpc_bdev_raid_create *r, const char *raid_name,
uint8_t bbdev_start_idx, bool create_base_bdev)
uint8_t bbdev_start_idx, bool create_base_bdev, bool superblock)
{
uint8_t i;
char name[16];
@ -953,6 +969,7 @@ create_test_req(struct rpc_bdev_raid_create *r, const char *raid_name,
SPDK_CU_ASSERT_FATAL(r->name != NULL);
r->strip_size_kb = (g_strip_size * g_block_len) / 1024;
r->level = RAID0;
r->superblock = superblock;
r->base_bdevs.num_base_bdevs = g_max_base_drives;
for (i = 0; i < g_max_base_drives; i++, bbdev_idx++) {
snprintf(name, 16, "%s%u%s", "Nvme", bbdev_idx, "n1");
@ -969,9 +986,9 @@ create_test_req(struct rpc_bdev_raid_create *r, const char *raid_name,
static void
create_raid_bdev_create_req(struct rpc_bdev_raid_create *r, const char *raid_name,
uint8_t bbdev_start_idx, bool create_base_bdev,
uint8_t json_decode_obj_err)
uint8_t json_decode_obj_err, bool superblock)
{
create_test_req(r, raid_name, bbdev_start_idx, create_base_bdev);
create_test_req(r, raid_name, bbdev_start_idx, create_base_bdev, superblock);
g_rpc_err = 0;
g_json_decode_obj_create = 1;
@ -1034,7 +1051,7 @@ test_create_raid(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
@ -1058,7 +1075,7 @@ test_delete_raid(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
@ -1085,44 +1102,44 @@ test_create_raid_invalid_args(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
req.level = INVALID_RAID_LEVEL;
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 1);
free_test_req(&req);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, false, 1);
create_raid_bdev_create_req(&req, "raid1", 0, false, 1, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 1);
free_test_req(&req);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, false, 0);
create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
req.strip_size_kb = 1231;
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 1);
free_test_req(&req);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, false, 0);
create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
free_test_req(&req);
create_raid_bdev_create_req(&req, "raid1", 0, false, 0);
create_raid_bdev_create_req(&req, "raid1", 0, false, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 1);
free_test_req(&req);
create_raid_bdev_create_req(&req, "raid2", 0, false, 0);
create_raid_bdev_create_req(&req, "raid2", 0, false, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 1);
free_test_req(&req);
verify_raid_bdev_present("raid2", false);
create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0);
create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme0n1");
SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
@ -1131,7 +1148,7 @@ test_create_raid_invalid_args(void)
free_test_req(&req);
verify_raid_bdev_present("raid2", false);
create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0);
create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, true, 0, false);
free(req.base_bdevs.base_bdevs[g_max_base_drives - 1]);
req.base_bdevs.base_bdevs[g_max_base_drives - 1] = strdup("Nvme100000n1");
SPDK_CU_ASSERT_FATAL(req.base_bdevs.base_bdevs[g_max_base_drives - 1] != NULL);
@ -1143,7 +1160,7 @@ test_create_raid_invalid_args(void)
SPDK_CU_ASSERT_FATAL(raid_bdev != NULL);
check_and_remove_raid_bdev(raid_bdev);
create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, false, 0);
create_raid_bdev_create_req(&req, "raid2", g_max_base_drives, false, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
free_test_req(&req);
@ -1169,7 +1186,7 @@ test_delete_raid_invalid_args(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&construct_req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&construct_req, true, RAID_BDEV_STATE_ONLINE);
@ -1207,7 +1224,7 @@ test_io_channel(void)
set_globals();
CU_ASSERT(raid_bdev_init() == 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
verify_raid_bdev_present("raid1", false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
@ -1259,7 +1276,7 @@ test_write_io(void)
set_globals();
CU_ASSERT(raid_bdev_init() == 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
verify_raid_bdev_present("raid1", false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
@ -1335,7 +1352,7 @@ test_read_io(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
@ -1485,7 +1502,7 @@ test_unmap_io(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
@ -1556,7 +1573,7 @@ test_io_failure(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
@ -1638,7 +1655,7 @@ test_reset_io(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
@ -1705,7 +1722,7 @@ test_multi_raid_no_io(void)
for (i = 0; i < g_max_raids; i++) {
snprintf(name, 16, "%s%u", "raid", i);
verify_raid_bdev_present(name, false);
create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0);
create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0, false);
bbdev_idx += g_max_base_drives;
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
@ -1808,7 +1825,7 @@ test_multi_raid_with_io(void)
for (i = 0; i < g_max_raids; i++) {
snprintf(name, 16, "%s%u", "raid", i);
verify_raid_bdev_present(name, false);
create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0);
create_raid_bdev_create_req(&construct_req[i], name, bbdev_idx, true, 0, false);
bbdev_idx += g_max_base_drives;
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
@ -1899,7 +1916,7 @@ test_raid_json_dump_info(void)
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, false);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
@ -1949,6 +1966,31 @@ test_raid_level_conversions(void)
CU_ASSERT(raid_str != NULL && strcmp(raid_str, "raid0") == 0);
}
static void
test_create_raid_superblock(void)
{
struct rpc_bdev_raid_create req;
struct rpc_bdev_raid_delete delete_req;
set_globals();
CU_ASSERT(raid_bdev_init() == 0);
verify_raid_bdev_present("raid1", false);
create_raid_bdev_create_req(&req, "raid1", 0, true, 0, true);
rpc_bdev_raid_create(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
verify_raid_bdev(&req, true, RAID_BDEV_STATE_ONLINE);
free_test_req(&req);
create_raid_bdev_delete_req(&delete_req, "raid1", 0);
rpc_bdev_raid_delete(NULL, NULL);
CU_ASSERT(g_rpc_err == 0);
raid_bdev_exit();
base_bdevs_cleanup();
reset_globals();
}
int
main(int argc, char **argv)
{
@ -1961,6 +2003,7 @@ main(int argc, char **argv)
suite = CU_add_suite("raid", NULL, NULL);
CU_ADD_TEST(suite, test_create_raid);
CU_ADD_TEST(suite, test_create_raid_superblock);
CU_ADD_TEST(suite, test_delete_raid);
CU_ADD_TEST(suite, test_create_raid_invalid_args);
CU_ADD_TEST(suite, test_delete_raid_invalid_args);

View File

@ -86,6 +86,7 @@ raid_test_create_raid_bdev(struct raid_params *params, struct raid_bdev_module *
CU_FAIL_FATAL("unsupported raid constraint type");
};
raid_bdev->superblock_enabled = false;
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);
@ -105,6 +106,8 @@ raid_test_create_raid_bdev(struct raid_params *params, struct raid_bdev_module *
base_info->bdev = bdev;
base_info->desc = desc;
base_info->data_offset = 0;
base_info->data_size = bdev->blockcnt;
}
raid_bdev->strip_size = params->strip_size;