diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index 100301d30..9a5542039 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -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) { diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index b54bae6f9..3daa368d8 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -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 */ diff --git a/module/bdev/raid/bdev_raid_rpc.c b/module/bdev/raid/bdev_raid_rpc.c index 27bc2c466..1c5722572 100644 --- a/module/bdev/raid/bdev_raid_rpc.c +++ b/module/bdev/raid/bdev_raid_rpc.c @@ -130,7 +130,7 @@ struct rpc_bdev_raid_create { /* UUID for this raid bdev */ char *uuid; - + /* superblock support */ bool superblock; }; @@ -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", diff --git a/module/bdev/raid/concat.c b/module/bdev/raid/concat.c index 0d750ae56..4e9865e3c 100644 --- a/module/bdev/raid/concat.c +++ b/module/bdev/raid/concat.c @@ -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; diff --git a/module/bdev/raid/raid0.c b/module/bdev/raid/raid0.c index 2895ef1b4..9372f7629 100644 --- a/module/bdev/raid/raid0.c +++ b/module/bdev/raid/raid0.c @@ -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; } } diff --git a/module/bdev/raid/raid1.c b/module/bdev/raid/raid1.c index 875410ee7..32d766b83 100644 --- a/module/bdev/raid/raid1.c +++ b/module/bdev/raid/raid1.c @@ -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; diff --git a/module/bdev/raid/raid5f.c b/module/bdev/raid/raid5f.c index 7bdadb22a..120950f82 100644 --- a/module/bdev/raid/raid5f.c +++ b/module/bdev/raid/raid5f.c @@ -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; diff --git a/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c b/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c index cc80c5010..11bd4991a 100644 --- a/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c +++ b/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c @@ -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); diff --git a/test/unit/lib/bdev/raid/common.c b/test/unit/lib/bdev/raid/common.c index 776c3c5b2..a8ad7da5d 100644 --- a/test/unit/lib/bdev/raid/common.c +++ b/test/unit/lib/bdev/raid/common.c @@ -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;