1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2022 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/bdev_module.h" 7 #include "spdk/crc32.h" 8 #include "spdk/env.h" 9 #include "spdk/log.h" 10 #include "spdk/string.h" 11 #include "spdk/util.h" 12 13 #include "bdev_raid.h" 14 15 struct raid_bdev_write_sb_ctx { 16 struct raid_bdev *raid_bdev; 17 int status; 18 uint8_t submitted; 19 uint8_t remaining; 20 raid_bdev_write_sb_cb cb; 21 void *cb_ctx; 22 struct spdk_bdev_io_wait_entry wait_entry; 23 }; 24 25 struct raid_bdev_read_sb_ctx { 26 struct spdk_bdev_desc *desc; 27 struct spdk_io_channel *ch; 28 raid_bdev_load_sb_cb cb; 29 void *cb_ctx; 30 void *buf; 31 uint32_t buf_size; 32 }; 33 34 int 35 raid_bdev_alloc_superblock(struct raid_bdev *raid_bdev, uint32_t block_size) 36 { 37 struct raid_bdev_superblock *sb; 38 39 assert(raid_bdev->sb == NULL); 40 41 sb = spdk_dma_zmalloc(SPDK_ALIGN_CEIL(RAID_BDEV_SB_MAX_LENGTH, block_size), 0x1000, NULL); 42 if (!sb) { 43 SPDK_ERRLOG("Failed to allocate raid bdev sb buffer\n"); 44 return -ENOMEM; 45 } 46 47 raid_bdev->sb = sb; 48 49 return 0; 50 } 51 52 void 53 raid_bdev_free_superblock(struct raid_bdev *raid_bdev) 54 { 55 if (raid_bdev->sb_io_buf != NULL && raid_bdev->sb_io_buf != raid_bdev->sb) { 56 assert(spdk_bdev_is_md_interleaved(&raid_bdev->bdev)); 57 spdk_dma_free(raid_bdev->sb_io_buf); 58 raid_bdev->sb_io_buf = NULL; 59 } 60 spdk_dma_free(raid_bdev->sb); 61 raid_bdev->sb = NULL; 62 } 63 64 void 65 raid_bdev_init_superblock(struct raid_bdev *raid_bdev) 66 { 67 struct raid_bdev_superblock *sb = raid_bdev->sb; 68 struct raid_base_bdev_info *base_info; 69 struct raid_bdev_sb_base_bdev *sb_base_bdev; 70 71 memcpy(&sb->signature, RAID_BDEV_SB_SIG, sizeof(sb->signature)); 72 sb->version.major = RAID_BDEV_SB_VERSION_MAJOR; 73 sb->version.minor = RAID_BDEV_SB_VERSION_MINOR; 74 spdk_uuid_copy(&sb->uuid, &raid_bdev->bdev.uuid); 75 snprintf(sb->name, RAID_BDEV_SB_NAME_SIZE, "%s", raid_bdev->bdev.name); 76 sb->raid_size = raid_bdev->bdev.blockcnt; 77 sb->block_size = spdk_bdev_get_data_block_size(&raid_bdev->bdev); 78 sb->level = raid_bdev->level; 79 sb->strip_size = raid_bdev->strip_size; 80 /* TODO: sb->state */ 81 sb->num_base_bdevs = sb->base_bdevs_size = raid_bdev->num_base_bdevs; 82 sb->length = sizeof(*sb) + sizeof(*sb_base_bdev) * sb->base_bdevs_size; 83 84 sb_base_bdev = &sb->base_bdevs[0]; 85 RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) { 86 spdk_uuid_copy(&sb_base_bdev->uuid, &base_info->uuid); 87 sb_base_bdev->data_offset = base_info->data_offset; 88 sb_base_bdev->data_size = base_info->data_size; 89 sb_base_bdev->state = RAID_SB_BASE_BDEV_CONFIGURED; 90 sb_base_bdev->slot = raid_bdev_base_bdev_slot(base_info); 91 sb_base_bdev++; 92 } 93 } 94 95 static int 96 raid_bdev_alloc_sb_io_buf(struct raid_bdev *raid_bdev) 97 { 98 struct raid_bdev_superblock *sb = raid_bdev->sb; 99 100 if (spdk_bdev_is_md_interleaved(&raid_bdev->bdev)) { 101 raid_bdev->sb_io_buf_size = spdk_divide_round_up(sb->length, 102 sb->block_size) * raid_bdev->bdev.blocklen; 103 raid_bdev->sb_io_buf = spdk_dma_zmalloc(raid_bdev->sb_io_buf_size, 0x1000, NULL); 104 if (!raid_bdev->sb_io_buf) { 105 SPDK_ERRLOG("Failed to allocate raid bdev sb io buffer\n"); 106 return -ENOMEM; 107 } 108 } else { 109 raid_bdev->sb_io_buf_size = SPDK_ALIGN_CEIL(sb->length, raid_bdev->bdev.blocklen); 110 raid_bdev->sb_io_buf = raid_bdev->sb; 111 } 112 113 return 0; 114 } 115 116 static void 117 raid_bdev_sb_update_crc(struct raid_bdev_superblock *sb) 118 { 119 sb->crc = 0; 120 sb->crc = spdk_crc32c_update(sb, sb->length, 0); 121 } 122 123 static bool 124 raid_bdev_sb_check_crc(struct raid_bdev_superblock *sb) 125 { 126 uint32_t crc, prev = sb->crc; 127 128 raid_bdev_sb_update_crc(sb); 129 crc = sb->crc; 130 sb->crc = prev; 131 132 return crc == prev; 133 } 134 135 static int 136 raid_bdev_parse_superblock(struct raid_bdev_read_sb_ctx *ctx) 137 { 138 struct raid_bdev_superblock *sb = ctx->buf; 139 struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(ctx->desc); 140 struct raid_bdev_sb_base_bdev *sb_base_bdev; 141 uint8_t i; 142 143 if (memcmp(sb->signature, RAID_BDEV_SB_SIG, sizeof(sb->signature))) { 144 SPDK_DEBUGLOG(bdev_raid_sb, "invalid signature\n"); 145 return -EINVAL; 146 } 147 148 if (spdk_divide_round_up(sb->length, spdk_bdev_get_data_block_size(bdev)) > 149 spdk_divide_round_up(ctx->buf_size, bdev->blocklen)) { 150 if (sb->length > RAID_BDEV_SB_MAX_LENGTH) { 151 SPDK_WARNLOG("Incorrect superblock length on bdev %s\n", 152 spdk_bdev_get_name(bdev)); 153 return -EINVAL; 154 } 155 156 return -EAGAIN; 157 } 158 159 if (!raid_bdev_sb_check_crc(sb)) { 160 SPDK_WARNLOG("Incorrect superblock crc on bdev %s\n", spdk_bdev_get_name(bdev)); 161 return -EINVAL; 162 } 163 164 if (sb->version.major != RAID_BDEV_SB_VERSION_MAJOR) { 165 SPDK_ERRLOG("Not supported superblock major version %d on bdev %s\n", 166 sb->version.major, spdk_bdev_get_name(bdev)); 167 return -EINVAL; 168 } 169 170 if (sb->version.minor > RAID_BDEV_SB_VERSION_MINOR) { 171 SPDK_WARNLOG("Superblock minor version %d on bdev %s is higher than the currently supported: %d\n", 172 sb->version.minor, spdk_bdev_get_name(bdev), RAID_BDEV_SB_VERSION_MINOR); 173 } 174 175 for (i = 0; i < sb->base_bdevs_size; i++) { 176 sb_base_bdev = &sb->base_bdevs[i]; 177 if (sb_base_bdev->slot >= sb->num_base_bdevs) { 178 SPDK_WARNLOG("Invalid superblock base bdev slot number %u on bdev %s\n", 179 sb_base_bdev->slot, spdk_bdev_get_name(bdev)); 180 return -EINVAL; 181 } 182 } 183 184 return 0; 185 } 186 187 static void 188 raid_bdev_read_sb_ctx_free(struct raid_bdev_read_sb_ctx *ctx) 189 { 190 spdk_dma_free(ctx->buf); 191 192 free(ctx); 193 } 194 195 static void raid_bdev_read_sb_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg); 196 197 static int 198 raid_bdev_read_sb_remainder(struct raid_bdev_read_sb_ctx *ctx) 199 { 200 struct raid_bdev_superblock *sb = ctx->buf; 201 struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(ctx->desc); 202 uint32_t buf_size_prev; 203 void *buf; 204 int rc; 205 206 buf_size_prev = ctx->buf_size; 207 ctx->buf_size = spdk_divide_round_up(spdk_min(sb->length, RAID_BDEV_SB_MAX_LENGTH), 208 spdk_bdev_get_data_block_size(bdev)) * bdev->blocklen; 209 buf = spdk_dma_realloc(ctx->buf, ctx->buf_size, spdk_bdev_get_buf_align(bdev), NULL); 210 if (buf == NULL) { 211 SPDK_ERRLOG("Failed to reallocate buffer\n"); 212 return -ENOMEM; 213 } 214 ctx->buf = buf; 215 216 rc = spdk_bdev_read(ctx->desc, ctx->ch, ctx->buf + buf_size_prev, buf_size_prev, 217 ctx->buf_size - buf_size_prev, raid_bdev_read_sb_cb, ctx); 218 if (rc != 0) { 219 SPDK_ERRLOG("Failed to read bdev %s superblock remainder: %s\n", 220 spdk_bdev_get_name(bdev), spdk_strerror(-rc)); 221 return rc; 222 } 223 224 return 0; 225 } 226 227 static void 228 raid_bdev_read_sb_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 229 { 230 struct spdk_bdev *bdev = bdev_io->bdev; 231 struct raid_bdev_read_sb_ctx *ctx = cb_arg; 232 struct raid_bdev_superblock *sb = NULL; 233 int status; 234 235 if (spdk_bdev_is_md_interleaved(bdev_io->bdev) && ctx->buf_size > bdev->blocklen) { 236 const uint32_t data_block_size = spdk_bdev_get_data_block_size(bdev); 237 uint32_t i; 238 239 for (i = 1; i < ctx->buf_size / bdev->blocklen; i++) { 240 memmove(ctx->buf + (i * data_block_size), 241 ctx->buf + (i * bdev->blocklen), 242 data_block_size); 243 } 244 } 245 246 spdk_bdev_free_io(bdev_io); 247 248 if (!success) { 249 status = -EIO; 250 goto out; 251 } 252 253 status = raid_bdev_parse_superblock(ctx); 254 if (status == -EAGAIN) { 255 status = raid_bdev_read_sb_remainder(ctx); 256 if (status == 0) { 257 return; 258 } 259 } else if (status != 0) { 260 SPDK_DEBUGLOG(bdev_raid_sb, "failed to parse bdev %s superblock\n", 261 spdk_bdev_get_name(spdk_bdev_desc_get_bdev(ctx->desc))); 262 } else { 263 sb = ctx->buf; 264 } 265 out: 266 ctx->cb(sb, status, ctx->cb_ctx); 267 268 raid_bdev_read_sb_ctx_free(ctx); 269 } 270 271 int 272 raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 273 raid_bdev_load_sb_cb cb, void *cb_ctx) 274 { 275 struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc); 276 struct raid_bdev_read_sb_ctx *ctx; 277 int rc; 278 279 assert(cb != NULL); 280 281 ctx = calloc(1, sizeof(*ctx)); 282 if (!ctx) { 283 return -ENOMEM; 284 } 285 286 ctx->desc = desc; 287 ctx->ch = ch; 288 ctx->cb = cb; 289 ctx->cb_ctx = cb_ctx; 290 ctx->buf_size = spdk_divide_round_up(sizeof(struct raid_bdev_superblock), 291 spdk_bdev_get_data_block_size(bdev)) * bdev->blocklen; 292 ctx->buf = spdk_dma_malloc(ctx->buf_size, spdk_bdev_get_buf_align(bdev), NULL); 293 if (!ctx->buf) { 294 rc = -ENOMEM; 295 goto err; 296 } 297 298 rc = spdk_bdev_read(desc, ch, ctx->buf, 0, ctx->buf_size, raid_bdev_read_sb_cb, ctx); 299 if (rc) { 300 goto err; 301 } 302 303 return 0; 304 err: 305 raid_bdev_read_sb_ctx_free(ctx); 306 307 return rc; 308 } 309 310 static void 311 raid_bdev_write_sb_base_bdev_done(int status, struct raid_bdev_write_sb_ctx *ctx) 312 { 313 if (status != 0) { 314 ctx->status = status; 315 } 316 317 if (--ctx->remaining == 0) { 318 ctx->cb(ctx->status, ctx->raid_bdev, ctx->cb_ctx); 319 free(ctx); 320 } 321 } 322 323 static void 324 raid_bdev_write_superblock_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 325 { 326 struct raid_bdev_write_sb_ctx *ctx = cb_arg; 327 int status = 0; 328 329 if (!success) { 330 SPDK_ERRLOG("Failed to save superblock on bdev %s\n", bdev_io->bdev->name); 331 status = -EIO; 332 } 333 334 spdk_bdev_free_io(bdev_io); 335 336 raid_bdev_write_sb_base_bdev_done(status, ctx); 337 } 338 339 static void 340 _raid_bdev_write_superblock(void *_ctx) 341 { 342 struct raid_bdev_write_sb_ctx *ctx = _ctx; 343 struct raid_bdev *raid_bdev = ctx->raid_bdev; 344 struct raid_base_bdev_info *base_info; 345 uint8_t i; 346 int rc; 347 348 for (i = ctx->submitted; i < raid_bdev->num_base_bdevs; i++) { 349 base_info = &raid_bdev->base_bdev_info[i]; 350 351 if (!base_info->is_configured || base_info->remove_scheduled) { 352 assert(ctx->remaining > 1); 353 raid_bdev_write_sb_base_bdev_done(0, ctx); 354 ctx->submitted++; 355 continue; 356 } 357 358 rc = spdk_bdev_write(base_info->desc, base_info->app_thread_ch, 359 raid_bdev->sb_io_buf, 0, raid_bdev->sb_io_buf_size, 360 raid_bdev_write_superblock_cb, ctx); 361 if (rc != 0) { 362 struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(base_info->desc); 363 364 if (rc == -ENOMEM) { 365 ctx->wait_entry.bdev = bdev; 366 ctx->wait_entry.cb_fn = _raid_bdev_write_superblock; 367 ctx->wait_entry.cb_arg = ctx; 368 spdk_bdev_queue_io_wait(bdev, base_info->app_thread_ch, &ctx->wait_entry); 369 return; 370 } 371 372 assert(ctx->remaining > 1); 373 raid_bdev_write_sb_base_bdev_done(rc, ctx); 374 } 375 376 ctx->submitted++; 377 } 378 379 raid_bdev_write_sb_base_bdev_done(0, ctx); 380 } 381 382 void 383 raid_bdev_write_superblock(struct raid_bdev *raid_bdev, raid_bdev_write_sb_cb cb, void *cb_ctx) 384 { 385 struct raid_bdev_write_sb_ctx *ctx; 386 struct raid_bdev_superblock *sb = raid_bdev->sb; 387 int rc; 388 389 assert(spdk_get_thread() == spdk_thread_get_app_thread()); 390 assert(sb != NULL); 391 assert(cb != NULL); 392 393 if (raid_bdev->sb_io_buf == NULL) { 394 rc = raid_bdev_alloc_sb_io_buf(raid_bdev); 395 if (rc != 0) { 396 goto err; 397 } 398 } 399 400 ctx = calloc(1, sizeof(*ctx)); 401 if (!ctx) { 402 rc = -ENOMEM; 403 goto err; 404 } 405 406 ctx->raid_bdev = raid_bdev; 407 ctx->remaining = raid_bdev->num_base_bdevs + 1; 408 ctx->cb = cb; 409 ctx->cb_ctx = cb_ctx; 410 411 sb->seq_number++; 412 raid_bdev_sb_update_crc(sb); 413 414 if (spdk_bdev_is_md_interleaved(&raid_bdev->bdev)) { 415 void *sb_buf = sb; 416 uint32_t i; 417 418 for (i = 0; i < raid_bdev->sb_io_buf_size / raid_bdev->bdev.blocklen; i++) { 419 memcpy(raid_bdev->sb_io_buf + (i * raid_bdev->bdev.blocklen), 420 sb_buf + (i * sb->block_size), sb->block_size); 421 } 422 } 423 424 _raid_bdev_write_superblock(ctx); 425 return; 426 err: 427 cb(rc, raid_bdev, cb_ctx); 428 } 429 430 SPDK_LOG_REGISTER_COMPONENT(bdev_raid_sb) 431