1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2022 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk_internal/cunit.h" 7 #include "spdk/stdinc.h" 8 #include "bdev/raid/bdev_raid.h" 9 10 struct spdk_bdev_desc { 11 struct spdk_bdev *bdev; 12 }; 13 14 struct raid_params { 15 uint8_t num_base_bdevs; 16 uint64_t base_bdev_blockcnt; 17 uint32_t base_bdev_blocklen; 18 uint32_t strip_size; 19 uint32_t md_len; 20 }; 21 22 struct raid_params *g_params; 23 size_t g_params_count; 24 size_t g_params_size; 25 26 #define ARRAY_FOR_EACH(a, e) \ 27 for (e = a; e < a + SPDK_COUNTOF(a); e++) 28 29 #define RAID_PARAMS_FOR_EACH(p) \ 30 for (p = g_params; p < g_params + g_params_count; p++) 31 32 struct spdk_bdev * 33 spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) 34 { 35 return desc->bdev; 36 } 37 38 static int 39 raid_test_params_alloc(size_t count) 40 { 41 assert(g_params == NULL); 42 43 g_params_size = count; 44 g_params_count = 0; 45 g_params = calloc(count, sizeof(*g_params)); 46 47 return g_params ? 0 : -ENOMEM; 48 } 49 50 static void 51 raid_test_params_free(void) 52 { 53 g_params_count = 0; 54 g_params_size = 0; 55 free(g_params); 56 } 57 58 static void 59 raid_test_params_add(struct raid_params *params) 60 { 61 assert(g_params_count < g_params_size); 62 63 memcpy(g_params + g_params_count, params, sizeof(*params)); 64 g_params_count++; 65 } 66 67 static struct raid_bdev * 68 raid_test_create_raid_bdev(struct raid_params *params, struct raid_bdev_module *module) 69 { 70 struct raid_bdev *raid_bdev; 71 struct raid_base_bdev_info *base_info; 72 73 raid_bdev = calloc(1, sizeof(*raid_bdev)); 74 SPDK_CU_ASSERT_FATAL(raid_bdev != NULL); 75 76 raid_bdev->module = module; 77 raid_bdev->level = module->level; 78 raid_bdev->num_base_bdevs = params->num_base_bdevs; 79 80 switch (raid_bdev->module->base_bdevs_constraint.type) { 81 case CONSTRAINT_MAX_BASE_BDEVS_REMOVED: 82 raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs - 83 raid_bdev->module->base_bdevs_constraint.value; 84 break; 85 case CONSTRAINT_MIN_BASE_BDEVS_OPERATIONAL: 86 raid_bdev->min_base_bdevs_operational = raid_bdev->module->base_bdevs_constraint.value; 87 break; 88 case CONSTRAINT_UNSET: 89 raid_bdev->min_base_bdevs_operational = raid_bdev->num_base_bdevs; 90 break; 91 default: 92 CU_FAIL_FATAL("unsupported raid constraint type"); 93 }; 94 95 raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs, 96 sizeof(struct raid_base_bdev_info)); 97 SPDK_CU_ASSERT_FATAL(raid_bdev->base_bdev_info != NULL); 98 99 RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 100 struct spdk_bdev *bdev; 101 struct spdk_bdev_desc *desc; 102 103 bdev = calloc(1, sizeof(*bdev)); 104 SPDK_CU_ASSERT_FATAL(bdev != NULL); 105 bdev->blockcnt = params->base_bdev_blockcnt; 106 bdev->blocklen = params->base_bdev_blocklen; 107 108 desc = calloc(1, sizeof(*desc)); 109 SPDK_CU_ASSERT_FATAL(desc != NULL); 110 desc->bdev = bdev; 111 112 base_info->desc = desc; 113 base_info->data_offset = 0; 114 base_info->data_size = bdev->blockcnt; 115 } 116 117 raid_bdev->strip_size = params->strip_size; 118 raid_bdev->strip_size_kb = params->strip_size * params->base_bdev_blocklen / 1024; 119 raid_bdev->strip_size_shift = spdk_u32log2(raid_bdev->strip_size); 120 raid_bdev->blocklen_shift = spdk_u32log2(params->base_bdev_blocklen); 121 raid_bdev->bdev.blocklen = params->base_bdev_blocklen; 122 raid_bdev->bdev.md_len = params->md_len; 123 124 return raid_bdev; 125 } 126 127 static void 128 raid_test_delete_raid_bdev(struct raid_bdev *raid_bdev) 129 { 130 struct raid_base_bdev_info *base_info; 131 132 RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 133 free(base_info->desc->bdev); 134 free(base_info->desc); 135 } 136 free(raid_bdev->base_bdev_info); 137 free(raid_bdev); 138 } 139 140 struct raid_bdev_io_channel { 141 struct spdk_io_channel **_base_channels; 142 struct spdk_io_channel *_module_channel; 143 }; 144 145 struct spdk_io_channel * 146 raid_bdev_channel_get_base_channel(struct raid_bdev_io_channel *raid_ch, uint8_t idx) 147 { 148 return raid_ch->_base_channels[idx]; 149 } 150 151 void * 152 raid_bdev_channel_get_module_ctx(struct raid_bdev_io_channel *raid_ch) 153 { 154 return spdk_io_channel_get_ctx(raid_ch->_module_channel); 155 } 156 157 static struct raid_bdev_io_channel * 158 raid_test_create_io_channel(struct raid_bdev *raid_bdev) 159 { 160 struct raid_bdev_io_channel *raid_ch; 161 uint8_t i; 162 163 raid_ch = calloc(1, sizeof(*raid_ch)); 164 SPDK_CU_ASSERT_FATAL(raid_ch != NULL); 165 166 raid_ch->_base_channels = calloc(raid_bdev->num_base_bdevs, sizeof(struct spdk_io_channel *)); 167 SPDK_CU_ASSERT_FATAL(raid_ch->_base_channels != NULL); 168 169 for (i = 0; i < raid_bdev->num_base_bdevs; i++) { 170 raid_ch->_base_channels[i] = (void *)1; 171 } 172 173 if (raid_bdev->module->get_io_channel) { 174 raid_ch->_module_channel = raid_bdev->module->get_io_channel(raid_bdev); 175 SPDK_CU_ASSERT_FATAL(raid_ch->_module_channel != NULL); 176 } 177 178 return raid_ch; 179 } 180 181 static void 182 raid_test_destroy_io_channel(struct raid_bdev_io_channel *raid_ch) 183 { 184 free(raid_ch->_base_channels); 185 186 if (raid_ch->_module_channel) { 187 spdk_put_io_channel(raid_ch->_module_channel); 188 poll_threads(); 189 } 190 191 free(raid_ch); 192 } 193 194 static void 195 raid_test_bdev_io_init(struct raid_bdev_io *raid_io, struct raid_bdev *raid_bdev, 196 struct raid_bdev_io_channel *raid_ch, 197 enum spdk_bdev_io_type type, uint64_t offset_blocks, 198 uint64_t num_blocks, struct iovec *iovs, int iovcnt, void *md_buf) 199 { 200 memset(raid_io, 0, sizeof(*raid_io)); 201 202 raid_io->raid_bdev = raid_bdev; 203 raid_io->raid_ch = raid_ch; 204 205 raid_io->type = type; 206 raid_io->offset_blocks = offset_blocks; 207 raid_io->num_blocks = num_blocks; 208 raid_io->iovs = iovs; 209 raid_io->iovcnt = iovcnt; 210 raid_io->md_buf = md_buf; 211 212 raid_io->base_bdev_io_status = SPDK_BDEV_IO_STATUS_SUCCESS; 213 } 214 215 /* needs to be implemented in module unit test files */ 216 static void raid_test_bdev_io_complete(struct raid_bdev_io *raid_io, 217 enum spdk_bdev_io_status status); 218 219 void 220 raid_bdev_io_complete(struct raid_bdev_io *raid_io, enum spdk_bdev_io_status status) 221 { 222 if (raid_io->completion_cb != NULL) { 223 raid_io->completion_cb(raid_io, status); 224 } else { 225 raid_test_bdev_io_complete(raid_io, status); 226 } 227 } 228 229 bool 230 raid_bdev_io_complete_part(struct raid_bdev_io *raid_io, uint64_t completed, 231 enum spdk_bdev_io_status status) 232 { 233 SPDK_CU_ASSERT_FATAL(raid_io->base_bdev_io_remaining >= completed); 234 raid_io->base_bdev_io_remaining -= completed; 235 236 if (status != SPDK_BDEV_IO_STATUS_SUCCESS) { 237 raid_io->base_bdev_io_status = status; 238 } 239 240 if (raid_io->base_bdev_io_remaining == 0) { 241 raid_bdev_io_complete(raid_io, raid_io->base_bdev_io_status); 242 return true; 243 } else { 244 return false; 245 } 246 } 247 248 int 249 raid_bdev_readv_blocks_ext(struct raid_base_bdev_info *base_info, struct spdk_io_channel *ch, 250 struct iovec *iov, int iovcnt, uint64_t offset_blocks, 251 uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg, 252 struct spdk_bdev_ext_io_opts *opts) 253 { 254 return spdk_bdev_readv_blocks_ext(base_info->desc, ch, iov, iovcnt, 255 base_info->data_offset + offset_blocks, num_blocks, cb, cb_arg, opts); 256 } 257 258 int 259 raid_bdev_writev_blocks_ext(struct raid_base_bdev_info *base_info, struct spdk_io_channel *ch, 260 struct iovec *iov, int iovcnt, uint64_t offset_blocks, 261 uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg, 262 struct spdk_bdev_ext_io_opts *opts) 263 { 264 return spdk_bdev_writev_blocks_ext(base_info->desc, ch, iov, iovcnt, 265 base_info->data_offset + offset_blocks, num_blocks, cb, cb_arg, opts); 266 } 267