1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. All rights reserved. 5 * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk_cunit.h" 35 36 #include "common/lib/ut_multithread.c" 37 #include "unit/lib/json_mock.c" 38 39 #include "spdk/config.h" 40 /* HACK: disable VTune integration so the unit test doesn't need VTune headers and libs to build */ 41 #undef SPDK_CONFIG_VTUNE 42 43 #include "bdev/bdev.c" 44 45 DEFINE_STUB(spdk_conf_find_section, struct spdk_conf_section *, (struct spdk_conf *cp, 46 const char *name), NULL); 47 DEFINE_STUB(spdk_conf_section_get_nmval, char *, 48 (struct spdk_conf_section *sp, const char *key, int idx1, int idx2), NULL); 49 DEFINE_STUB(spdk_conf_section_get_intval, int, (struct spdk_conf_section *sp, const char *key), -1); 50 51 struct spdk_trace_histories *g_trace_histories; 52 DEFINE_STUB_V(spdk_trace_add_register_fn, (struct spdk_trace_register_fn *reg_fn)); 53 DEFINE_STUB_V(spdk_trace_register_owner, (uint8_t type, char id_prefix)); 54 DEFINE_STUB_V(spdk_trace_register_object, (uint8_t type, char id_prefix)); 55 DEFINE_STUB_V(spdk_trace_register_description, (const char *name, 56 uint16_t tpoint_id, uint8_t owner_type, 57 uint8_t object_type, uint8_t new_object, 58 uint8_t arg1_type, const char *arg1_name)); 59 DEFINE_STUB_V(_spdk_trace_record, (uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, 60 uint32_t size, uint64_t object_id, uint64_t arg1)); 61 DEFINE_STUB(spdk_notify_send, uint64_t, (const char *type, const char *ctx), 0); 62 DEFINE_STUB(spdk_notify_type_register, struct spdk_notify_type *, (const char *type), NULL); 63 64 65 int g_status; 66 int g_count; 67 enum spdk_bdev_event_type g_event_type1; 68 enum spdk_bdev_event_type g_event_type2; 69 struct spdk_histogram_data *g_histogram; 70 void *g_unregister_arg; 71 int g_unregister_rc; 72 73 void 74 spdk_scsi_nvme_translate(const struct spdk_bdev_io *bdev_io, 75 int *sc, int *sk, int *asc, int *ascq) 76 { 77 } 78 79 static int 80 null_init(void) 81 { 82 return 0; 83 } 84 85 static int 86 null_clean(void) 87 { 88 return 0; 89 } 90 91 static int 92 stub_destruct(void *ctx) 93 { 94 return 0; 95 } 96 97 struct ut_expected_io { 98 uint8_t type; 99 uint64_t offset; 100 uint64_t length; 101 int iovcnt; 102 struct iovec iov[BDEV_IO_NUM_CHILD_IOV]; 103 void *md_buf; 104 TAILQ_ENTRY(ut_expected_io) link; 105 }; 106 107 struct bdev_ut_channel { 108 TAILQ_HEAD(, spdk_bdev_io) outstanding_io; 109 uint32_t outstanding_io_count; 110 TAILQ_HEAD(, ut_expected_io) expected_io; 111 }; 112 113 static bool g_io_done; 114 static struct spdk_bdev_io *g_bdev_io; 115 static enum spdk_bdev_io_status g_io_status; 116 static enum spdk_bdev_io_status g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 117 static uint32_t g_bdev_ut_io_device; 118 static struct bdev_ut_channel *g_bdev_ut_channel; 119 static void *g_compare_read_buf; 120 static uint32_t g_compare_read_buf_len; 121 static void *g_compare_write_buf; 122 static uint32_t g_compare_write_buf_len; 123 124 static struct ut_expected_io * 125 ut_alloc_expected_io(uint8_t type, uint64_t offset, uint64_t length, int iovcnt) 126 { 127 struct ut_expected_io *expected_io; 128 129 expected_io = calloc(1, sizeof(*expected_io)); 130 SPDK_CU_ASSERT_FATAL(expected_io != NULL); 131 132 expected_io->type = type; 133 expected_io->offset = offset; 134 expected_io->length = length; 135 expected_io->iovcnt = iovcnt; 136 137 return expected_io; 138 } 139 140 static void 141 ut_expected_io_set_iov(struct ut_expected_io *expected_io, int pos, void *base, size_t len) 142 { 143 expected_io->iov[pos].iov_base = base; 144 expected_io->iov[pos].iov_len = len; 145 } 146 147 static void 148 stub_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 149 { 150 struct bdev_ut_channel *ch = spdk_io_channel_get_ctx(_ch); 151 struct ut_expected_io *expected_io; 152 struct iovec *iov, *expected_iov; 153 int i; 154 155 g_bdev_io = bdev_io; 156 157 if (g_compare_read_buf && bdev_io->type == SPDK_BDEV_IO_TYPE_READ) { 158 uint32_t len = bdev_io->u.bdev.iovs[0].iov_len; 159 160 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 161 CU_ASSERT(g_compare_read_buf_len == len); 162 memcpy(bdev_io->u.bdev.iovs[0].iov_base, g_compare_read_buf, len); 163 } 164 165 if (g_compare_write_buf && bdev_io->type == SPDK_BDEV_IO_TYPE_WRITE) { 166 uint32_t len = bdev_io->u.bdev.iovs[0].iov_len; 167 168 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 169 CU_ASSERT(g_compare_write_buf_len == len); 170 memcpy(g_compare_write_buf, bdev_io->u.bdev.iovs[0].iov_base, len); 171 } 172 173 if (g_compare_read_buf && bdev_io->type == SPDK_BDEV_IO_TYPE_COMPARE) { 174 uint32_t len = bdev_io->u.bdev.iovs[0].iov_len; 175 176 CU_ASSERT(bdev_io->u.bdev.iovcnt == 1); 177 CU_ASSERT(g_compare_read_buf_len == len); 178 if (memcmp(bdev_io->u.bdev.iovs[0].iov_base, g_compare_read_buf, len)) { 179 g_io_exp_status = SPDK_BDEV_IO_STATUS_MISCOMPARE; 180 } 181 } 182 183 TAILQ_INSERT_TAIL(&ch->outstanding_io, bdev_io, module_link); 184 ch->outstanding_io_count++; 185 186 expected_io = TAILQ_FIRST(&ch->expected_io); 187 if (expected_io == NULL) { 188 return; 189 } 190 TAILQ_REMOVE(&ch->expected_io, expected_io, link); 191 192 if (expected_io->type != SPDK_BDEV_IO_TYPE_INVALID) { 193 CU_ASSERT(bdev_io->type == expected_io->type); 194 } 195 196 if (expected_io->md_buf != NULL) { 197 CU_ASSERT(expected_io->md_buf == bdev_io->u.bdev.md_buf); 198 } 199 200 if (expected_io->length == 0) { 201 free(expected_io); 202 return; 203 } 204 205 CU_ASSERT(expected_io->offset == bdev_io->u.bdev.offset_blocks); 206 CU_ASSERT(expected_io->length = bdev_io->u.bdev.num_blocks); 207 208 if (expected_io->iovcnt == 0) { 209 free(expected_io); 210 /* UNMAP, WRITE_ZEROES and FLUSH don't have iovs, so we can just return now. */ 211 return; 212 } 213 214 CU_ASSERT(expected_io->iovcnt == bdev_io->u.bdev.iovcnt); 215 for (i = 0; i < expected_io->iovcnt; i++) { 216 iov = &bdev_io->u.bdev.iovs[i]; 217 expected_iov = &expected_io->iov[i]; 218 CU_ASSERT(iov->iov_len == expected_iov->iov_len); 219 CU_ASSERT(iov->iov_base == expected_iov->iov_base); 220 } 221 222 free(expected_io); 223 } 224 225 static void 226 stub_submit_request_get_buf_cb(struct spdk_io_channel *_ch, 227 struct spdk_bdev_io *bdev_io, bool success) 228 { 229 CU_ASSERT(success == true); 230 231 stub_submit_request(_ch, bdev_io); 232 } 233 234 static void 235 stub_submit_request_get_buf(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 236 { 237 spdk_bdev_io_get_buf(bdev_io, stub_submit_request_get_buf_cb, 238 bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); 239 } 240 241 static uint32_t 242 stub_complete_io(uint32_t num_to_complete) 243 { 244 struct bdev_ut_channel *ch = g_bdev_ut_channel; 245 struct spdk_bdev_io *bdev_io; 246 static enum spdk_bdev_io_status io_status; 247 uint32_t num_completed = 0; 248 249 while (num_completed < num_to_complete) { 250 if (TAILQ_EMPTY(&ch->outstanding_io)) { 251 break; 252 } 253 bdev_io = TAILQ_FIRST(&ch->outstanding_io); 254 TAILQ_REMOVE(&ch->outstanding_io, bdev_io, module_link); 255 ch->outstanding_io_count--; 256 io_status = g_io_exp_status == SPDK_BDEV_IO_STATUS_SUCCESS ? SPDK_BDEV_IO_STATUS_SUCCESS : 257 g_io_exp_status; 258 spdk_bdev_io_complete(bdev_io, io_status); 259 num_completed++; 260 } 261 262 return num_completed; 263 } 264 265 static struct spdk_io_channel * 266 bdev_ut_get_io_channel(void *ctx) 267 { 268 return spdk_get_io_channel(&g_bdev_ut_io_device); 269 } 270 271 static bool g_io_types_supported[SPDK_BDEV_NUM_IO_TYPES] = { 272 [SPDK_BDEV_IO_TYPE_READ] = true, 273 [SPDK_BDEV_IO_TYPE_WRITE] = true, 274 [SPDK_BDEV_IO_TYPE_COMPARE] = true, 275 [SPDK_BDEV_IO_TYPE_UNMAP] = true, 276 [SPDK_BDEV_IO_TYPE_FLUSH] = true, 277 [SPDK_BDEV_IO_TYPE_RESET] = true, 278 [SPDK_BDEV_IO_TYPE_NVME_ADMIN] = true, 279 [SPDK_BDEV_IO_TYPE_NVME_IO] = true, 280 [SPDK_BDEV_IO_TYPE_NVME_IO_MD] = true, 281 [SPDK_BDEV_IO_TYPE_WRITE_ZEROES] = true, 282 [SPDK_BDEV_IO_TYPE_ZCOPY] = true, 283 }; 284 285 static void 286 ut_enable_io_type(enum spdk_bdev_io_type io_type, bool enable) 287 { 288 g_io_types_supported[io_type] = enable; 289 } 290 291 static bool 292 stub_io_type_supported(void *_bdev, enum spdk_bdev_io_type io_type) 293 { 294 return g_io_types_supported[io_type]; 295 } 296 297 static struct spdk_bdev_fn_table fn_table = { 298 .destruct = stub_destruct, 299 .submit_request = stub_submit_request, 300 .get_io_channel = bdev_ut_get_io_channel, 301 .io_type_supported = stub_io_type_supported, 302 }; 303 304 static int 305 bdev_ut_create_ch(void *io_device, void *ctx_buf) 306 { 307 struct bdev_ut_channel *ch = ctx_buf; 308 309 CU_ASSERT(g_bdev_ut_channel == NULL); 310 g_bdev_ut_channel = ch; 311 312 TAILQ_INIT(&ch->outstanding_io); 313 ch->outstanding_io_count = 0; 314 TAILQ_INIT(&ch->expected_io); 315 return 0; 316 } 317 318 static void 319 bdev_ut_destroy_ch(void *io_device, void *ctx_buf) 320 { 321 CU_ASSERT(g_bdev_ut_channel != NULL); 322 g_bdev_ut_channel = NULL; 323 } 324 325 struct spdk_bdev_module bdev_ut_if; 326 327 static int 328 bdev_ut_module_init(void) 329 { 330 spdk_io_device_register(&g_bdev_ut_io_device, bdev_ut_create_ch, bdev_ut_destroy_ch, 331 sizeof(struct bdev_ut_channel), NULL); 332 spdk_bdev_module_init_done(&bdev_ut_if); 333 return 0; 334 } 335 336 static void 337 bdev_ut_module_fini(void) 338 { 339 spdk_io_device_unregister(&g_bdev_ut_io_device, NULL); 340 } 341 342 struct spdk_bdev_module bdev_ut_if = { 343 .name = "bdev_ut", 344 .module_init = bdev_ut_module_init, 345 .module_fini = bdev_ut_module_fini, 346 .async_init = true, 347 }; 348 349 static void vbdev_ut_examine(struct spdk_bdev *bdev); 350 351 static int 352 vbdev_ut_module_init(void) 353 { 354 return 0; 355 } 356 357 static void 358 vbdev_ut_module_fini(void) 359 { 360 } 361 362 struct spdk_bdev_module vbdev_ut_if = { 363 .name = "vbdev_ut", 364 .module_init = vbdev_ut_module_init, 365 .module_fini = vbdev_ut_module_fini, 366 .examine_config = vbdev_ut_examine, 367 }; 368 369 SPDK_BDEV_MODULE_REGISTER(bdev_ut, &bdev_ut_if) 370 SPDK_BDEV_MODULE_REGISTER(vbdev_ut, &vbdev_ut_if) 371 372 static void 373 vbdev_ut_examine(struct spdk_bdev *bdev) 374 { 375 spdk_bdev_module_examine_done(&vbdev_ut_if); 376 } 377 378 static struct spdk_bdev * 379 allocate_bdev(char *name) 380 { 381 struct spdk_bdev *bdev; 382 int rc; 383 384 bdev = calloc(1, sizeof(*bdev)); 385 SPDK_CU_ASSERT_FATAL(bdev != NULL); 386 387 bdev->name = name; 388 bdev->fn_table = &fn_table; 389 bdev->module = &bdev_ut_if; 390 bdev->blockcnt = 1024; 391 bdev->blocklen = 512; 392 393 rc = spdk_bdev_register(bdev); 394 CU_ASSERT(rc == 0); 395 396 return bdev; 397 } 398 399 static struct spdk_bdev * 400 allocate_vbdev(char *name) 401 { 402 struct spdk_bdev *bdev; 403 int rc; 404 405 bdev = calloc(1, sizeof(*bdev)); 406 SPDK_CU_ASSERT_FATAL(bdev != NULL); 407 408 bdev->name = name; 409 bdev->fn_table = &fn_table; 410 bdev->module = &vbdev_ut_if; 411 412 rc = spdk_bdev_register(bdev); 413 CU_ASSERT(rc == 0); 414 415 return bdev; 416 } 417 418 static void 419 free_bdev(struct spdk_bdev *bdev) 420 { 421 spdk_bdev_unregister(bdev, NULL, NULL); 422 poll_threads(); 423 memset(bdev, 0xFF, sizeof(*bdev)); 424 free(bdev); 425 } 426 427 static void 428 free_vbdev(struct spdk_bdev *bdev) 429 { 430 spdk_bdev_unregister(bdev, NULL, NULL); 431 poll_threads(); 432 memset(bdev, 0xFF, sizeof(*bdev)); 433 free(bdev); 434 } 435 436 static void 437 get_device_stat_cb(struct spdk_bdev *bdev, struct spdk_bdev_io_stat *stat, void *cb_arg, int rc) 438 { 439 const char *bdev_name; 440 441 CU_ASSERT(bdev != NULL); 442 CU_ASSERT(rc == 0); 443 bdev_name = spdk_bdev_get_name(bdev); 444 CU_ASSERT_STRING_EQUAL(bdev_name, "bdev0"); 445 446 free(stat); 447 free_bdev(bdev); 448 449 *(bool *)cb_arg = true; 450 } 451 452 static void 453 bdev_unregister_cb(void *cb_arg, int rc) 454 { 455 g_unregister_arg = cb_arg; 456 g_unregister_rc = rc; 457 } 458 459 static void 460 bdev_open_cb1(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx) 461 { 462 struct spdk_bdev_desc *desc = *(struct spdk_bdev_desc **)event_ctx; 463 464 g_event_type1 = type; 465 if (SPDK_BDEV_EVENT_REMOVE == type) { 466 spdk_bdev_close(desc); 467 } 468 } 469 470 static void 471 bdev_open_cb2(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx) 472 { 473 struct spdk_bdev_desc *desc = *(struct spdk_bdev_desc **)event_ctx; 474 475 g_event_type2 = type; 476 if (SPDK_BDEV_EVENT_REMOVE == type) { 477 spdk_bdev_close(desc); 478 } 479 } 480 481 static void 482 get_device_stat_test(void) 483 { 484 struct spdk_bdev *bdev; 485 struct spdk_bdev_io_stat *stat; 486 bool done; 487 488 bdev = allocate_bdev("bdev0"); 489 stat = calloc(1, sizeof(struct spdk_bdev_io_stat)); 490 if (stat == NULL) { 491 free_bdev(bdev); 492 return; 493 } 494 495 done = false; 496 spdk_bdev_get_device_stat(bdev, stat, get_device_stat_cb, &done); 497 while (!done) { poll_threads(); } 498 499 500 } 501 502 static void 503 open_write_test(void) 504 { 505 struct spdk_bdev *bdev[9]; 506 struct spdk_bdev_desc *desc[9] = {}; 507 int rc; 508 509 /* 510 * Create a tree of bdevs to test various open w/ write cases. 511 * 512 * bdev0 through bdev3 are physical block devices, such as NVMe 513 * namespaces or Ceph block devices. 514 * 515 * bdev4 is a virtual bdev with multiple base bdevs. This models 516 * caching or RAID use cases. 517 * 518 * bdev5 through bdev7 are all virtual bdevs with the same base 519 * bdev (except bdev7). This models partitioning or logical volume 520 * use cases. 521 * 522 * bdev7 is a virtual bdev with multiple base bdevs. One of base bdevs 523 * (bdev2) is shared with other virtual bdevs: bdev5 and bdev6. This 524 * models caching, RAID, partitioning or logical volumes use cases. 525 * 526 * bdev8 is a virtual bdev with multiple base bdevs, but these 527 * base bdevs are themselves virtual bdevs. 528 * 529 * bdev8 530 * | 531 * +----------+ 532 * | | 533 * bdev4 bdev5 bdev6 bdev7 534 * | | | | 535 * +---+---+ +---+ + +---+---+ 536 * | | \ | / \ 537 * bdev0 bdev1 bdev2 bdev3 538 */ 539 540 bdev[0] = allocate_bdev("bdev0"); 541 rc = spdk_bdev_module_claim_bdev(bdev[0], NULL, &bdev_ut_if); 542 CU_ASSERT(rc == 0); 543 544 bdev[1] = allocate_bdev("bdev1"); 545 rc = spdk_bdev_module_claim_bdev(bdev[1], NULL, &bdev_ut_if); 546 CU_ASSERT(rc == 0); 547 548 bdev[2] = allocate_bdev("bdev2"); 549 rc = spdk_bdev_module_claim_bdev(bdev[2], NULL, &bdev_ut_if); 550 CU_ASSERT(rc == 0); 551 552 bdev[3] = allocate_bdev("bdev3"); 553 rc = spdk_bdev_module_claim_bdev(bdev[3], NULL, &bdev_ut_if); 554 CU_ASSERT(rc == 0); 555 556 bdev[4] = allocate_vbdev("bdev4"); 557 rc = spdk_bdev_module_claim_bdev(bdev[4], NULL, &bdev_ut_if); 558 CU_ASSERT(rc == 0); 559 560 bdev[5] = allocate_vbdev("bdev5"); 561 rc = spdk_bdev_module_claim_bdev(bdev[5], NULL, &bdev_ut_if); 562 CU_ASSERT(rc == 0); 563 564 bdev[6] = allocate_vbdev("bdev6"); 565 566 bdev[7] = allocate_vbdev("bdev7"); 567 568 bdev[8] = allocate_vbdev("bdev8"); 569 570 /* Open bdev0 read-only. This should succeed. */ 571 rc = spdk_bdev_open(bdev[0], false, NULL, NULL, &desc[0]); 572 CU_ASSERT(rc == 0); 573 SPDK_CU_ASSERT_FATAL(desc[0] != NULL); 574 spdk_bdev_close(desc[0]); 575 576 /* 577 * Open bdev1 read/write. This should fail since bdev1 has been claimed 578 * by a vbdev module. 579 */ 580 rc = spdk_bdev_open(bdev[1], true, NULL, NULL, &desc[1]); 581 CU_ASSERT(rc == -EPERM); 582 583 /* 584 * Open bdev4 read/write. This should fail since bdev3 has been claimed 585 * by a vbdev module. 586 */ 587 rc = spdk_bdev_open(bdev[4], true, NULL, NULL, &desc[4]); 588 CU_ASSERT(rc == -EPERM); 589 590 /* Open bdev4 read-only. This should succeed. */ 591 rc = spdk_bdev_open(bdev[4], false, NULL, NULL, &desc[4]); 592 CU_ASSERT(rc == 0); 593 SPDK_CU_ASSERT_FATAL(desc[4] != NULL); 594 spdk_bdev_close(desc[4]); 595 596 /* 597 * Open bdev8 read/write. This should succeed since it is a leaf 598 * bdev. 599 */ 600 rc = spdk_bdev_open(bdev[8], true, NULL, NULL, &desc[8]); 601 CU_ASSERT(rc == 0); 602 SPDK_CU_ASSERT_FATAL(desc[8] != NULL); 603 spdk_bdev_close(desc[8]); 604 605 /* 606 * Open bdev5 read/write. This should fail since bdev4 has been claimed 607 * by a vbdev module. 608 */ 609 rc = spdk_bdev_open(bdev[5], true, NULL, NULL, &desc[5]); 610 CU_ASSERT(rc == -EPERM); 611 612 /* Open bdev4 read-only. This should succeed. */ 613 rc = spdk_bdev_open(bdev[5], false, NULL, NULL, &desc[5]); 614 CU_ASSERT(rc == 0); 615 SPDK_CU_ASSERT_FATAL(desc[5] != NULL); 616 spdk_bdev_close(desc[5]); 617 618 free_vbdev(bdev[8]); 619 620 free_vbdev(bdev[5]); 621 free_vbdev(bdev[6]); 622 free_vbdev(bdev[7]); 623 624 free_vbdev(bdev[4]); 625 626 free_bdev(bdev[0]); 627 free_bdev(bdev[1]); 628 free_bdev(bdev[2]); 629 free_bdev(bdev[3]); 630 } 631 632 static void 633 bytes_to_blocks_test(void) 634 { 635 struct spdk_bdev bdev; 636 uint64_t offset_blocks, num_blocks; 637 638 memset(&bdev, 0, sizeof(bdev)); 639 640 bdev.blocklen = 512; 641 642 /* All parameters valid */ 643 offset_blocks = 0; 644 num_blocks = 0; 645 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 1024, &num_blocks) == 0); 646 CU_ASSERT(offset_blocks == 1); 647 CU_ASSERT(num_blocks == 2); 648 649 /* Offset not a block multiple */ 650 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 3, &offset_blocks, 512, &num_blocks) != 0); 651 652 /* Length not a block multiple */ 653 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 512, &offset_blocks, 3, &num_blocks) != 0); 654 655 /* In case blocklen not the power of two */ 656 bdev.blocklen = 100; 657 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 100, &offset_blocks, 200, &num_blocks) == 0); 658 CU_ASSERT(offset_blocks == 1); 659 CU_ASSERT(num_blocks == 2); 660 661 /* Offset not a block multiple */ 662 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 3, &offset_blocks, 100, &num_blocks) != 0); 663 664 /* Length not a block multiple */ 665 CU_ASSERT(bdev_bytes_to_blocks(&bdev, 100, &offset_blocks, 3, &num_blocks) != 0); 666 } 667 668 static void 669 num_blocks_test(void) 670 { 671 struct spdk_bdev bdev; 672 struct spdk_bdev_desc *desc = NULL; 673 struct spdk_bdev_desc *desc_ext = NULL; 674 int rc; 675 676 memset(&bdev, 0, sizeof(bdev)); 677 bdev.name = "num_blocks"; 678 bdev.fn_table = &fn_table; 679 bdev.module = &bdev_ut_if; 680 spdk_bdev_register(&bdev); 681 spdk_bdev_notify_blockcnt_change(&bdev, 50); 682 683 /* Growing block number */ 684 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 70) == 0); 685 /* Shrinking block number */ 686 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 30) == 0); 687 688 /* In case bdev opened */ 689 rc = spdk_bdev_open(&bdev, false, NULL, NULL, &desc); 690 CU_ASSERT(rc == 0); 691 SPDK_CU_ASSERT_FATAL(desc != NULL); 692 693 /* Growing block number */ 694 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 80) == 0); 695 /* Shrinking block number */ 696 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 20) != 0); 697 698 /* In case bdev opened with ext API */ 699 rc = spdk_bdev_open_ext("num_blocks", false, bdev_open_cb1, &desc_ext, &desc_ext); 700 CU_ASSERT(rc == 0); 701 SPDK_CU_ASSERT_FATAL(desc_ext != NULL); 702 703 g_event_type1 = 0xFF; 704 /* Growing block number */ 705 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 90) == 0); 706 707 poll_threads(); 708 CU_ASSERT_EQUAL(g_event_type1, SPDK_BDEV_EVENT_RESIZE); 709 710 g_event_type1 = 0xFF; 711 /* Growing block number and closing */ 712 CU_ASSERT(spdk_bdev_notify_blockcnt_change(&bdev, 100) == 0); 713 714 spdk_bdev_close(desc); 715 spdk_bdev_close(desc_ext); 716 spdk_bdev_unregister(&bdev, NULL, NULL); 717 718 poll_threads(); 719 720 /* Callback is not called for closed device */ 721 CU_ASSERT_EQUAL(g_event_type1, 0xFF); 722 } 723 724 static void 725 io_valid_test(void) 726 { 727 struct spdk_bdev bdev; 728 729 memset(&bdev, 0, sizeof(bdev)); 730 731 bdev.blocklen = 512; 732 spdk_bdev_notify_blockcnt_change(&bdev, 100); 733 734 /* All parameters valid */ 735 CU_ASSERT(bdev_io_valid_blocks(&bdev, 1, 2) == true); 736 737 /* Last valid block */ 738 CU_ASSERT(bdev_io_valid_blocks(&bdev, 99, 1) == true); 739 740 /* Offset past end of bdev */ 741 CU_ASSERT(bdev_io_valid_blocks(&bdev, 100, 1) == false); 742 743 /* Offset + length past end of bdev */ 744 CU_ASSERT(bdev_io_valid_blocks(&bdev, 99, 2) == false); 745 746 /* Offset near end of uint64_t range (2^64 - 1) */ 747 CU_ASSERT(bdev_io_valid_blocks(&bdev, 18446744073709551615ULL, 1) == false); 748 } 749 750 static void 751 alias_add_del_test(void) 752 { 753 struct spdk_bdev *bdev[3]; 754 int rc; 755 756 /* Creating and registering bdevs */ 757 bdev[0] = allocate_bdev("bdev0"); 758 SPDK_CU_ASSERT_FATAL(bdev[0] != 0); 759 760 bdev[1] = allocate_bdev("bdev1"); 761 SPDK_CU_ASSERT_FATAL(bdev[1] != 0); 762 763 bdev[2] = allocate_bdev("bdev2"); 764 SPDK_CU_ASSERT_FATAL(bdev[2] != 0); 765 766 poll_threads(); 767 768 /* 769 * Trying adding an alias identical to name. 770 * Alias is identical to name, so it can not be added to aliases list 771 */ 772 rc = spdk_bdev_alias_add(bdev[0], bdev[0]->name); 773 CU_ASSERT(rc == -EEXIST); 774 775 /* 776 * Trying to add empty alias, 777 * this one should fail 778 */ 779 rc = spdk_bdev_alias_add(bdev[0], NULL); 780 CU_ASSERT(rc == -EINVAL); 781 782 /* Trying adding same alias to two different registered bdevs */ 783 784 /* Alias is used first time, so this one should pass */ 785 rc = spdk_bdev_alias_add(bdev[0], "proper alias 0"); 786 CU_ASSERT(rc == 0); 787 788 /* Alias was added to another bdev, so this one should fail */ 789 rc = spdk_bdev_alias_add(bdev[1], "proper alias 0"); 790 CU_ASSERT(rc == -EEXIST); 791 792 /* Alias is used first time, so this one should pass */ 793 rc = spdk_bdev_alias_add(bdev[1], "proper alias 1"); 794 CU_ASSERT(rc == 0); 795 796 /* Trying removing an alias from registered bdevs */ 797 798 /* Alias is not on a bdev aliases list, so this one should fail */ 799 rc = spdk_bdev_alias_del(bdev[0], "not existing"); 800 CU_ASSERT(rc == -ENOENT); 801 802 /* Alias is present on a bdev aliases list, so this one should pass */ 803 rc = spdk_bdev_alias_del(bdev[0], "proper alias 0"); 804 CU_ASSERT(rc == 0); 805 806 /* Alias is present on a bdev aliases list, so this one should pass */ 807 rc = spdk_bdev_alias_del(bdev[1], "proper alias 1"); 808 CU_ASSERT(rc == 0); 809 810 /* Trying to remove name instead of alias, so this one should fail, name cannot be changed or removed */ 811 rc = spdk_bdev_alias_del(bdev[0], bdev[0]->name); 812 CU_ASSERT(rc != 0); 813 814 /* Trying to del all alias from empty alias list */ 815 spdk_bdev_alias_del_all(bdev[2]); 816 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&bdev[2]->aliases)); 817 818 /* Trying to del all alias from non-empty alias list */ 819 rc = spdk_bdev_alias_add(bdev[2], "alias0"); 820 CU_ASSERT(rc == 0); 821 rc = spdk_bdev_alias_add(bdev[2], "alias1"); 822 CU_ASSERT(rc == 0); 823 spdk_bdev_alias_del_all(bdev[2]); 824 CU_ASSERT(TAILQ_EMPTY(&bdev[2]->aliases)); 825 826 /* Unregister and free bdevs */ 827 spdk_bdev_unregister(bdev[0], NULL, NULL); 828 spdk_bdev_unregister(bdev[1], NULL, NULL); 829 spdk_bdev_unregister(bdev[2], NULL, NULL); 830 831 poll_threads(); 832 833 free(bdev[0]); 834 free(bdev[1]); 835 free(bdev[2]); 836 } 837 838 static void 839 io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) 840 { 841 g_io_done = true; 842 g_io_status = bdev_io->internal.status; 843 spdk_bdev_free_io(bdev_io); 844 } 845 846 static void 847 bdev_init_cb(void *arg, int rc) 848 { 849 CU_ASSERT(rc == 0); 850 } 851 852 static void 853 bdev_fini_cb(void *arg) 854 { 855 } 856 857 struct bdev_ut_io_wait_entry { 858 struct spdk_bdev_io_wait_entry entry; 859 struct spdk_io_channel *io_ch; 860 struct spdk_bdev_desc *desc; 861 bool submitted; 862 }; 863 864 static void 865 io_wait_cb(void *arg) 866 { 867 struct bdev_ut_io_wait_entry *entry = arg; 868 int rc; 869 870 rc = spdk_bdev_read_blocks(entry->desc, entry->io_ch, NULL, 0, 1, io_done, NULL); 871 CU_ASSERT(rc == 0); 872 entry->submitted = true; 873 } 874 875 static void 876 bdev_io_types_test(void) 877 { 878 struct spdk_bdev *bdev; 879 struct spdk_bdev_desc *desc = NULL; 880 struct spdk_io_channel *io_ch; 881 struct spdk_bdev_opts bdev_opts = { 882 .bdev_io_pool_size = 4, 883 .bdev_io_cache_size = 2, 884 }; 885 int rc; 886 887 rc = spdk_bdev_set_opts(&bdev_opts); 888 CU_ASSERT(rc == 0); 889 spdk_bdev_initialize(bdev_init_cb, NULL); 890 poll_threads(); 891 892 bdev = allocate_bdev("bdev0"); 893 894 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 895 CU_ASSERT(rc == 0); 896 poll_threads(); 897 SPDK_CU_ASSERT_FATAL(desc != NULL); 898 io_ch = spdk_bdev_get_io_channel(desc); 899 CU_ASSERT(io_ch != NULL); 900 901 /* WRITE and WRITE ZEROES are not supported */ 902 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, false); 903 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE, false); 904 rc = spdk_bdev_write_zeroes_blocks(desc, io_ch, 0, 128, io_done, NULL); 905 CU_ASSERT(rc == -ENOTSUP); 906 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, true); 907 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE, true); 908 909 spdk_put_io_channel(io_ch); 910 spdk_bdev_close(desc); 911 free_bdev(bdev); 912 spdk_bdev_finish(bdev_fini_cb, NULL); 913 poll_threads(); 914 } 915 916 static void 917 bdev_io_wait_test(void) 918 { 919 struct spdk_bdev *bdev; 920 struct spdk_bdev_desc *desc = NULL; 921 struct spdk_io_channel *io_ch; 922 struct spdk_bdev_opts bdev_opts = { 923 .bdev_io_pool_size = 4, 924 .bdev_io_cache_size = 2, 925 }; 926 struct bdev_ut_io_wait_entry io_wait_entry; 927 struct bdev_ut_io_wait_entry io_wait_entry2; 928 int rc; 929 930 rc = spdk_bdev_set_opts(&bdev_opts); 931 CU_ASSERT(rc == 0); 932 spdk_bdev_initialize(bdev_init_cb, NULL); 933 poll_threads(); 934 935 bdev = allocate_bdev("bdev0"); 936 937 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 938 CU_ASSERT(rc == 0); 939 poll_threads(); 940 SPDK_CU_ASSERT_FATAL(desc != NULL); 941 io_ch = spdk_bdev_get_io_channel(desc); 942 CU_ASSERT(io_ch != NULL); 943 944 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 945 CU_ASSERT(rc == 0); 946 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 947 CU_ASSERT(rc == 0); 948 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 949 CU_ASSERT(rc == 0); 950 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 951 CU_ASSERT(rc == 0); 952 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 953 954 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 955 CU_ASSERT(rc == -ENOMEM); 956 957 io_wait_entry.entry.bdev = bdev; 958 io_wait_entry.entry.cb_fn = io_wait_cb; 959 io_wait_entry.entry.cb_arg = &io_wait_entry; 960 io_wait_entry.io_ch = io_ch; 961 io_wait_entry.desc = desc; 962 io_wait_entry.submitted = false; 963 /* Cannot use the same io_wait_entry for two different calls. */ 964 memcpy(&io_wait_entry2, &io_wait_entry, sizeof(io_wait_entry)); 965 io_wait_entry2.entry.cb_arg = &io_wait_entry2; 966 967 /* Queue two I/O waits. */ 968 rc = spdk_bdev_queue_io_wait(bdev, io_ch, &io_wait_entry.entry); 969 CU_ASSERT(rc == 0); 970 CU_ASSERT(io_wait_entry.submitted == false); 971 rc = spdk_bdev_queue_io_wait(bdev, io_ch, &io_wait_entry2.entry); 972 CU_ASSERT(rc == 0); 973 CU_ASSERT(io_wait_entry2.submitted == false); 974 975 stub_complete_io(1); 976 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 977 CU_ASSERT(io_wait_entry.submitted == true); 978 CU_ASSERT(io_wait_entry2.submitted == false); 979 980 stub_complete_io(1); 981 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 4); 982 CU_ASSERT(io_wait_entry2.submitted == true); 983 984 stub_complete_io(4); 985 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 986 987 spdk_put_io_channel(io_ch); 988 spdk_bdev_close(desc); 989 free_bdev(bdev); 990 spdk_bdev_finish(bdev_fini_cb, NULL); 991 poll_threads(); 992 } 993 994 static void 995 bdev_io_spans_boundary_test(void) 996 { 997 struct spdk_bdev bdev; 998 struct spdk_bdev_io bdev_io; 999 1000 memset(&bdev, 0, sizeof(bdev)); 1001 1002 bdev.optimal_io_boundary = 0; 1003 bdev_io.bdev = &bdev; 1004 1005 /* bdev has no optimal_io_boundary set - so this should return false. */ 1006 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1007 1008 bdev.optimal_io_boundary = 32; 1009 bdev_io.type = SPDK_BDEV_IO_TYPE_RESET; 1010 1011 /* RESETs are not based on LBAs - so this should return false. */ 1012 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1013 1014 bdev_io.type = SPDK_BDEV_IO_TYPE_READ; 1015 bdev_io.u.bdev.offset_blocks = 0; 1016 bdev_io.u.bdev.num_blocks = 32; 1017 1018 /* This I/O run right up to, but does not cross, the boundary - so this should return false. */ 1019 CU_ASSERT(bdev_io_should_split(&bdev_io) == false); 1020 1021 bdev_io.u.bdev.num_blocks = 33; 1022 1023 /* This I/O spans a boundary. */ 1024 CU_ASSERT(bdev_io_should_split(&bdev_io) == true); 1025 } 1026 1027 static void 1028 bdev_io_split_test(void) 1029 { 1030 struct spdk_bdev *bdev; 1031 struct spdk_bdev_desc *desc = NULL; 1032 struct spdk_io_channel *io_ch; 1033 struct spdk_bdev_opts bdev_opts = { 1034 .bdev_io_pool_size = 512, 1035 .bdev_io_cache_size = 64, 1036 }; 1037 struct iovec iov[BDEV_IO_NUM_CHILD_IOV * 2]; 1038 struct ut_expected_io *expected_io; 1039 uint64_t i; 1040 int rc; 1041 1042 rc = spdk_bdev_set_opts(&bdev_opts); 1043 CU_ASSERT(rc == 0); 1044 spdk_bdev_initialize(bdev_init_cb, NULL); 1045 1046 bdev = allocate_bdev("bdev0"); 1047 1048 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 1049 CU_ASSERT(rc == 0); 1050 SPDK_CU_ASSERT_FATAL(desc != NULL); 1051 io_ch = spdk_bdev_get_io_channel(desc); 1052 CU_ASSERT(io_ch != NULL); 1053 1054 bdev->optimal_io_boundary = 16; 1055 bdev->split_on_optimal_io_boundary = false; 1056 1057 g_io_done = false; 1058 1059 /* First test that the I/O does not get split if split_on_optimal_io_boundary == false. */ 1060 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 8, 1); 1061 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 8 * 512); 1062 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1063 1064 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 1065 CU_ASSERT(rc == 0); 1066 CU_ASSERT(g_io_done == false); 1067 1068 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1069 stub_complete_io(1); 1070 CU_ASSERT(g_io_done == true); 1071 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1072 1073 bdev->split_on_optimal_io_boundary = true; 1074 1075 /* Now test that a single-vector command is split correctly. 1076 * Offset 14, length 8, payload 0xF000 1077 * Child - Offset 14, length 2, payload 0xF000 1078 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 1079 * 1080 * Set up the expected values before calling spdk_bdev_read_blocks 1081 */ 1082 g_io_done = false; 1083 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1); 1084 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 1085 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1086 1087 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1); 1088 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 1089 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1090 1091 /* spdk_bdev_read_blocks will submit the first child immediately. */ 1092 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 1093 CU_ASSERT(rc == 0); 1094 CU_ASSERT(g_io_done == false); 1095 1096 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1097 stub_complete_io(2); 1098 CU_ASSERT(g_io_done == true); 1099 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1100 1101 /* Now set up a more complex, multi-vector command that needs to be split, 1102 * including splitting iovecs. 1103 */ 1104 iov[0].iov_base = (void *)0x10000; 1105 iov[0].iov_len = 512; 1106 iov[1].iov_base = (void *)0x20000; 1107 iov[1].iov_len = 20 * 512; 1108 iov[2].iov_base = (void *)0x30000; 1109 iov[2].iov_len = 11 * 512; 1110 1111 g_io_done = false; 1112 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 2); 1113 ut_expected_io_set_iov(expected_io, 0, (void *)0x10000, 512); 1114 ut_expected_io_set_iov(expected_io, 1, (void *)0x20000, 512); 1115 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1116 1117 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 16, 1); 1118 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 512), 16 * 512); 1119 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1120 1121 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 2); 1122 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 17 * 512), 3 * 512); 1123 ut_expected_io_set_iov(expected_io, 1, (void *)0x30000, 11 * 512); 1124 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1125 1126 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 3, 14, 32, io_done, NULL); 1127 CU_ASSERT(rc == 0); 1128 CU_ASSERT(g_io_done == false); 1129 1130 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 1131 stub_complete_io(3); 1132 CU_ASSERT(g_io_done == true); 1133 1134 /* Test multi vector command that needs to be split by strip and then needs to be 1135 * split further due to the capacity of child iovs. 1136 */ 1137 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV * 2; i++) { 1138 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1139 iov[i].iov_len = 512; 1140 } 1141 1142 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1143 g_io_done = false; 1144 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, BDEV_IO_NUM_CHILD_IOV, 1145 BDEV_IO_NUM_CHILD_IOV); 1146 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1147 ut_expected_io_set_iov(expected_io, i, (void *)((i + 1) * 0x10000), 512); 1148 } 1149 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1150 1151 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1152 BDEV_IO_NUM_CHILD_IOV, BDEV_IO_NUM_CHILD_IOV); 1153 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1154 ut_expected_io_set_iov(expected_io, i, 1155 (void *)((i + 1 + BDEV_IO_NUM_CHILD_IOV) * 0x10000), 512); 1156 } 1157 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1158 1159 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV * 2, 0, 1160 BDEV_IO_NUM_CHILD_IOV * 2, io_done, NULL); 1161 CU_ASSERT(rc == 0); 1162 CU_ASSERT(g_io_done == false); 1163 1164 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1165 stub_complete_io(1); 1166 CU_ASSERT(g_io_done == false); 1167 1168 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1169 stub_complete_io(1); 1170 CU_ASSERT(g_io_done == true); 1171 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1172 1173 /* Test multi vector command that needs to be split by strip and then needs to be 1174 * split further due to the capacity of child iovs. In this case, the length of 1175 * the rest of iovec array with an I/O boundary is the multiple of block size. 1176 */ 1177 1178 /* Fill iovec array for exactly one boundary. The iovec cnt for this boundary 1179 * is BDEV_IO_NUM_CHILD_IOV + 1, which exceeds the capacity of child iovs. 1180 */ 1181 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 1182 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1183 iov[i].iov_len = 512; 1184 } 1185 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1186 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1187 iov[i].iov_len = 256; 1188 } 1189 iov[BDEV_IO_NUM_CHILD_IOV].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000); 1190 iov[BDEV_IO_NUM_CHILD_IOV].iov_len = 512; 1191 1192 /* Add an extra iovec to trigger split */ 1193 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000); 1194 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_len = 512; 1195 1196 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1197 g_io_done = false; 1198 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 1199 BDEV_IO_NUM_CHILD_IOV - 1, BDEV_IO_NUM_CHILD_IOV); 1200 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 1201 ut_expected_io_set_iov(expected_io, i, 1202 (void *)((i + 1) * 0x10000), 512); 1203 } 1204 for (i = BDEV_IO_NUM_CHILD_IOV - 2; i < BDEV_IO_NUM_CHILD_IOV; i++) { 1205 ut_expected_io_set_iov(expected_io, i, 1206 (void *)((i + 1) * 0x10000), 256); 1207 } 1208 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1209 1210 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV - 1, 1211 1, 1); 1212 ut_expected_io_set_iov(expected_io, 0, 1213 (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000), 512); 1214 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1215 1216 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1217 1, 1); 1218 ut_expected_io_set_iov(expected_io, 0, 1219 (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000), 512); 1220 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1221 1222 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV + 2, 0, 1223 BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1224 CU_ASSERT(rc == 0); 1225 CU_ASSERT(g_io_done == false); 1226 1227 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1228 stub_complete_io(1); 1229 CU_ASSERT(g_io_done == false); 1230 1231 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1232 stub_complete_io(2); 1233 CU_ASSERT(g_io_done == true); 1234 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1235 1236 /* Test multi vector command that needs to be split by strip and then needs to be 1237 * split further due to the capacity of child iovs, the child request offset should 1238 * be rewind to last aligned offset and go success without error. 1239 */ 1240 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 1; i++) { 1241 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1242 iov[i].iov_len = 512; 1243 } 1244 iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_base = (void *)(BDEV_IO_NUM_CHILD_IOV * 0x10000); 1245 iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_len = 256; 1246 1247 iov[BDEV_IO_NUM_CHILD_IOV].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000); 1248 iov[BDEV_IO_NUM_CHILD_IOV].iov_len = 256; 1249 1250 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_base = (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000); 1251 iov[BDEV_IO_NUM_CHILD_IOV + 1].iov_len = 512; 1252 1253 bdev->optimal_io_boundary = BDEV_IO_NUM_CHILD_IOV; 1254 g_io_done = false; 1255 g_io_status = 0; 1256 /* The first expected io should be start from offset 0 to BDEV_IO_NUM_CHILD_IOV - 1 */ 1257 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 1258 BDEV_IO_NUM_CHILD_IOV - 1, BDEV_IO_NUM_CHILD_IOV - 1); 1259 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 1; i++) { 1260 ut_expected_io_set_iov(expected_io, i, 1261 (void *)((i + 1) * 0x10000), 512); 1262 } 1263 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1264 /* The second expected io should be start from offset BDEV_IO_NUM_CHILD_IOV - 1 to BDEV_IO_NUM_CHILD_IOV */ 1265 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV - 1, 1266 1, 2); 1267 ut_expected_io_set_iov(expected_io, 0, 1268 (void *)(BDEV_IO_NUM_CHILD_IOV * 0x10000), 256); 1269 ut_expected_io_set_iov(expected_io, 1, 1270 (void *)((BDEV_IO_NUM_CHILD_IOV + 1) * 0x10000), 256); 1271 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1272 /* The third expected io should be start from offset BDEV_IO_NUM_CHILD_IOV to BDEV_IO_NUM_CHILD_IOV + 1 */ 1273 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1274 1, 1); 1275 ut_expected_io_set_iov(expected_io, 0, 1276 (void *)((BDEV_IO_NUM_CHILD_IOV + 2) * 0x10000), 512); 1277 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1278 1279 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV * 2, 0, 1280 BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1281 CU_ASSERT(rc == 0); 1282 CU_ASSERT(g_io_done == false); 1283 1284 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1285 stub_complete_io(1); 1286 CU_ASSERT(g_io_done == false); 1287 1288 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 1289 stub_complete_io(2); 1290 CU_ASSERT(g_io_done == true); 1291 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1292 1293 /* Test multi vector command that needs to be split due to the IO boundary and 1294 * the capacity of child iovs. Especially test the case when the command is 1295 * split due to the capacity of child iovs, the tail address is not aligned with 1296 * block size and is rewinded to the aligned address. 1297 * 1298 * The iovecs used in read request is complex but is based on the data 1299 * collected in the real issue. We change the base addresses but keep the lengths 1300 * not to loose the credibility of the test. 1301 */ 1302 bdev->optimal_io_boundary = 128; 1303 g_io_done = false; 1304 g_io_status = 0; 1305 1306 for (i = 0; i < 31; i++) { 1307 iov[i].iov_base = (void *)(0xFEED0000000 + (i << 20)); 1308 iov[i].iov_len = 1024; 1309 } 1310 iov[31].iov_base = (void *)0xFEED1F00000; 1311 iov[31].iov_len = 32768; 1312 iov[32].iov_base = (void *)0xFEED2000000; 1313 iov[32].iov_len = 160; 1314 iov[33].iov_base = (void *)0xFEED2100000; 1315 iov[33].iov_len = 4096; 1316 iov[34].iov_base = (void *)0xFEED2200000; 1317 iov[34].iov_len = 4096; 1318 iov[35].iov_base = (void *)0xFEED2300000; 1319 iov[35].iov_len = 4096; 1320 iov[36].iov_base = (void *)0xFEED2400000; 1321 iov[36].iov_len = 4096; 1322 iov[37].iov_base = (void *)0xFEED2500000; 1323 iov[37].iov_len = 4096; 1324 iov[38].iov_base = (void *)0xFEED2600000; 1325 iov[38].iov_len = 4096; 1326 iov[39].iov_base = (void *)0xFEED2700000; 1327 iov[39].iov_len = 4096; 1328 iov[40].iov_base = (void *)0xFEED2800000; 1329 iov[40].iov_len = 4096; 1330 iov[41].iov_base = (void *)0xFEED2900000; 1331 iov[41].iov_len = 4096; 1332 iov[42].iov_base = (void *)0xFEED2A00000; 1333 iov[42].iov_len = 4096; 1334 iov[43].iov_base = (void *)0xFEED2B00000; 1335 iov[43].iov_len = 12288; 1336 iov[44].iov_base = (void *)0xFEED2C00000; 1337 iov[44].iov_len = 8192; 1338 iov[45].iov_base = (void *)0xFEED2F00000; 1339 iov[45].iov_len = 4096; 1340 iov[46].iov_base = (void *)0xFEED3000000; 1341 iov[46].iov_len = 4096; 1342 iov[47].iov_base = (void *)0xFEED3100000; 1343 iov[47].iov_len = 4096; 1344 iov[48].iov_base = (void *)0xFEED3200000; 1345 iov[48].iov_len = 24576; 1346 iov[49].iov_base = (void *)0xFEED3300000; 1347 iov[49].iov_len = 16384; 1348 iov[50].iov_base = (void *)0xFEED3400000; 1349 iov[50].iov_len = 12288; 1350 iov[51].iov_base = (void *)0xFEED3500000; 1351 iov[51].iov_len = 4096; 1352 iov[52].iov_base = (void *)0xFEED3600000; 1353 iov[52].iov_len = 4096; 1354 iov[53].iov_base = (void *)0xFEED3700000; 1355 iov[53].iov_len = 4096; 1356 iov[54].iov_base = (void *)0xFEED3800000; 1357 iov[54].iov_len = 28672; 1358 iov[55].iov_base = (void *)0xFEED3900000; 1359 iov[55].iov_len = 20480; 1360 iov[56].iov_base = (void *)0xFEED3A00000; 1361 iov[56].iov_len = 4096; 1362 iov[57].iov_base = (void *)0xFEED3B00000; 1363 iov[57].iov_len = 12288; 1364 iov[58].iov_base = (void *)0xFEED3C00000; 1365 iov[58].iov_len = 4096; 1366 iov[59].iov_base = (void *)0xFEED3D00000; 1367 iov[59].iov_len = 4096; 1368 iov[60].iov_base = (void *)0xFEED3E00000; 1369 iov[60].iov_len = 352; 1370 1371 /* The 1st child IO must be from iov[0] to iov[31] split by the capacity 1372 * of child iovs, 1373 */ 1374 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, 126, 32); 1375 for (i = 0; i < 32; i++) { 1376 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, iov[i].iov_len); 1377 } 1378 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1379 1380 /* The 2nd child IO must be from iov[32] to the first 864 bytes of iov[33] 1381 * split by the IO boundary requirement. 1382 */ 1383 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 126, 2, 2); 1384 ut_expected_io_set_iov(expected_io, 0, iov[32].iov_base, iov[32].iov_len); 1385 ut_expected_io_set_iov(expected_io, 1, iov[33].iov_base, 864); 1386 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1387 1388 /* The 3rd child IO must be from the remaining 3232 bytes of iov[33] to 1389 * the first 864 bytes of iov[46] split by the IO boundary requirement. 1390 */ 1391 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 128, 128, 14); 1392 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[33].iov_base + 864), 1393 iov[33].iov_len - 864); 1394 ut_expected_io_set_iov(expected_io, 1, iov[34].iov_base, iov[34].iov_len); 1395 ut_expected_io_set_iov(expected_io, 2, iov[35].iov_base, iov[35].iov_len); 1396 ut_expected_io_set_iov(expected_io, 3, iov[36].iov_base, iov[36].iov_len); 1397 ut_expected_io_set_iov(expected_io, 4, iov[37].iov_base, iov[37].iov_len); 1398 ut_expected_io_set_iov(expected_io, 5, iov[38].iov_base, iov[38].iov_len); 1399 ut_expected_io_set_iov(expected_io, 6, iov[39].iov_base, iov[39].iov_len); 1400 ut_expected_io_set_iov(expected_io, 7, iov[40].iov_base, iov[40].iov_len); 1401 ut_expected_io_set_iov(expected_io, 8, iov[41].iov_base, iov[41].iov_len); 1402 ut_expected_io_set_iov(expected_io, 9, iov[42].iov_base, iov[42].iov_len); 1403 ut_expected_io_set_iov(expected_io, 10, iov[43].iov_base, iov[43].iov_len); 1404 ut_expected_io_set_iov(expected_io, 11, iov[44].iov_base, iov[44].iov_len); 1405 ut_expected_io_set_iov(expected_io, 12, iov[45].iov_base, iov[45].iov_len); 1406 ut_expected_io_set_iov(expected_io, 13, iov[46].iov_base, 864); 1407 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1408 1409 /* The 4th child IO must be from the remaining 3232 bytes of iov[46] to the 1410 * first 864 bytes of iov[52] split by the IO boundary requirement. 1411 */ 1412 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 256, 128, 7); 1413 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[46].iov_base + 864), 1414 iov[46].iov_len - 864); 1415 ut_expected_io_set_iov(expected_io, 1, iov[47].iov_base, iov[47].iov_len); 1416 ut_expected_io_set_iov(expected_io, 2, iov[48].iov_base, iov[48].iov_len); 1417 ut_expected_io_set_iov(expected_io, 3, iov[49].iov_base, iov[49].iov_len); 1418 ut_expected_io_set_iov(expected_io, 4, iov[50].iov_base, iov[50].iov_len); 1419 ut_expected_io_set_iov(expected_io, 5, iov[51].iov_base, iov[51].iov_len); 1420 ut_expected_io_set_iov(expected_io, 6, iov[52].iov_base, 864); 1421 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1422 1423 /* The 5th child IO must be from the remaining 3232 bytes of iov[52] to 1424 * the first 4096 bytes of iov[57] split by the IO boundary requirement. 1425 */ 1426 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 384, 128, 6); 1427 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[52].iov_base + 864), 1428 iov[52].iov_len - 864); 1429 ut_expected_io_set_iov(expected_io, 1, iov[53].iov_base, iov[53].iov_len); 1430 ut_expected_io_set_iov(expected_io, 2, iov[54].iov_base, iov[54].iov_len); 1431 ut_expected_io_set_iov(expected_io, 3, iov[55].iov_base, iov[55].iov_len); 1432 ut_expected_io_set_iov(expected_io, 4, iov[56].iov_base, iov[56].iov_len); 1433 ut_expected_io_set_iov(expected_io, 5, iov[57].iov_base, 4960); 1434 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1435 1436 /* The 6th child IO must be from the remaining 7328 bytes of iov[57] 1437 * to the first 3936 bytes of iov[58] split by the capacity of child iovs. 1438 */ 1439 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 512, 30, 3); 1440 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[57].iov_base + 4960), 1441 iov[57].iov_len - 4960); 1442 ut_expected_io_set_iov(expected_io, 1, iov[58].iov_base, iov[58].iov_len); 1443 ut_expected_io_set_iov(expected_io, 2, iov[59].iov_base, 3936); 1444 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1445 1446 /* The 7th child IO is from the remaining 160 bytes of iov[59] and iov[60]. */ 1447 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 542, 1, 2); 1448 ut_expected_io_set_iov(expected_io, 0, (void *)((uintptr_t)iov[59].iov_base + 3936), 1449 iov[59].iov_len - 3936); 1450 ut_expected_io_set_iov(expected_io, 1, iov[60].iov_base, iov[60].iov_len); 1451 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1452 1453 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, 61, 0, 543, io_done, NULL); 1454 CU_ASSERT(rc == 0); 1455 CU_ASSERT(g_io_done == false); 1456 1457 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1458 stub_complete_io(1); 1459 CU_ASSERT(g_io_done == false); 1460 1461 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 5); 1462 stub_complete_io(5); 1463 CU_ASSERT(g_io_done == false); 1464 1465 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1466 stub_complete_io(1); 1467 CU_ASSERT(g_io_done == true); 1468 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1469 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 1470 1471 /* Test a WRITE_ZEROES that would span an I/O boundary. WRITE_ZEROES should not be 1472 * split, so test that. 1473 */ 1474 bdev->optimal_io_boundary = 15; 1475 g_io_done = false; 1476 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, 9, 36, 0); 1477 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1478 1479 rc = spdk_bdev_write_zeroes_blocks(desc, io_ch, 9, 36, io_done, NULL); 1480 CU_ASSERT(rc == 0); 1481 CU_ASSERT(g_io_done == false); 1482 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1483 stub_complete_io(1); 1484 CU_ASSERT(g_io_done == true); 1485 1486 /* Test an UNMAP. This should also not be split. */ 1487 bdev->optimal_io_boundary = 16; 1488 g_io_done = false; 1489 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_UNMAP, 15, 2, 0); 1490 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1491 1492 rc = spdk_bdev_unmap_blocks(desc, io_ch, 15, 2, io_done, NULL); 1493 CU_ASSERT(rc == 0); 1494 CU_ASSERT(g_io_done == false); 1495 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1496 stub_complete_io(1); 1497 CU_ASSERT(g_io_done == true); 1498 1499 /* Test a FLUSH. This should also not be split. */ 1500 bdev->optimal_io_boundary = 16; 1501 g_io_done = false; 1502 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_FLUSH, 15, 2, 0); 1503 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1504 1505 rc = spdk_bdev_flush_blocks(desc, io_ch, 15, 2, io_done, NULL); 1506 CU_ASSERT(rc == 0); 1507 CU_ASSERT(g_io_done == false); 1508 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1509 stub_complete_io(1); 1510 CU_ASSERT(g_io_done == true); 1511 1512 CU_ASSERT(TAILQ_EMPTY(&g_bdev_ut_channel->expected_io)); 1513 1514 /* Children requests return an error status */ 1515 bdev->optimal_io_boundary = 16; 1516 iov[0].iov_base = (void *)0x10000; 1517 iov[0].iov_len = 512 * 64; 1518 g_io_exp_status = SPDK_BDEV_IO_STATUS_FAILED; 1519 g_io_done = false; 1520 g_io_status = SPDK_BDEV_IO_STATUS_SUCCESS; 1521 1522 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, 1, 1, 64, io_done, NULL); 1523 CU_ASSERT(rc == 0); 1524 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 5); 1525 stub_complete_io(4); 1526 CU_ASSERT(g_io_done == false); 1527 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 1528 stub_complete_io(1); 1529 CU_ASSERT(g_io_done == true); 1530 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_FAILED); 1531 1532 /* for this test we will create the following conditions to hit the code path where 1533 * we are trying to send and IO following a split that has no iovs because we had to 1534 * trim them for alignment reasons. 1535 * 1536 * - 16K boundary, our IO will start at offset 0 with a length of 0x4200 1537 * - Our IOVs are 0x212 in size so that we run into the 16K boundary at child IOV 1538 * position 30 and overshoot by 0x2e. 1539 * - That means we'll send the IO and loop back to pick up the remaining bytes at 1540 * child IOV index 31. When we do, we find that we have to shorten index 31 by 0x2e 1541 * which eliniates that vector so we just send the first split IO with 30 vectors 1542 * and let the completion pick up the last 2 vectors. 1543 */ 1544 bdev->optimal_io_boundary = 32; 1545 bdev->split_on_optimal_io_boundary = true; 1546 g_io_done = false; 1547 1548 /* Init all parent IOVs to 0x212 */ 1549 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV + 2; i++) { 1550 iov[i].iov_base = (void *)((i + 1) * 0x10000); 1551 iov[i].iov_len = 0x212; 1552 } 1553 1554 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 0, BDEV_IO_NUM_CHILD_IOV, 1555 BDEV_IO_NUM_CHILD_IOV - 1); 1556 /* expect 0-29 to be 1:1 with the parent iov */ 1557 for (i = 0; i < BDEV_IO_NUM_CHILD_IOV - 2; i++) { 1558 ut_expected_io_set_iov(expected_io, i, iov[i].iov_base, iov[i].iov_len); 1559 } 1560 1561 /* expect index 30 to be shortened to 0x1e4 (0x212 - 0x1e) because of the alignment 1562 * where 0x1e is the amount we overshot the 16K boundary 1563 */ 1564 ut_expected_io_set_iov(expected_io, BDEV_IO_NUM_CHILD_IOV - 2, 1565 (void *)(iov[BDEV_IO_NUM_CHILD_IOV - 2].iov_base), 0x1e4); 1566 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1567 1568 /* 2nd child IO will have 2 remaining vectors, one to pick up from the one that was 1569 * shortened that take it to the next boundary and then a final one to get us to 1570 * 0x4200 bytes for the IO. 1571 */ 1572 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, BDEV_IO_NUM_CHILD_IOV, 1573 BDEV_IO_NUM_CHILD_IOV, 2); 1574 /* position 30 picked up the remaining bytes to the next boundary */ 1575 ut_expected_io_set_iov(expected_io, 0, 1576 (void *)(iov[BDEV_IO_NUM_CHILD_IOV - 2].iov_base + 0x1e4), 0x2e); 1577 1578 /* position 31 picked the the rest of the trasnfer to get us to 0x4200 */ 1579 ut_expected_io_set_iov(expected_io, 1, 1580 (void *)(iov[BDEV_IO_NUM_CHILD_IOV - 1].iov_base), 0x1d2); 1581 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1582 1583 rc = spdk_bdev_readv_blocks(desc, io_ch, iov, BDEV_IO_NUM_CHILD_IOV + 1, 0, 1584 BDEV_IO_NUM_CHILD_IOV + 1, io_done, NULL); 1585 CU_ASSERT(rc == 0); 1586 CU_ASSERT(g_io_done == false); 1587 1588 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1589 stub_complete_io(1); 1590 CU_ASSERT(g_io_done == false); 1591 1592 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1593 stub_complete_io(1); 1594 CU_ASSERT(g_io_done == true); 1595 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1596 1597 spdk_put_io_channel(io_ch); 1598 spdk_bdev_close(desc); 1599 free_bdev(bdev); 1600 spdk_bdev_finish(bdev_fini_cb, NULL); 1601 poll_threads(); 1602 } 1603 1604 static void 1605 bdev_io_split_with_io_wait(void) 1606 { 1607 struct spdk_bdev *bdev; 1608 struct spdk_bdev_desc *desc = NULL; 1609 struct spdk_io_channel *io_ch; 1610 struct spdk_bdev_channel *channel; 1611 struct spdk_bdev_mgmt_channel *mgmt_ch; 1612 struct spdk_bdev_opts bdev_opts = { 1613 .bdev_io_pool_size = 2, 1614 .bdev_io_cache_size = 1, 1615 }; 1616 struct iovec iov[3]; 1617 struct ut_expected_io *expected_io; 1618 int rc; 1619 1620 rc = spdk_bdev_set_opts(&bdev_opts); 1621 CU_ASSERT(rc == 0); 1622 spdk_bdev_initialize(bdev_init_cb, NULL); 1623 1624 bdev = allocate_bdev("bdev0"); 1625 1626 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 1627 CU_ASSERT(rc == 0); 1628 CU_ASSERT(desc != NULL); 1629 io_ch = spdk_bdev_get_io_channel(desc); 1630 CU_ASSERT(io_ch != NULL); 1631 channel = spdk_io_channel_get_ctx(io_ch); 1632 mgmt_ch = channel->shared_resource->mgmt_ch; 1633 1634 bdev->optimal_io_boundary = 16; 1635 bdev->split_on_optimal_io_boundary = true; 1636 1637 rc = spdk_bdev_read_blocks(desc, io_ch, NULL, 0, 1, io_done, NULL); 1638 CU_ASSERT(rc == 0); 1639 1640 /* Now test that a single-vector command is split correctly. 1641 * Offset 14, length 8, payload 0xF000 1642 * Child - Offset 14, length 2, payload 0xF000 1643 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 1644 * 1645 * Set up the expected values before calling spdk_bdev_read_blocks 1646 */ 1647 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 14, 2, 1); 1648 ut_expected_io_set_iov(expected_io, 0, (void *)0xF000, 2 * 512); 1649 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1650 1651 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, 16, 6, 1); 1652 ut_expected_io_set_iov(expected_io, 0, (void *)(0xF000 + 2 * 512), 6 * 512); 1653 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1654 1655 /* The following children will be submitted sequentially due to the capacity of 1656 * spdk_bdev_io. 1657 */ 1658 1659 /* The first child I/O will be queued to wait until an spdk_bdev_io becomes available */ 1660 rc = spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL); 1661 CU_ASSERT(rc == 0); 1662 CU_ASSERT(!TAILQ_EMPTY(&mgmt_ch->io_wait_queue)); 1663 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1664 1665 /* Completing the first read I/O will submit the first child */ 1666 stub_complete_io(1); 1667 CU_ASSERT(TAILQ_EMPTY(&mgmt_ch->io_wait_queue)); 1668 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1669 1670 /* Completing the first child will submit the second child */ 1671 stub_complete_io(1); 1672 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1673 1674 /* Complete the second child I/O. This should result in our callback getting 1675 * invoked since the parent I/O is now complete. 1676 */ 1677 stub_complete_io(1); 1678 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 0); 1679 1680 /* Now set up a more complex, multi-vector command that needs to be split, 1681 * including splitting iovecs. 1682 */ 1683 iov[0].iov_base = (void *)0x10000; 1684 iov[0].iov_len = 512; 1685 iov[1].iov_base = (void *)0x20000; 1686 iov[1].iov_len = 20 * 512; 1687 iov[2].iov_base = (void *)0x30000; 1688 iov[2].iov_len = 11 * 512; 1689 1690 g_io_done = false; 1691 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 14, 2, 2); 1692 ut_expected_io_set_iov(expected_io, 0, (void *)0x10000, 512); 1693 ut_expected_io_set_iov(expected_io, 1, (void *)0x20000, 512); 1694 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1695 1696 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 16, 16, 1); 1697 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 512), 16 * 512); 1698 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1699 1700 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 32, 14, 2); 1701 ut_expected_io_set_iov(expected_io, 0, (void *)(0x20000 + 17 * 512), 3 * 512); 1702 ut_expected_io_set_iov(expected_io, 1, (void *)0x30000, 11 * 512); 1703 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 1704 1705 rc = spdk_bdev_writev_blocks(desc, io_ch, iov, 3, 14, 32, io_done, NULL); 1706 CU_ASSERT(rc == 0); 1707 CU_ASSERT(g_io_done == false); 1708 1709 /* The following children will be submitted sequentially due to the capacity of 1710 * spdk_bdev_io. 1711 */ 1712 1713 /* Completing the first child will submit the second child */ 1714 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1715 stub_complete_io(1); 1716 CU_ASSERT(g_io_done == false); 1717 1718 /* Completing the second child will submit the third child */ 1719 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1720 stub_complete_io(1); 1721 CU_ASSERT(g_io_done == false); 1722 1723 /* Completing the third child will result in our callback getting invoked 1724 * since the parent I/O is now complete. 1725 */ 1726 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 1); 1727 stub_complete_io(1); 1728 CU_ASSERT(g_io_done == true); 1729 1730 CU_ASSERT(TAILQ_EMPTY(&g_bdev_ut_channel->expected_io)); 1731 1732 spdk_put_io_channel(io_ch); 1733 spdk_bdev_close(desc); 1734 free_bdev(bdev); 1735 spdk_bdev_finish(bdev_fini_cb, NULL); 1736 poll_threads(); 1737 } 1738 1739 static void 1740 bdev_io_alignment(void) 1741 { 1742 struct spdk_bdev *bdev; 1743 struct spdk_bdev_desc *desc = NULL; 1744 struct spdk_io_channel *io_ch; 1745 struct spdk_bdev_opts bdev_opts = { 1746 .bdev_io_pool_size = 20, 1747 .bdev_io_cache_size = 2, 1748 }; 1749 int rc; 1750 void *buf; 1751 struct iovec iovs[2]; 1752 int iovcnt; 1753 uint64_t alignment; 1754 1755 rc = spdk_bdev_set_opts(&bdev_opts); 1756 CU_ASSERT(rc == 0); 1757 spdk_bdev_initialize(bdev_init_cb, NULL); 1758 1759 fn_table.submit_request = stub_submit_request_get_buf; 1760 bdev = allocate_bdev("bdev0"); 1761 1762 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 1763 CU_ASSERT(rc == 0); 1764 CU_ASSERT(desc != NULL); 1765 io_ch = spdk_bdev_get_io_channel(desc); 1766 CU_ASSERT(io_ch != NULL); 1767 1768 /* Create aligned buffer */ 1769 rc = posix_memalign(&buf, 4096, 8192); 1770 SPDK_CU_ASSERT_FATAL(rc == 0); 1771 1772 /* Pass aligned single buffer with no alignment required */ 1773 alignment = 1; 1774 bdev->required_alignment = spdk_u32log2(alignment); 1775 1776 rc = spdk_bdev_write_blocks(desc, io_ch, buf, 0, 1, io_done, NULL); 1777 CU_ASSERT(rc == 0); 1778 stub_complete_io(1); 1779 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1780 alignment)); 1781 1782 rc = spdk_bdev_read_blocks(desc, io_ch, buf, 0, 1, io_done, NULL); 1783 CU_ASSERT(rc == 0); 1784 stub_complete_io(1); 1785 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1786 alignment)); 1787 1788 /* Pass unaligned single buffer with no alignment required */ 1789 alignment = 1; 1790 bdev->required_alignment = spdk_u32log2(alignment); 1791 1792 rc = spdk_bdev_write_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 1793 CU_ASSERT(rc == 0); 1794 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1795 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == buf + 4); 1796 stub_complete_io(1); 1797 1798 rc = spdk_bdev_read_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 1799 CU_ASSERT(rc == 0); 1800 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1801 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == buf + 4); 1802 stub_complete_io(1); 1803 1804 /* Pass unaligned single buffer with 512 alignment required */ 1805 alignment = 512; 1806 bdev->required_alignment = spdk_u32log2(alignment); 1807 1808 rc = spdk_bdev_write_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 1809 CU_ASSERT(rc == 0); 1810 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 1811 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 1812 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1813 alignment)); 1814 stub_complete_io(1); 1815 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1816 1817 rc = spdk_bdev_read_blocks(desc, io_ch, buf + 4, 0, 1, io_done, NULL); 1818 CU_ASSERT(rc == 0); 1819 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 1820 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 1821 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1822 alignment)); 1823 stub_complete_io(1); 1824 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1825 1826 /* Pass unaligned single buffer with 4096 alignment required */ 1827 alignment = 4096; 1828 bdev->required_alignment = spdk_u32log2(alignment); 1829 1830 rc = spdk_bdev_write_blocks(desc, io_ch, buf + 8, 0, 1, io_done, NULL); 1831 CU_ASSERT(rc == 0); 1832 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 1833 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 1834 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1835 alignment)); 1836 stub_complete_io(1); 1837 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1838 1839 rc = spdk_bdev_read_blocks(desc, io_ch, buf + 8, 0, 1, io_done, NULL); 1840 CU_ASSERT(rc == 0); 1841 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 1); 1842 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 1843 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1844 alignment)); 1845 stub_complete_io(1); 1846 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1847 1848 /* Pass aligned iovs with no alignment required */ 1849 alignment = 1; 1850 bdev->required_alignment = spdk_u32log2(alignment); 1851 1852 iovcnt = 1; 1853 iovs[0].iov_base = buf; 1854 iovs[0].iov_len = 512; 1855 1856 rc = spdk_bdev_writev(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1857 CU_ASSERT(rc == 0); 1858 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1859 stub_complete_io(1); 1860 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 1861 1862 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1863 CU_ASSERT(rc == 0); 1864 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1865 stub_complete_io(1); 1866 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 1867 1868 /* Pass unaligned iovs with no alignment required */ 1869 alignment = 1; 1870 bdev->required_alignment = spdk_u32log2(alignment); 1871 1872 iovcnt = 2; 1873 iovs[0].iov_base = buf + 16; 1874 iovs[0].iov_len = 256; 1875 iovs[1].iov_base = buf + 16 + 256 + 32; 1876 iovs[1].iov_len = 256; 1877 1878 rc = spdk_bdev_writev(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1879 CU_ASSERT(rc == 0); 1880 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1881 stub_complete_io(1); 1882 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 1883 1884 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1885 CU_ASSERT(rc == 0); 1886 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1887 stub_complete_io(1); 1888 CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == iovs[0].iov_base); 1889 1890 /* Pass unaligned iov with 2048 alignment required */ 1891 alignment = 2048; 1892 bdev->required_alignment = spdk_u32log2(alignment); 1893 1894 iovcnt = 2; 1895 iovs[0].iov_base = buf + 16; 1896 iovs[0].iov_len = 256; 1897 iovs[1].iov_base = buf + 16 + 256 + 32; 1898 iovs[1].iov_len = 256; 1899 1900 rc = spdk_bdev_writev(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1901 CU_ASSERT(rc == 0); 1902 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == iovcnt); 1903 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 1904 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1905 alignment)); 1906 stub_complete_io(1); 1907 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1908 1909 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1910 CU_ASSERT(rc == 0); 1911 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == iovcnt); 1912 CU_ASSERT(g_bdev_io->u.bdev.iovs == &g_bdev_io->internal.bounce_iov); 1913 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1914 alignment)); 1915 stub_complete_io(1); 1916 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1917 1918 /* Pass iov without allocated buffer without alignment required */ 1919 alignment = 1; 1920 bdev->required_alignment = spdk_u32log2(alignment); 1921 1922 iovcnt = 1; 1923 iovs[0].iov_base = NULL; 1924 iovs[0].iov_len = 0; 1925 1926 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1927 CU_ASSERT(rc == 0); 1928 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1929 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1930 alignment)); 1931 stub_complete_io(1); 1932 1933 /* Pass iov without allocated buffer with 1024 alignment required */ 1934 alignment = 1024; 1935 bdev->required_alignment = spdk_u32log2(alignment); 1936 1937 iovcnt = 1; 1938 iovs[0].iov_base = NULL; 1939 iovs[0].iov_len = 0; 1940 1941 rc = spdk_bdev_readv(desc, io_ch, iovs, iovcnt, 0, 512, io_done, NULL); 1942 CU_ASSERT(rc == 0); 1943 CU_ASSERT(g_bdev_io->internal.orig_iovcnt == 0); 1944 CU_ASSERT(_are_iovs_aligned(g_bdev_io->u.bdev.iovs, g_bdev_io->u.bdev.iovcnt, 1945 alignment)); 1946 stub_complete_io(1); 1947 1948 spdk_put_io_channel(io_ch); 1949 spdk_bdev_close(desc); 1950 free_bdev(bdev); 1951 fn_table.submit_request = stub_submit_request; 1952 spdk_bdev_finish(bdev_fini_cb, NULL); 1953 poll_threads(); 1954 1955 free(buf); 1956 } 1957 1958 static void 1959 bdev_io_alignment_with_boundary(void) 1960 { 1961 struct spdk_bdev *bdev; 1962 struct spdk_bdev_desc *desc = NULL; 1963 struct spdk_io_channel *io_ch; 1964 struct spdk_bdev_opts bdev_opts = { 1965 .bdev_io_pool_size = 20, 1966 .bdev_io_cache_size = 2, 1967 }; 1968 int rc; 1969 void *buf; 1970 struct iovec iovs[2]; 1971 int iovcnt; 1972 uint64_t alignment; 1973 1974 rc = spdk_bdev_set_opts(&bdev_opts); 1975 CU_ASSERT(rc == 0); 1976 spdk_bdev_initialize(bdev_init_cb, NULL); 1977 1978 fn_table.submit_request = stub_submit_request_get_buf; 1979 bdev = allocate_bdev("bdev0"); 1980 1981 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 1982 CU_ASSERT(rc == 0); 1983 CU_ASSERT(desc != NULL); 1984 io_ch = spdk_bdev_get_io_channel(desc); 1985 CU_ASSERT(io_ch != NULL); 1986 1987 /* Create aligned buffer */ 1988 rc = posix_memalign(&buf, 4096, 131072); 1989 SPDK_CU_ASSERT_FATAL(rc == 0); 1990 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 1991 1992 /* 512 * 3 with 2 IO boundary, allocate small data buffer from bdev layer */ 1993 alignment = 512; 1994 bdev->required_alignment = spdk_u32log2(alignment); 1995 bdev->optimal_io_boundary = 2; 1996 bdev->split_on_optimal_io_boundary = true; 1997 1998 iovcnt = 1; 1999 iovs[0].iov_base = NULL; 2000 iovs[0].iov_len = 512 * 3; 2001 2002 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 3, io_done, NULL); 2003 CU_ASSERT(rc == 0); 2004 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2005 stub_complete_io(2); 2006 2007 /* 8KiB with 16 IO boundary, allocate large data buffer from bdev layer */ 2008 alignment = 512; 2009 bdev->required_alignment = spdk_u32log2(alignment); 2010 bdev->optimal_io_boundary = 16; 2011 bdev->split_on_optimal_io_boundary = true; 2012 2013 iovcnt = 1; 2014 iovs[0].iov_base = NULL; 2015 iovs[0].iov_len = 512 * 16; 2016 2017 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 16, io_done, NULL); 2018 CU_ASSERT(rc == 0); 2019 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2020 stub_complete_io(2); 2021 2022 /* 512 * 160 with 128 IO boundary, 63.5KiB + 16.5KiB for the two children requests */ 2023 alignment = 512; 2024 bdev->required_alignment = spdk_u32log2(alignment); 2025 bdev->optimal_io_boundary = 128; 2026 bdev->split_on_optimal_io_boundary = true; 2027 2028 iovcnt = 1; 2029 iovs[0].iov_base = buf + 16; 2030 iovs[0].iov_len = 512 * 160; 2031 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 160, io_done, NULL); 2032 CU_ASSERT(rc == 0); 2033 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2034 stub_complete_io(2); 2035 2036 /* 512 * 3 with 2 IO boundary */ 2037 alignment = 512; 2038 bdev->required_alignment = spdk_u32log2(alignment); 2039 bdev->optimal_io_boundary = 2; 2040 bdev->split_on_optimal_io_boundary = true; 2041 2042 iovcnt = 2; 2043 iovs[0].iov_base = buf + 16; 2044 iovs[0].iov_len = 512; 2045 iovs[1].iov_base = buf + 16 + 512 + 32; 2046 iovs[1].iov_len = 1024; 2047 2048 rc = spdk_bdev_writev_blocks(desc, io_ch, iovs, iovcnt, 1, 3, io_done, NULL); 2049 CU_ASSERT(rc == 0); 2050 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2051 stub_complete_io(2); 2052 2053 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 3, io_done, NULL); 2054 CU_ASSERT(rc == 0); 2055 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 2); 2056 stub_complete_io(2); 2057 2058 /* 512 * 64 with 32 IO boundary */ 2059 bdev->optimal_io_boundary = 32; 2060 iovcnt = 2; 2061 iovs[0].iov_base = buf + 16; 2062 iovs[0].iov_len = 16384; 2063 iovs[1].iov_base = buf + 16 + 16384 + 32; 2064 iovs[1].iov_len = 16384; 2065 2066 rc = spdk_bdev_writev_blocks(desc, io_ch, iovs, iovcnt, 1, 64, io_done, NULL); 2067 CU_ASSERT(rc == 0); 2068 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 2069 stub_complete_io(3); 2070 2071 rc = spdk_bdev_readv_blocks(desc, io_ch, iovs, iovcnt, 1, 64, io_done, NULL); 2072 CU_ASSERT(rc == 0); 2073 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 3); 2074 stub_complete_io(3); 2075 2076 /* 512 * 160 with 32 IO boundary */ 2077 iovcnt = 1; 2078 iovs[0].iov_base = buf + 16; 2079 iovs[0].iov_len = 16384 + 65536; 2080 2081 rc = spdk_bdev_writev_blocks(desc, io_ch, iovs, iovcnt, 1, 160, io_done, NULL); 2082 CU_ASSERT(rc == 0); 2083 CU_ASSERT(g_bdev_ut_channel->outstanding_io_count == 6); 2084 stub_complete_io(6); 2085 2086 spdk_put_io_channel(io_ch); 2087 spdk_bdev_close(desc); 2088 free_bdev(bdev); 2089 fn_table.submit_request = stub_submit_request; 2090 spdk_bdev_finish(bdev_fini_cb, NULL); 2091 poll_threads(); 2092 2093 free(buf); 2094 } 2095 2096 static void 2097 histogram_status_cb(void *cb_arg, int status) 2098 { 2099 g_status = status; 2100 } 2101 2102 static void 2103 histogram_data_cb(void *cb_arg, int status, struct spdk_histogram_data *histogram) 2104 { 2105 g_status = status; 2106 g_histogram = histogram; 2107 } 2108 2109 static void 2110 histogram_io_count(void *ctx, uint64_t start, uint64_t end, uint64_t count, 2111 uint64_t total, uint64_t so_far) 2112 { 2113 g_count += count; 2114 } 2115 2116 static void 2117 bdev_histograms(void) 2118 { 2119 struct spdk_bdev *bdev; 2120 struct spdk_bdev_desc *desc = NULL; 2121 struct spdk_io_channel *ch; 2122 struct spdk_histogram_data *histogram; 2123 uint8_t buf[4096]; 2124 int rc; 2125 2126 spdk_bdev_initialize(bdev_init_cb, NULL); 2127 2128 bdev = allocate_bdev("bdev"); 2129 2130 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2131 CU_ASSERT(rc == 0); 2132 CU_ASSERT(desc != NULL); 2133 2134 ch = spdk_bdev_get_io_channel(desc); 2135 CU_ASSERT(ch != NULL); 2136 2137 /* Enable histogram */ 2138 g_status = -1; 2139 spdk_bdev_histogram_enable(bdev, histogram_status_cb, NULL, true); 2140 poll_threads(); 2141 CU_ASSERT(g_status == 0); 2142 CU_ASSERT(bdev->internal.histogram_enabled == true); 2143 2144 /* Allocate histogram */ 2145 histogram = spdk_histogram_data_alloc(); 2146 SPDK_CU_ASSERT_FATAL(histogram != NULL); 2147 2148 /* Check if histogram is zeroed */ 2149 spdk_bdev_histogram_get(bdev, histogram, histogram_data_cb, NULL); 2150 poll_threads(); 2151 CU_ASSERT(g_status == 0); 2152 SPDK_CU_ASSERT_FATAL(g_histogram != NULL); 2153 2154 g_count = 0; 2155 spdk_histogram_data_iterate(g_histogram, histogram_io_count, NULL); 2156 2157 CU_ASSERT(g_count == 0); 2158 2159 rc = spdk_bdev_write_blocks(desc, ch, buf, 0, 1, io_done, NULL); 2160 CU_ASSERT(rc == 0); 2161 2162 spdk_delay_us(10); 2163 stub_complete_io(1); 2164 poll_threads(); 2165 2166 rc = spdk_bdev_read_blocks(desc, ch, buf, 0, 1, io_done, NULL); 2167 CU_ASSERT(rc == 0); 2168 2169 spdk_delay_us(10); 2170 stub_complete_io(1); 2171 poll_threads(); 2172 2173 /* Check if histogram gathered data from all I/O channels */ 2174 g_histogram = NULL; 2175 spdk_bdev_histogram_get(bdev, histogram, histogram_data_cb, NULL); 2176 poll_threads(); 2177 CU_ASSERT(g_status == 0); 2178 CU_ASSERT(bdev->internal.histogram_enabled == true); 2179 SPDK_CU_ASSERT_FATAL(g_histogram != NULL); 2180 2181 g_count = 0; 2182 spdk_histogram_data_iterate(g_histogram, histogram_io_count, NULL); 2183 CU_ASSERT(g_count == 2); 2184 2185 /* Disable histogram */ 2186 spdk_bdev_histogram_enable(bdev, histogram_status_cb, NULL, false); 2187 poll_threads(); 2188 CU_ASSERT(g_status == 0); 2189 CU_ASSERT(bdev->internal.histogram_enabled == false); 2190 2191 /* Try to run histogram commands on disabled bdev */ 2192 spdk_bdev_histogram_get(bdev, histogram, histogram_data_cb, NULL); 2193 poll_threads(); 2194 CU_ASSERT(g_status == -EFAULT); 2195 2196 spdk_histogram_data_free(histogram); 2197 spdk_put_io_channel(ch); 2198 spdk_bdev_close(desc); 2199 free_bdev(bdev); 2200 spdk_bdev_finish(bdev_fini_cb, NULL); 2201 poll_threads(); 2202 } 2203 2204 static void 2205 _bdev_compare(bool emulated) 2206 { 2207 struct spdk_bdev *bdev; 2208 struct spdk_bdev_desc *desc = NULL; 2209 struct spdk_io_channel *ioch; 2210 struct ut_expected_io *expected_io; 2211 uint64_t offset, num_blocks; 2212 uint32_t num_completed; 2213 char aa_buf[512]; 2214 char bb_buf[512]; 2215 struct iovec compare_iov; 2216 uint8_t io_type; 2217 int rc; 2218 2219 if (emulated) { 2220 io_type = SPDK_BDEV_IO_TYPE_READ; 2221 } else { 2222 io_type = SPDK_BDEV_IO_TYPE_COMPARE; 2223 } 2224 2225 memset(aa_buf, 0xaa, sizeof(aa_buf)); 2226 memset(bb_buf, 0xbb, sizeof(bb_buf)); 2227 2228 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = !emulated; 2229 2230 spdk_bdev_initialize(bdev_init_cb, NULL); 2231 fn_table.submit_request = stub_submit_request_get_buf; 2232 bdev = allocate_bdev("bdev"); 2233 2234 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2235 CU_ASSERT_EQUAL(rc, 0); 2236 SPDK_CU_ASSERT_FATAL(desc != NULL); 2237 ioch = spdk_bdev_get_io_channel(desc); 2238 SPDK_CU_ASSERT_FATAL(ioch != NULL); 2239 2240 fn_table.submit_request = stub_submit_request_get_buf; 2241 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 2242 2243 offset = 50; 2244 num_blocks = 1; 2245 compare_iov.iov_base = aa_buf; 2246 compare_iov.iov_len = sizeof(aa_buf); 2247 2248 expected_io = ut_alloc_expected_io(io_type, offset, num_blocks, 0); 2249 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2250 2251 g_io_done = false; 2252 g_compare_read_buf = aa_buf; 2253 g_compare_read_buf_len = sizeof(aa_buf); 2254 rc = spdk_bdev_comparev_blocks(desc, ioch, &compare_iov, 1, offset, num_blocks, io_done, NULL); 2255 CU_ASSERT_EQUAL(rc, 0); 2256 num_completed = stub_complete_io(1); 2257 CU_ASSERT_EQUAL(num_completed, 1); 2258 CU_ASSERT(g_io_done == true); 2259 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 2260 2261 expected_io = ut_alloc_expected_io(io_type, offset, num_blocks, 0); 2262 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2263 2264 g_io_done = false; 2265 g_compare_read_buf = bb_buf; 2266 g_compare_read_buf_len = sizeof(bb_buf); 2267 rc = spdk_bdev_comparev_blocks(desc, ioch, &compare_iov, 1, offset, num_blocks, io_done, NULL); 2268 CU_ASSERT_EQUAL(rc, 0); 2269 num_completed = stub_complete_io(1); 2270 CU_ASSERT_EQUAL(num_completed, 1); 2271 CU_ASSERT(g_io_done == true); 2272 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_MISCOMPARE); 2273 2274 spdk_put_io_channel(ioch); 2275 spdk_bdev_close(desc); 2276 free_bdev(bdev); 2277 fn_table.submit_request = stub_submit_request; 2278 spdk_bdev_finish(bdev_fini_cb, NULL); 2279 poll_threads(); 2280 2281 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = true; 2282 2283 g_compare_read_buf = NULL; 2284 } 2285 2286 static void 2287 bdev_compare(void) 2288 { 2289 _bdev_compare(true); 2290 _bdev_compare(false); 2291 } 2292 2293 static void 2294 bdev_compare_and_write(void) 2295 { 2296 struct spdk_bdev *bdev; 2297 struct spdk_bdev_desc *desc = NULL; 2298 struct spdk_io_channel *ioch; 2299 struct ut_expected_io *expected_io; 2300 uint64_t offset, num_blocks; 2301 uint32_t num_completed; 2302 char aa_buf[512]; 2303 char bb_buf[512]; 2304 char cc_buf[512]; 2305 char write_buf[512]; 2306 struct iovec compare_iov; 2307 struct iovec write_iov; 2308 int rc; 2309 2310 memset(aa_buf, 0xaa, sizeof(aa_buf)); 2311 memset(bb_buf, 0xbb, sizeof(bb_buf)); 2312 memset(cc_buf, 0xcc, sizeof(cc_buf)); 2313 2314 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = false; 2315 2316 spdk_bdev_initialize(bdev_init_cb, NULL); 2317 fn_table.submit_request = stub_submit_request_get_buf; 2318 bdev = allocate_bdev("bdev"); 2319 2320 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2321 CU_ASSERT_EQUAL(rc, 0); 2322 SPDK_CU_ASSERT_FATAL(desc != NULL); 2323 ioch = spdk_bdev_get_io_channel(desc); 2324 SPDK_CU_ASSERT_FATAL(ioch != NULL); 2325 2326 fn_table.submit_request = stub_submit_request_get_buf; 2327 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 2328 2329 offset = 50; 2330 num_blocks = 1; 2331 compare_iov.iov_base = aa_buf; 2332 compare_iov.iov_len = sizeof(aa_buf); 2333 write_iov.iov_base = bb_buf; 2334 write_iov.iov_len = sizeof(bb_buf); 2335 2336 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset, num_blocks, 0); 2337 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2338 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, offset, num_blocks, 0); 2339 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2340 2341 g_io_done = false; 2342 g_compare_read_buf = aa_buf; 2343 g_compare_read_buf_len = sizeof(aa_buf); 2344 memset(write_buf, 0, sizeof(write_buf)); 2345 g_compare_write_buf = write_buf; 2346 g_compare_write_buf_len = sizeof(write_buf); 2347 rc = spdk_bdev_comparev_and_writev_blocks(desc, ioch, &compare_iov, 1, &write_iov, 1, 2348 offset, num_blocks, io_done, NULL); 2349 /* Trigger range locking */ 2350 poll_threads(); 2351 CU_ASSERT_EQUAL(rc, 0); 2352 num_completed = stub_complete_io(1); 2353 CU_ASSERT_EQUAL(num_completed, 1); 2354 CU_ASSERT(g_io_done == false); 2355 num_completed = stub_complete_io(1); 2356 /* Trigger range unlocking */ 2357 poll_threads(); 2358 CU_ASSERT_EQUAL(num_completed, 1); 2359 CU_ASSERT(g_io_done == true); 2360 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_SUCCESS); 2361 CU_ASSERT(memcmp(write_buf, bb_buf, sizeof(write_buf)) == 0); 2362 2363 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_READ, offset, num_blocks, 0); 2364 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2365 2366 g_io_done = false; 2367 g_compare_read_buf = cc_buf; 2368 g_compare_read_buf_len = sizeof(cc_buf); 2369 memset(write_buf, 0, sizeof(write_buf)); 2370 g_compare_write_buf = write_buf; 2371 g_compare_write_buf_len = sizeof(write_buf); 2372 rc = spdk_bdev_comparev_and_writev_blocks(desc, ioch, &compare_iov, 1, &write_iov, 1, 2373 offset, num_blocks, io_done, NULL); 2374 /* Trigger range locking */ 2375 poll_threads(); 2376 CU_ASSERT_EQUAL(rc, 0); 2377 num_completed = stub_complete_io(1); 2378 /* Trigger range unlocking earlier because we expect error here */ 2379 poll_threads(); 2380 CU_ASSERT_EQUAL(num_completed, 1); 2381 CU_ASSERT(g_io_done == true); 2382 CU_ASSERT(g_io_status == SPDK_BDEV_IO_STATUS_MISCOMPARE); 2383 num_completed = stub_complete_io(1); 2384 CU_ASSERT_EQUAL(num_completed, 0); 2385 2386 spdk_put_io_channel(ioch); 2387 spdk_bdev_close(desc); 2388 free_bdev(bdev); 2389 fn_table.submit_request = stub_submit_request; 2390 spdk_bdev_finish(bdev_fini_cb, NULL); 2391 poll_threads(); 2392 2393 g_io_types_supported[SPDK_BDEV_IO_TYPE_COMPARE] = true; 2394 2395 g_compare_read_buf = NULL; 2396 g_compare_write_buf = NULL; 2397 } 2398 2399 static void 2400 bdev_write_zeroes(void) 2401 { 2402 struct spdk_bdev *bdev; 2403 struct spdk_bdev_desc *desc = NULL; 2404 struct spdk_io_channel *ioch; 2405 struct ut_expected_io *expected_io; 2406 uint64_t offset, num_io_blocks, num_blocks; 2407 uint32_t num_completed, num_requests; 2408 int rc; 2409 2410 spdk_bdev_initialize(bdev_init_cb, NULL); 2411 bdev = allocate_bdev("bdev"); 2412 2413 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2414 CU_ASSERT_EQUAL(rc, 0); 2415 SPDK_CU_ASSERT_FATAL(desc != NULL); 2416 ioch = spdk_bdev_get_io_channel(desc); 2417 SPDK_CU_ASSERT_FATAL(ioch != NULL); 2418 2419 fn_table.submit_request = stub_submit_request; 2420 g_io_exp_status = SPDK_BDEV_IO_STATUS_SUCCESS; 2421 2422 /* First test that if the bdev supports write_zeroes, the request won't be split */ 2423 bdev->md_len = 0; 2424 bdev->blocklen = 4096; 2425 num_blocks = (ZERO_BUFFER_SIZE / bdev->blocklen) * 2; 2426 2427 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, 0, num_blocks, 0); 2428 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2429 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 2430 CU_ASSERT_EQUAL(rc, 0); 2431 num_completed = stub_complete_io(1); 2432 CU_ASSERT_EQUAL(num_completed, 1); 2433 2434 /* Check that if write zeroes is not supported it'll be replaced by regular writes */ 2435 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, false); 2436 num_io_blocks = ZERO_BUFFER_SIZE / bdev->blocklen; 2437 num_requests = 2; 2438 num_blocks = (ZERO_BUFFER_SIZE / bdev->blocklen) * num_requests; 2439 2440 for (offset = 0; offset < num_requests; ++offset) { 2441 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 2442 offset * num_io_blocks, num_io_blocks, 0); 2443 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2444 } 2445 2446 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 2447 CU_ASSERT_EQUAL(rc, 0); 2448 num_completed = stub_complete_io(num_requests); 2449 CU_ASSERT_EQUAL(num_completed, num_requests); 2450 2451 /* Check that the splitting is correct if bdev has interleaved metadata */ 2452 bdev->md_interleave = true; 2453 bdev->md_len = 64; 2454 bdev->blocklen = 4096 + 64; 2455 num_blocks = (ZERO_BUFFER_SIZE / bdev->blocklen) * 2; 2456 2457 num_requests = offset = 0; 2458 while (offset < num_blocks) { 2459 num_io_blocks = spdk_min(ZERO_BUFFER_SIZE / bdev->blocklen, num_blocks - offset); 2460 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 2461 offset, num_io_blocks, 0); 2462 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2463 offset += num_io_blocks; 2464 num_requests++; 2465 } 2466 2467 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 2468 CU_ASSERT_EQUAL(rc, 0); 2469 num_completed = stub_complete_io(num_requests); 2470 CU_ASSERT_EQUAL(num_completed, num_requests); 2471 num_completed = stub_complete_io(num_requests); 2472 assert(num_completed == 0); 2473 2474 /* Check the the same for separate metadata buffer */ 2475 bdev->md_interleave = false; 2476 bdev->md_len = 64; 2477 bdev->blocklen = 4096; 2478 2479 num_requests = offset = 0; 2480 while (offset < num_blocks) { 2481 num_io_blocks = spdk_min(ZERO_BUFFER_SIZE / (bdev->blocklen + bdev->md_len), num_blocks); 2482 expected_io = ut_alloc_expected_io(SPDK_BDEV_IO_TYPE_WRITE, 2483 offset, num_io_blocks, 0); 2484 expected_io->md_buf = (char *)g_bdev_mgr.zero_buffer + num_io_blocks * bdev->blocklen; 2485 TAILQ_INSERT_TAIL(&g_bdev_ut_channel->expected_io, expected_io, link); 2486 offset += num_io_blocks; 2487 num_requests++; 2488 } 2489 2490 rc = spdk_bdev_write_zeroes_blocks(desc, ioch, 0, num_blocks, io_done, NULL); 2491 CU_ASSERT_EQUAL(rc, 0); 2492 num_completed = stub_complete_io(num_requests); 2493 CU_ASSERT_EQUAL(num_completed, num_requests); 2494 2495 ut_enable_io_type(SPDK_BDEV_IO_TYPE_WRITE_ZEROES, true); 2496 spdk_put_io_channel(ioch); 2497 spdk_bdev_close(desc); 2498 free_bdev(bdev); 2499 spdk_bdev_finish(bdev_fini_cb, NULL); 2500 poll_threads(); 2501 } 2502 2503 static void 2504 bdev_open_while_hotremove(void) 2505 { 2506 struct spdk_bdev *bdev; 2507 struct spdk_bdev_desc *desc[2] = {}; 2508 int rc; 2509 2510 bdev = allocate_bdev("bdev"); 2511 2512 rc = spdk_bdev_open(bdev, false, NULL, NULL, &desc[0]); 2513 CU_ASSERT(rc == 0); 2514 SPDK_CU_ASSERT_FATAL(desc[0] != NULL); 2515 2516 spdk_bdev_unregister(bdev, NULL, NULL); 2517 2518 rc = spdk_bdev_open(bdev, false, NULL, NULL, &desc[1]); 2519 CU_ASSERT(rc == -ENODEV); 2520 SPDK_CU_ASSERT_FATAL(desc[1] == NULL); 2521 2522 spdk_bdev_close(desc[0]); 2523 free_bdev(bdev); 2524 } 2525 2526 static void 2527 bdev_close_while_hotremove(void) 2528 { 2529 struct spdk_bdev *bdev; 2530 struct spdk_bdev_desc *desc = NULL; 2531 int rc = 0; 2532 2533 bdev = allocate_bdev("bdev"); 2534 2535 rc = spdk_bdev_open_ext("bdev", true, bdev_open_cb1, &desc, &desc); 2536 CU_ASSERT_EQUAL(rc, 0); 2537 2538 /* Simulate hot-unplug by unregistering bdev */ 2539 g_event_type1 = 0xFF; 2540 g_unregister_arg = NULL; 2541 g_unregister_rc = -1; 2542 spdk_bdev_unregister(bdev, bdev_unregister_cb, (void *)0x12345678); 2543 /* Close device while remove event is in flight */ 2544 spdk_bdev_close(desc); 2545 2546 /* Ensure that unregister callback is delayed */ 2547 CU_ASSERT_EQUAL(g_unregister_arg, NULL); 2548 CU_ASSERT_EQUAL(g_unregister_rc, -1); 2549 2550 poll_threads(); 2551 2552 /* Event callback shall not be issued because device was closed */ 2553 CU_ASSERT_EQUAL(g_event_type1, 0xFF); 2554 /* Unregister callback is issued */ 2555 CU_ASSERT_EQUAL(g_unregister_arg, (void *)0x12345678); 2556 CU_ASSERT_EQUAL(g_unregister_rc, 0); 2557 2558 free_bdev(bdev); 2559 } 2560 2561 static void 2562 bdev_open_ext(void) 2563 { 2564 struct spdk_bdev *bdev; 2565 struct spdk_bdev_desc *desc1 = NULL; 2566 struct spdk_bdev_desc *desc2 = NULL; 2567 int rc = 0; 2568 2569 bdev = allocate_bdev("bdev"); 2570 2571 rc = spdk_bdev_open_ext("bdev", true, NULL, NULL, &desc1); 2572 CU_ASSERT_EQUAL(rc, -EINVAL); 2573 2574 rc = spdk_bdev_open_ext("bdev", true, bdev_open_cb1, &desc1, &desc1); 2575 CU_ASSERT_EQUAL(rc, 0); 2576 2577 rc = spdk_bdev_open_ext("bdev", true, bdev_open_cb2, &desc2, &desc2); 2578 CU_ASSERT_EQUAL(rc, 0); 2579 2580 g_event_type1 = 0xFF; 2581 g_event_type2 = 0xFF; 2582 2583 /* Simulate hot-unplug by unregistering bdev */ 2584 spdk_bdev_unregister(bdev, NULL, NULL); 2585 poll_threads(); 2586 2587 /* Check if correct events have been triggered in event callback fn */ 2588 CU_ASSERT_EQUAL(g_event_type1, SPDK_BDEV_EVENT_REMOVE); 2589 CU_ASSERT_EQUAL(g_event_type2, SPDK_BDEV_EVENT_REMOVE); 2590 2591 free_bdev(bdev); 2592 poll_threads(); 2593 } 2594 2595 struct timeout_io_cb_arg { 2596 struct iovec iov; 2597 uint8_t type; 2598 }; 2599 2600 static int 2601 bdev_channel_count_submitted_io(struct spdk_bdev_channel *ch) 2602 { 2603 struct spdk_bdev_io *bdev_io; 2604 int n = 0; 2605 2606 if (!ch) { 2607 return -1; 2608 } 2609 2610 TAILQ_FOREACH(bdev_io, &ch->io_submitted, internal.ch_link) { 2611 n++; 2612 } 2613 2614 return n; 2615 } 2616 2617 static void 2618 bdev_channel_io_timeout_cb(void *cb_arg, struct spdk_bdev_io *bdev_io) 2619 { 2620 struct timeout_io_cb_arg *ctx = cb_arg; 2621 2622 ctx->type = bdev_io->type; 2623 ctx->iov.iov_base = bdev_io->iov.iov_base; 2624 ctx->iov.iov_len = bdev_io->iov.iov_len; 2625 } 2626 2627 static void 2628 bdev_set_io_timeout(void) 2629 { 2630 struct spdk_bdev *bdev; 2631 struct spdk_bdev_desc *desc = NULL; 2632 struct spdk_io_channel *io_ch = NULL; 2633 struct spdk_bdev_channel *bdev_ch = NULL; 2634 struct timeout_io_cb_arg cb_arg; 2635 2636 spdk_bdev_initialize(bdev_init_cb, NULL); 2637 2638 bdev = allocate_bdev("bdev"); 2639 2640 CU_ASSERT(spdk_bdev_open(bdev, true, NULL, NULL, &desc) == 0); 2641 SPDK_CU_ASSERT_FATAL(desc != NULL); 2642 io_ch = spdk_bdev_get_io_channel(desc); 2643 CU_ASSERT(io_ch != NULL); 2644 2645 bdev_ch = spdk_io_channel_get_ctx(io_ch); 2646 CU_ASSERT(TAILQ_EMPTY(&bdev_ch->io_submitted)); 2647 2648 /* This is the part1. 2649 * We will check the bdev_ch->io_submitted list 2650 * TO make sure that it can link IOs and only the user submitted IOs 2651 */ 2652 CU_ASSERT(spdk_bdev_read(desc, io_ch, (void *)0x1000, 0, 4096, io_done, NULL) == 0); 2653 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 2654 CU_ASSERT(spdk_bdev_write(desc, io_ch, (void *)0x2000, 0, 4096, io_done, NULL) == 0); 2655 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 2); 2656 stub_complete_io(1); 2657 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 2658 stub_complete_io(1); 2659 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0); 2660 2661 /* Split IO */ 2662 bdev->optimal_io_boundary = 16; 2663 bdev->split_on_optimal_io_boundary = true; 2664 2665 /* Now test that a single-vector command is split correctly. 2666 * Offset 14, length 8, payload 0xF000 2667 * Child - Offset 14, length 2, payload 0xF000 2668 * Child - Offset 16, length 6, payload 0xF000 + 2 * 512 2669 * 2670 * Set up the expected values before calling spdk_bdev_read_blocks 2671 */ 2672 CU_ASSERT(spdk_bdev_read_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL) == 0); 2673 /* We only count the submitted IO by the user 2674 * Even the IO split into two IOs but we only count one. 2675 * Becauce the user only see one IO. 2676 */ 2677 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 2678 stub_complete_io(1); 2679 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 2680 stub_complete_io(1); 2681 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0); 2682 2683 /* Also include the reset IO */ 2684 CU_ASSERT(spdk_bdev_reset(desc, io_ch, io_done, NULL) == 0); 2685 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 1); 2686 poll_threads(); 2687 stub_complete_io(1); 2688 poll_threads(); 2689 CU_ASSERT(bdev_channel_count_submitted_io(bdev_ch) == 0); 2690 2691 /* This is part2 2692 * Test the desc timeout poller register 2693 */ 2694 2695 /* Successfully set the timeout */ 2696 CU_ASSERT(spdk_bdev_set_timeout(desc, 30, bdev_channel_io_timeout_cb, &cb_arg) == 0); 2697 CU_ASSERT(desc->io_timeout_poller != NULL); 2698 CU_ASSERT(desc->timeout_in_sec == 30); 2699 CU_ASSERT(desc->cb_fn == bdev_channel_io_timeout_cb); 2700 CU_ASSERT(desc->cb_arg == &cb_arg); 2701 2702 /* Change the timeout limit */ 2703 CU_ASSERT(spdk_bdev_set_timeout(desc, 20, bdev_channel_io_timeout_cb, &cb_arg) == 0); 2704 CU_ASSERT(desc->io_timeout_poller != NULL); 2705 CU_ASSERT(desc->timeout_in_sec == 20); 2706 CU_ASSERT(desc->cb_fn == bdev_channel_io_timeout_cb); 2707 CU_ASSERT(desc->cb_arg == &cb_arg); 2708 2709 /* Disable the timeout */ 2710 CU_ASSERT(spdk_bdev_set_timeout(desc, 0, NULL, NULL) == 0); 2711 CU_ASSERT(desc->io_timeout_poller == NULL); 2712 2713 /* This the part3 2714 * We will test to catch timeout IO and check whether the IO is 2715 * the submitted one. 2716 */ 2717 memset(&cb_arg, 0, sizeof(cb_arg)); 2718 CU_ASSERT(spdk_bdev_set_timeout(desc, 30, bdev_channel_io_timeout_cb, &cb_arg) == 0); 2719 CU_ASSERT(spdk_bdev_write_blocks(desc, io_ch, (void *)0x1000, 0, 1, io_done, NULL) == 0); 2720 2721 /* Don't reach the limit */ 2722 spdk_delay_us(15 * spdk_get_ticks_hz()); 2723 poll_threads(); 2724 CU_ASSERT(cb_arg.type == 0); 2725 CU_ASSERT(cb_arg.iov.iov_base == (void *)0x0); 2726 CU_ASSERT(cb_arg.iov.iov_len == 0); 2727 2728 /* 15 + 15 = 30 reach the limit */ 2729 spdk_delay_us(15 * spdk_get_ticks_hz()); 2730 poll_threads(); 2731 CU_ASSERT(cb_arg.type == SPDK_BDEV_IO_TYPE_WRITE); 2732 CU_ASSERT(cb_arg.iov.iov_base == (void *)0x1000); 2733 CU_ASSERT(cb_arg.iov.iov_len == 1 * bdev->blocklen); 2734 stub_complete_io(1); 2735 2736 /* Use the same split IO above and check the IO */ 2737 memset(&cb_arg, 0, sizeof(cb_arg)); 2738 CU_ASSERT(spdk_bdev_write_blocks(desc, io_ch, (void *)0xF000, 14, 8, io_done, NULL) == 0); 2739 2740 /* The first child complete in time */ 2741 spdk_delay_us(15 * spdk_get_ticks_hz()); 2742 poll_threads(); 2743 stub_complete_io(1); 2744 CU_ASSERT(cb_arg.type == 0); 2745 CU_ASSERT(cb_arg.iov.iov_base == (void *)0x0); 2746 CU_ASSERT(cb_arg.iov.iov_len == 0); 2747 2748 /* The second child reach the limit */ 2749 spdk_delay_us(15 * spdk_get_ticks_hz()); 2750 poll_threads(); 2751 CU_ASSERT(cb_arg.type == SPDK_BDEV_IO_TYPE_WRITE); 2752 CU_ASSERT(cb_arg.iov.iov_base == (void *)0xF000); 2753 CU_ASSERT(cb_arg.iov.iov_len == 8 * bdev->blocklen); 2754 stub_complete_io(1); 2755 2756 /* Also include the reset IO */ 2757 memset(&cb_arg, 0, sizeof(cb_arg)); 2758 CU_ASSERT(spdk_bdev_reset(desc, io_ch, io_done, NULL) == 0); 2759 spdk_delay_us(30 * spdk_get_ticks_hz()); 2760 poll_threads(); 2761 CU_ASSERT(cb_arg.type == SPDK_BDEV_IO_TYPE_RESET); 2762 stub_complete_io(1); 2763 poll_threads(); 2764 2765 spdk_put_io_channel(io_ch); 2766 spdk_bdev_close(desc); 2767 free_bdev(bdev); 2768 spdk_bdev_finish(bdev_fini_cb, NULL); 2769 poll_threads(); 2770 } 2771 2772 static void 2773 lba_range_overlap(void) 2774 { 2775 struct lba_range r1, r2; 2776 2777 r1.offset = 100; 2778 r1.length = 50; 2779 2780 r2.offset = 0; 2781 r2.length = 1; 2782 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 2783 2784 r2.offset = 0; 2785 r2.length = 100; 2786 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 2787 2788 r2.offset = 0; 2789 r2.length = 110; 2790 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 2791 2792 r2.offset = 100; 2793 r2.length = 10; 2794 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 2795 2796 r2.offset = 110; 2797 r2.length = 20; 2798 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 2799 2800 r2.offset = 140; 2801 r2.length = 150; 2802 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 2803 2804 r2.offset = 130; 2805 r2.length = 200; 2806 CU_ASSERT(bdev_lba_range_overlapped(&r1, &r2)); 2807 2808 r2.offset = 150; 2809 r2.length = 100; 2810 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 2811 2812 r2.offset = 110; 2813 r2.length = 0; 2814 CU_ASSERT(!bdev_lba_range_overlapped(&r1, &r2)); 2815 } 2816 2817 static bool g_lock_lba_range_done; 2818 static bool g_unlock_lba_range_done; 2819 2820 static void 2821 lock_lba_range_done(void *ctx, int status) 2822 { 2823 g_lock_lba_range_done = true; 2824 } 2825 2826 static void 2827 unlock_lba_range_done(void *ctx, int status) 2828 { 2829 g_unlock_lba_range_done = true; 2830 } 2831 2832 static void 2833 lock_lba_range_check_ranges(void) 2834 { 2835 struct spdk_bdev *bdev; 2836 struct spdk_bdev_desc *desc = NULL; 2837 struct spdk_io_channel *io_ch; 2838 struct spdk_bdev_channel *channel; 2839 struct lba_range *range; 2840 int ctx1; 2841 int rc; 2842 2843 spdk_bdev_initialize(bdev_init_cb, NULL); 2844 2845 bdev = allocate_bdev("bdev0"); 2846 2847 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2848 CU_ASSERT(rc == 0); 2849 CU_ASSERT(desc != NULL); 2850 io_ch = spdk_bdev_get_io_channel(desc); 2851 CU_ASSERT(io_ch != NULL); 2852 channel = spdk_io_channel_get_ctx(io_ch); 2853 2854 g_lock_lba_range_done = false; 2855 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 2856 CU_ASSERT(rc == 0); 2857 poll_threads(); 2858 2859 CU_ASSERT(g_lock_lba_range_done == true); 2860 range = TAILQ_FIRST(&channel->locked_ranges); 2861 SPDK_CU_ASSERT_FATAL(range != NULL); 2862 CU_ASSERT(range->offset == 20); 2863 CU_ASSERT(range->length == 10); 2864 CU_ASSERT(range->owner_ch == channel); 2865 2866 /* Unlocks must exactly match a lock. */ 2867 g_unlock_lba_range_done = false; 2868 rc = bdev_unlock_lba_range(desc, io_ch, 20, 1, unlock_lba_range_done, &ctx1); 2869 CU_ASSERT(rc == -EINVAL); 2870 CU_ASSERT(g_unlock_lba_range_done == false); 2871 2872 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, unlock_lba_range_done, &ctx1); 2873 CU_ASSERT(rc == 0); 2874 spdk_delay_us(100); 2875 poll_threads(); 2876 2877 CU_ASSERT(g_unlock_lba_range_done == true); 2878 CU_ASSERT(TAILQ_EMPTY(&channel->locked_ranges)); 2879 2880 spdk_put_io_channel(io_ch); 2881 spdk_bdev_close(desc); 2882 free_bdev(bdev); 2883 spdk_bdev_finish(bdev_fini_cb, NULL); 2884 poll_threads(); 2885 } 2886 2887 static void 2888 lock_lba_range_with_io_outstanding(void) 2889 { 2890 struct spdk_bdev *bdev; 2891 struct spdk_bdev_desc *desc = NULL; 2892 struct spdk_io_channel *io_ch; 2893 struct spdk_bdev_channel *channel; 2894 struct lba_range *range; 2895 char buf[4096]; 2896 int ctx1; 2897 int rc; 2898 2899 spdk_bdev_initialize(bdev_init_cb, NULL); 2900 2901 bdev = allocate_bdev("bdev0"); 2902 2903 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2904 CU_ASSERT(rc == 0); 2905 CU_ASSERT(desc != NULL); 2906 io_ch = spdk_bdev_get_io_channel(desc); 2907 CU_ASSERT(io_ch != NULL); 2908 channel = spdk_io_channel_get_ctx(io_ch); 2909 2910 g_io_done = false; 2911 rc = spdk_bdev_read_blocks(desc, io_ch, buf, 20, 1, io_done, &ctx1); 2912 CU_ASSERT(rc == 0); 2913 2914 g_lock_lba_range_done = false; 2915 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 2916 CU_ASSERT(rc == 0); 2917 poll_threads(); 2918 2919 /* The lock should immediately become valid, since there are no outstanding 2920 * write I/O. 2921 */ 2922 CU_ASSERT(g_io_done == false); 2923 CU_ASSERT(g_lock_lba_range_done == true); 2924 range = TAILQ_FIRST(&channel->locked_ranges); 2925 SPDK_CU_ASSERT_FATAL(range != NULL); 2926 CU_ASSERT(range->offset == 20); 2927 CU_ASSERT(range->length == 10); 2928 CU_ASSERT(range->owner_ch == channel); 2929 CU_ASSERT(range->locked_ctx == &ctx1); 2930 2931 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 2932 CU_ASSERT(rc == 0); 2933 stub_complete_io(1); 2934 spdk_delay_us(100); 2935 poll_threads(); 2936 2937 CU_ASSERT(TAILQ_EMPTY(&channel->locked_ranges)); 2938 2939 /* Now try again, but with a write I/O. */ 2940 g_io_done = false; 2941 rc = spdk_bdev_write_blocks(desc, io_ch, buf, 20, 1, io_done, &ctx1); 2942 CU_ASSERT(rc == 0); 2943 2944 g_lock_lba_range_done = false; 2945 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 2946 CU_ASSERT(rc == 0); 2947 poll_threads(); 2948 2949 /* The lock should not be fully valid yet, since a write I/O is outstanding. 2950 * But note that the range should be on the channel's locked_list, to make sure no 2951 * new write I/O are started. 2952 */ 2953 CU_ASSERT(g_io_done == false); 2954 CU_ASSERT(g_lock_lba_range_done == false); 2955 range = TAILQ_FIRST(&channel->locked_ranges); 2956 SPDK_CU_ASSERT_FATAL(range != NULL); 2957 CU_ASSERT(range->offset == 20); 2958 CU_ASSERT(range->length == 10); 2959 2960 /* Complete the write I/O. This should make the lock valid (checked by confirming 2961 * our callback was invoked). 2962 */ 2963 stub_complete_io(1); 2964 spdk_delay_us(100); 2965 poll_threads(); 2966 CU_ASSERT(g_io_done == true); 2967 CU_ASSERT(g_lock_lba_range_done == true); 2968 2969 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, unlock_lba_range_done, &ctx1); 2970 CU_ASSERT(rc == 0); 2971 poll_threads(); 2972 2973 CU_ASSERT(TAILQ_EMPTY(&channel->locked_ranges)); 2974 2975 spdk_put_io_channel(io_ch); 2976 spdk_bdev_close(desc); 2977 free_bdev(bdev); 2978 spdk_bdev_finish(bdev_fini_cb, NULL); 2979 poll_threads(); 2980 } 2981 2982 static void 2983 lock_lba_range_overlapped(void) 2984 { 2985 struct spdk_bdev *bdev; 2986 struct spdk_bdev_desc *desc = NULL; 2987 struct spdk_io_channel *io_ch; 2988 struct spdk_bdev_channel *channel; 2989 struct lba_range *range; 2990 int ctx1; 2991 int rc; 2992 2993 spdk_bdev_initialize(bdev_init_cb, NULL); 2994 2995 bdev = allocate_bdev("bdev0"); 2996 2997 rc = spdk_bdev_open(bdev, true, NULL, NULL, &desc); 2998 CU_ASSERT(rc == 0); 2999 CU_ASSERT(desc != NULL); 3000 io_ch = spdk_bdev_get_io_channel(desc); 3001 CU_ASSERT(io_ch != NULL); 3002 channel = spdk_io_channel_get_ctx(io_ch); 3003 3004 /* Lock range 20-29. */ 3005 g_lock_lba_range_done = false; 3006 rc = bdev_lock_lba_range(desc, io_ch, 20, 10, lock_lba_range_done, &ctx1); 3007 CU_ASSERT(rc == 0); 3008 poll_threads(); 3009 3010 CU_ASSERT(g_lock_lba_range_done == true); 3011 range = TAILQ_FIRST(&channel->locked_ranges); 3012 SPDK_CU_ASSERT_FATAL(range != NULL); 3013 CU_ASSERT(range->offset == 20); 3014 CU_ASSERT(range->length == 10); 3015 3016 /* Try to lock range 25-39. It should not lock immediately, since it overlaps with 3017 * 20-29. 3018 */ 3019 g_lock_lba_range_done = false; 3020 rc = bdev_lock_lba_range(desc, io_ch, 25, 15, lock_lba_range_done, &ctx1); 3021 CU_ASSERT(rc == 0); 3022 poll_threads(); 3023 3024 CU_ASSERT(g_lock_lba_range_done == false); 3025 range = TAILQ_FIRST(&bdev->internal.pending_locked_ranges); 3026 SPDK_CU_ASSERT_FATAL(range != NULL); 3027 CU_ASSERT(range->offset == 25); 3028 CU_ASSERT(range->length == 15); 3029 3030 /* Unlock 20-29. This should result in range 25-39 now getting locked since it 3031 * no longer overlaps with an active lock. 3032 */ 3033 g_unlock_lba_range_done = false; 3034 rc = bdev_unlock_lba_range(desc, io_ch, 20, 10, unlock_lba_range_done, &ctx1); 3035 CU_ASSERT(rc == 0); 3036 poll_threads(); 3037 3038 CU_ASSERT(g_unlock_lba_range_done == true); 3039 CU_ASSERT(TAILQ_EMPTY(&bdev->internal.pending_locked_ranges)); 3040 range = TAILQ_FIRST(&channel->locked_ranges); 3041 SPDK_CU_ASSERT_FATAL(range != NULL); 3042 CU_ASSERT(range->offset == 25); 3043 CU_ASSERT(range->length == 15); 3044 3045 /* Lock 40-59. This should immediately lock since it does not overlap with the 3046 * currently active 25-39 lock. 3047 */ 3048 g_lock_lba_range_done = false; 3049 rc = bdev_lock_lba_range(desc, io_ch, 40, 20, lock_lba_range_done, &ctx1); 3050 CU_ASSERT(rc == 0); 3051 poll_threads(); 3052 3053 CU_ASSERT(g_lock_lba_range_done == true); 3054 range = TAILQ_FIRST(&bdev->internal.locked_ranges); 3055 SPDK_CU_ASSERT_FATAL(range != NULL); 3056 range = TAILQ_NEXT(range, tailq); 3057 SPDK_CU_ASSERT_FATAL(range != NULL); 3058 CU_ASSERT(range->offset == 40); 3059 CU_ASSERT(range->length == 20); 3060 3061 /* Try to lock 35-44. Note that this overlaps with both 25-39 and 40-59. */ 3062 g_lock_lba_range_done = false; 3063 rc = bdev_lock_lba_range(desc, io_ch, 35, 10, lock_lba_range_done, &ctx1); 3064 CU_ASSERT(rc == 0); 3065 poll_threads(); 3066 3067 CU_ASSERT(g_lock_lba_range_done == false); 3068 range = TAILQ_FIRST(&bdev->internal.pending_locked_ranges); 3069 SPDK_CU_ASSERT_FATAL(range != NULL); 3070 CU_ASSERT(range->offset == 35); 3071 CU_ASSERT(range->length == 10); 3072 3073 /* Unlock 25-39. Make sure that 35-44 is still in the pending list, since 3074 * the 40-59 lock is still active. 3075 */ 3076 g_unlock_lba_range_done = false; 3077 rc = bdev_unlock_lba_range(desc, io_ch, 25, 15, unlock_lba_range_done, &ctx1); 3078 CU_ASSERT(rc == 0); 3079 poll_threads(); 3080 3081 CU_ASSERT(g_unlock_lba_range_done == true); 3082 CU_ASSERT(g_lock_lba_range_done == false); 3083 range = TAILQ_FIRST(&bdev->internal.pending_locked_ranges); 3084 SPDK_CU_ASSERT_FATAL(range != NULL); 3085 CU_ASSERT(range->offset == 35); 3086 CU_ASSERT(range->length == 10); 3087 3088 /* Unlock 40-59. This should result in 35-44 now getting locked, since there are 3089 * no longer any active overlapping locks. 3090 */ 3091 g_unlock_lba_range_done = false; 3092 rc = bdev_unlock_lba_range(desc, io_ch, 40, 20, unlock_lba_range_done, &ctx1); 3093 CU_ASSERT(rc == 0); 3094 poll_threads(); 3095 3096 CU_ASSERT(g_unlock_lba_range_done == true); 3097 CU_ASSERT(g_lock_lba_range_done == true); 3098 CU_ASSERT(TAILQ_EMPTY(&bdev->internal.pending_locked_ranges)); 3099 range = TAILQ_FIRST(&bdev->internal.locked_ranges); 3100 SPDK_CU_ASSERT_FATAL(range != NULL); 3101 CU_ASSERT(range->offset == 35); 3102 CU_ASSERT(range->length == 10); 3103 3104 /* Finally, unlock 35-44. */ 3105 g_unlock_lba_range_done = false; 3106 rc = bdev_unlock_lba_range(desc, io_ch, 35, 10, unlock_lba_range_done, &ctx1); 3107 CU_ASSERT(rc == 0); 3108 poll_threads(); 3109 3110 CU_ASSERT(g_unlock_lba_range_done == true); 3111 CU_ASSERT(TAILQ_EMPTY(&bdev->internal.locked_ranges)); 3112 3113 spdk_put_io_channel(io_ch); 3114 spdk_bdev_close(desc); 3115 free_bdev(bdev); 3116 spdk_bdev_finish(bdev_fini_cb, NULL); 3117 poll_threads(); 3118 } 3119 3120 int 3121 main(int argc, char **argv) 3122 { 3123 CU_pSuite suite = NULL; 3124 unsigned int num_failures; 3125 3126 if (CU_initialize_registry() != CUE_SUCCESS) { 3127 return CU_get_error(); 3128 } 3129 3130 suite = CU_add_suite("bdev", null_init, null_clean); 3131 if (suite == NULL) { 3132 CU_cleanup_registry(); 3133 return CU_get_error(); 3134 } 3135 3136 if ( 3137 CU_add_test(suite, "bytes_to_blocks_test", bytes_to_blocks_test) == NULL || 3138 CU_add_test(suite, "num_blocks_test", num_blocks_test) == NULL || 3139 CU_add_test(suite, "io_valid", io_valid_test) == NULL || 3140 CU_add_test(suite, "open_write", open_write_test) == NULL || 3141 CU_add_test(suite, "alias_add_del", alias_add_del_test) == NULL || 3142 CU_add_test(suite, "get_device_stat", get_device_stat_test) == NULL || 3143 CU_add_test(suite, "bdev_io_types", bdev_io_types_test) == NULL || 3144 CU_add_test(suite, "bdev_io_wait", bdev_io_wait_test) == NULL || 3145 CU_add_test(suite, "bdev_io_spans_boundary", bdev_io_spans_boundary_test) == NULL || 3146 CU_add_test(suite, "bdev_io_split", bdev_io_split_test) == NULL || 3147 CU_add_test(suite, "bdev_io_split_with_io_wait", bdev_io_split_with_io_wait) == NULL || 3148 CU_add_test(suite, "bdev_io_alignment_with_boundary", bdev_io_alignment_with_boundary) == NULL || 3149 CU_add_test(suite, "bdev_io_alignment", bdev_io_alignment) == NULL || 3150 CU_add_test(suite, "bdev_histograms", bdev_histograms) == NULL || 3151 CU_add_test(suite, "bdev_write_zeroes", bdev_write_zeroes) == NULL || 3152 CU_add_test(suite, "bdev_compare_and_write", bdev_compare_and_write) == NULL || 3153 CU_add_test(suite, "bdev_compare", bdev_compare) == NULL || 3154 CU_add_test(suite, "bdev_open_while_hotremove", bdev_open_while_hotremove) == NULL || 3155 CU_add_test(suite, "bdev_close_while_hotremove", bdev_close_while_hotremove) == NULL || 3156 CU_add_test(suite, "bdev_open_ext", bdev_open_ext) == NULL || 3157 CU_add_test(suite, "bdev_set_io_timeout", bdev_set_io_timeout) == NULL || 3158 CU_add_test(suite, "lba_range_overlap", lba_range_overlap) == NULL || 3159 CU_add_test(suite, "lock_lba_range_check_ranges", lock_lba_range_check_ranges) == NULL || 3160 CU_add_test(suite, "lock_lba_range_with_io_outstanding", 3161 lock_lba_range_with_io_outstanding) == NULL || 3162 CU_add_test(suite, "lock_lba_range_overlapped", lock_lba_range_overlapped) == NULL 3163 ) { 3164 CU_cleanup_registry(); 3165 return CU_get_error(); 3166 } 3167 3168 allocate_threads(1); 3169 set_thread(0); 3170 3171 CU_basic_set_mode(CU_BRM_VERBOSE); 3172 CU_basic_run_tests(); 3173 num_failures = CU_get_number_of_failures(); 3174 CU_cleanup_registry(); 3175 3176 free_threads(); 3177 3178 return num_failures; 3179 } 3180