1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * 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/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "spdk/blob.h" 38 39 #include "lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "blobstore.c" 42 #include "request.c" 43 44 struct spdk_blob_store *g_bs; 45 spdk_blob_id g_blobid; 46 struct spdk_blob *g_blob; 47 int g_bserrno; 48 struct spdk_xattr_names *g_names; 49 int g_done; 50 51 bool g_scheduler_delay = false; 52 53 struct scheduled_ops { 54 spdk_thread_fn fn; 55 void *ctx; 56 57 TAILQ_ENTRY(scheduled_ops) ops_queue; 58 }; 59 60 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 61 62 struct spdk_bs_super_block_ver1 { 63 uint8_t signature[8]; 64 uint32_t version; 65 uint32_t length; 66 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 67 spdk_blob_id super_blob; 68 69 uint32_t cluster_size; /* In bytes */ 70 71 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 72 uint32_t used_page_mask_len; /* Count, in pages */ 73 74 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 75 uint32_t used_cluster_mask_len; /* Count, in pages */ 76 77 uint32_t md_start; /* Offset from beginning of disk, in pages */ 78 uint32_t md_len; /* Count, in pages */ 79 80 uint8_t reserved[4036]; 81 uint32_t crc; 82 } __attribute__((packed)); 83 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 84 85 static void 86 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 87 { 88 if (g_scheduler_delay) { 89 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 90 91 SPDK_CU_ASSERT_FATAL(ops != NULL); 92 ops->fn = fn; 93 ops->ctx = ctx; 94 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 95 } else { 96 fn(ctx); 97 } 98 } 99 100 static void 101 _bs_flush_scheduler(void) 102 { 103 struct scheduled_ops *ops, *tmp; 104 105 TAILQ_FOREACH_SAFE(ops, &g_scheduled_ops, ops_queue, tmp) { 106 ops->fn(ops->ctx); 107 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 108 free(ops); 109 } 110 } 111 112 static void 113 bs_op_complete(void *cb_arg, int bserrno) 114 { 115 g_bserrno = bserrno; 116 } 117 118 static void 119 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 120 int bserrno) 121 { 122 g_bs = bs; 123 g_bserrno = bserrno; 124 } 125 126 static void 127 blob_op_complete(void *cb_arg, int bserrno) 128 { 129 g_bserrno = bserrno; 130 } 131 132 static void 133 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 134 { 135 g_blobid = blobid; 136 g_bserrno = bserrno; 137 } 138 139 static void 140 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 141 { 142 g_blob = blb; 143 g_bserrno = bserrno; 144 } 145 146 static void 147 blob_init(void) 148 { 149 struct spdk_bs_dev *dev; 150 151 dev = init_dev(); 152 153 /* should fail for an unsupported blocklen */ 154 dev->blocklen = 500; 155 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 156 CU_ASSERT(g_bserrno == -EINVAL); 157 158 dev = init_dev(); 159 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 160 CU_ASSERT(g_bserrno == 0); 161 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 162 163 spdk_bs_unload(g_bs, bs_op_complete, NULL); 164 CU_ASSERT(g_bserrno == 0); 165 g_bs = NULL; 166 } 167 168 static void 169 blob_super(void) 170 { 171 struct spdk_blob_store *bs; 172 struct spdk_bs_dev *dev; 173 spdk_blob_id blobid; 174 175 dev = init_dev(); 176 177 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 178 CU_ASSERT(g_bserrno == 0); 179 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 180 bs = g_bs; 181 182 /* Get the super blob without having set one */ 183 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 184 CU_ASSERT(g_bserrno == -ENOENT); 185 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 186 187 /* Create a blob */ 188 spdk_bs_md_create_blob(bs, 189 blob_op_with_id_complete, NULL); 190 CU_ASSERT(g_bserrno == 0); 191 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 192 blobid = g_blobid; 193 194 /* Set the blob as the super blob */ 195 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 196 CU_ASSERT(g_bserrno == 0); 197 198 /* Get the super blob */ 199 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 200 CU_ASSERT(g_bserrno == 0); 201 CU_ASSERT(blobid == g_blobid); 202 203 spdk_bs_unload(g_bs, bs_op_complete, NULL); 204 CU_ASSERT(g_bserrno == 0); 205 g_bs = NULL; 206 } 207 208 static void 209 blob_open(void) 210 { 211 struct spdk_blob_store *bs; 212 struct spdk_bs_dev *dev; 213 struct spdk_blob *blob; 214 spdk_blob_id blobid, blobid2; 215 216 dev = init_dev(); 217 218 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 219 CU_ASSERT(g_bserrno == 0); 220 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 221 bs = g_bs; 222 223 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 224 CU_ASSERT(g_bserrno == 0); 225 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 226 blobid = g_blobid; 227 228 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 229 CU_ASSERT(g_bserrno == 0); 230 CU_ASSERT(g_blob != NULL); 231 blob = g_blob; 232 233 blobid2 = spdk_blob_get_id(blob); 234 CU_ASSERT(blobid == blobid2); 235 236 /* Try to open file again. It should return success. */ 237 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 238 CU_ASSERT(g_bserrno == 0); 239 CU_ASSERT(blob == g_blob); 240 241 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 242 CU_ASSERT(g_bserrno == 0); 243 CU_ASSERT(blob == NULL); 244 245 /* 246 * Close the file a second time, releasing the second reference. This 247 * should succeed. 248 */ 249 blob = g_blob; 250 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 251 CU_ASSERT(g_bserrno == 0); 252 253 /* 254 * Try to open file again. It should succeed. This tests the case 255 * where the file is opened, closed, then re-opened again. 256 */ 257 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 258 CU_ASSERT(g_bserrno == 0); 259 CU_ASSERT(g_blob != NULL); 260 blob = g_blob; 261 262 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 263 CU_ASSERT(g_bserrno == 0); 264 265 spdk_bs_unload(g_bs, bs_op_complete, NULL); 266 CU_ASSERT(g_bserrno == 0); 267 g_bs = NULL; 268 } 269 270 static void 271 blob_delete(void) 272 { 273 struct spdk_blob_store *bs; 274 struct spdk_bs_dev *dev; 275 spdk_blob_id blobid; 276 277 dev = init_dev(); 278 279 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 280 CU_ASSERT(g_bserrno == 0); 281 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 282 bs = g_bs; 283 284 /* Create a blob and then delete it. */ 285 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 286 CU_ASSERT(g_bserrno == 0); 287 CU_ASSERT(g_blobid > 0); 288 blobid = g_blobid; 289 290 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 291 CU_ASSERT(g_bserrno == 0); 292 293 /* Try to open the blob */ 294 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 295 CU_ASSERT(g_bserrno == -ENOENT); 296 297 spdk_bs_unload(g_bs, bs_op_complete, NULL); 298 CU_ASSERT(g_bserrno == 0); 299 g_bs = NULL; 300 } 301 302 static void 303 blob_resize(void) 304 { 305 struct spdk_blob_store *bs; 306 struct spdk_bs_dev *dev; 307 struct spdk_blob *blob; 308 spdk_blob_id blobid; 309 uint64_t free_clusters; 310 int rc; 311 312 dev = init_dev(); 313 314 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 315 CU_ASSERT(g_bserrno == 0); 316 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 317 bs = g_bs; 318 free_clusters = spdk_bs_free_cluster_count(bs); 319 320 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 321 CU_ASSERT(g_bserrno == 0); 322 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 323 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 324 blobid = g_blobid; 325 326 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 327 CU_ASSERT(g_bserrno == 0); 328 CU_ASSERT(g_blob != NULL); 329 blob = g_blob; 330 331 /* The blob started at 0 clusters. Resize it to be 5. */ 332 rc = spdk_bs_md_resize_blob(blob, 5); 333 CU_ASSERT(rc == 0); 334 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 335 336 /* Shrink the blob to 3 clusters. This will not actually release 337 * the old clusters until the blob is synced. 338 */ 339 rc = spdk_bs_md_resize_blob(blob, 3); 340 CU_ASSERT(rc == 0); 341 /* Verify there are still 5 clusters in use */ 342 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 343 344 spdk_bs_md_sync_blob(blob, blob_op_complete, NULL); 345 CU_ASSERT(g_bserrno == 0); 346 /* Now there are only 3 clusters in use */ 347 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 348 349 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 350 rc = spdk_bs_md_resize_blob(blob, 10); 351 CU_ASSERT(rc == 0); 352 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 353 354 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 355 CU_ASSERT(g_bserrno == 0); 356 357 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 358 CU_ASSERT(g_bserrno == 0); 359 360 spdk_bs_unload(g_bs, bs_op_complete, NULL); 361 CU_ASSERT(g_bserrno == 0); 362 g_bs = NULL; 363 } 364 365 static void 366 channel_ops(void) 367 { 368 struct spdk_blob_store *bs; 369 struct spdk_bs_dev *dev; 370 struct spdk_io_channel *channel; 371 372 dev = init_dev(); 373 374 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 375 CU_ASSERT(g_bserrno == 0); 376 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 377 bs = g_bs; 378 379 channel = spdk_bs_alloc_io_channel(bs); 380 CU_ASSERT(channel != NULL); 381 382 spdk_bs_free_io_channel(channel); 383 384 spdk_bs_unload(g_bs, bs_op_complete, NULL); 385 CU_ASSERT(g_bserrno == 0); 386 g_bs = NULL; 387 } 388 389 static void 390 blob_write(void) 391 { 392 struct spdk_blob_store *bs; 393 struct spdk_bs_dev *dev; 394 struct spdk_blob *blob; 395 struct spdk_io_channel *channel; 396 spdk_blob_id blobid; 397 uint64_t pages_per_cluster; 398 uint8_t payload[10 * 4096]; 399 int rc; 400 401 dev = init_dev(); 402 403 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 404 CU_ASSERT(g_bserrno == 0); 405 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 406 bs = g_bs; 407 408 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 409 410 channel = spdk_bs_alloc_io_channel(bs); 411 CU_ASSERT(channel != NULL); 412 413 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 414 CU_ASSERT(g_bserrno == 0); 415 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 416 blobid = g_blobid; 417 418 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 419 CU_ASSERT(g_bserrno == 0); 420 CU_ASSERT(g_blob != NULL); 421 blob = g_blob; 422 423 /* Write to a blob with 0 size */ 424 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 425 CU_ASSERT(g_bserrno == -EINVAL); 426 427 /* Resize the blob */ 428 rc = spdk_bs_md_resize_blob(blob, 5); 429 CU_ASSERT(rc == 0); 430 431 /* Write to the blob */ 432 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 433 CU_ASSERT(g_bserrno == 0); 434 435 /* Write starting beyond the end */ 436 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 437 NULL); 438 CU_ASSERT(g_bserrno == -EINVAL); 439 440 /* Write starting at a valid location but going off the end */ 441 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 442 blob_op_complete, NULL); 443 CU_ASSERT(g_bserrno == -EINVAL); 444 445 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 446 CU_ASSERT(g_bserrno == 0); 447 448 spdk_bs_free_io_channel(channel); 449 450 spdk_bs_unload(g_bs, bs_op_complete, NULL); 451 CU_ASSERT(g_bserrno == 0); 452 g_bs = NULL; 453 } 454 455 static void 456 blob_read(void) 457 { 458 struct spdk_blob_store *bs; 459 struct spdk_bs_dev *dev; 460 struct spdk_blob *blob; 461 struct spdk_io_channel *channel; 462 spdk_blob_id blobid; 463 uint64_t pages_per_cluster; 464 uint8_t payload[10 * 4096]; 465 int rc; 466 467 dev = init_dev(); 468 469 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 470 CU_ASSERT(g_bserrno == 0); 471 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 472 bs = g_bs; 473 474 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 475 476 channel = spdk_bs_alloc_io_channel(bs); 477 CU_ASSERT(channel != NULL); 478 479 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 480 CU_ASSERT(g_bserrno == 0); 481 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 482 blobid = g_blobid; 483 484 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 485 CU_ASSERT(g_bserrno == 0); 486 CU_ASSERT(g_blob != NULL); 487 blob = g_blob; 488 489 /* Read from a blob with 0 size */ 490 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 491 CU_ASSERT(g_bserrno == -EINVAL); 492 493 /* Resize the blob */ 494 rc = spdk_bs_md_resize_blob(blob, 5); 495 CU_ASSERT(rc == 0); 496 497 /* Read from the blob */ 498 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 499 CU_ASSERT(g_bserrno == 0); 500 501 /* Read starting beyond the end */ 502 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 503 NULL); 504 CU_ASSERT(g_bserrno == -EINVAL); 505 506 /* Read starting at a valid location but going off the end */ 507 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 508 blob_op_complete, NULL); 509 CU_ASSERT(g_bserrno == -EINVAL); 510 511 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 512 CU_ASSERT(g_bserrno == 0); 513 514 spdk_bs_free_io_channel(channel); 515 516 spdk_bs_unload(g_bs, bs_op_complete, NULL); 517 CU_ASSERT(g_bserrno == 0); 518 g_bs = NULL; 519 } 520 521 static void 522 blob_rw_verify(void) 523 { 524 struct spdk_blob_store *bs; 525 struct spdk_bs_dev *dev; 526 struct spdk_blob *blob; 527 struct spdk_io_channel *channel; 528 spdk_blob_id blobid; 529 uint8_t payload_read[10 * 4096]; 530 uint8_t payload_write[10 * 4096]; 531 int rc; 532 533 dev = init_dev(); 534 535 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 536 CU_ASSERT(g_bserrno == 0); 537 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 538 bs = g_bs; 539 540 channel = spdk_bs_alloc_io_channel(bs); 541 CU_ASSERT(channel != NULL); 542 543 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 544 CU_ASSERT(g_bserrno == 0); 545 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 546 blobid = g_blobid; 547 548 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 549 CU_ASSERT(g_bserrno == 0); 550 CU_ASSERT(g_blob != NULL); 551 blob = g_blob; 552 553 rc = spdk_bs_md_resize_blob(blob, 32); 554 CU_ASSERT(rc == 0); 555 556 memset(payload_write, 0xE5, sizeof(payload_write)); 557 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 558 CU_ASSERT(g_bserrno == 0); 559 560 memset(payload_read, 0x00, sizeof(payload_read)); 561 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 562 CU_ASSERT(g_bserrno == 0); 563 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 564 565 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 566 CU_ASSERT(g_bserrno == 0); 567 568 spdk_bs_free_io_channel(channel); 569 570 spdk_bs_unload(g_bs, bs_op_complete, NULL); 571 CU_ASSERT(g_bserrno == 0); 572 g_bs = NULL; 573 } 574 575 static void 576 blob_rw_verify_iov(void) 577 { 578 struct spdk_blob_store *bs; 579 struct spdk_bs_dev *dev; 580 struct spdk_blob *blob; 581 struct spdk_io_channel *channel; 582 spdk_blob_id blobid; 583 uint8_t payload_read[10 * 4096]; 584 uint8_t payload_write[10 * 4096]; 585 struct iovec iov_read[3]; 586 struct iovec iov_write[3]; 587 void *buf; 588 int rc; 589 590 dev = init_dev(); 591 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 592 593 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 594 CU_ASSERT(g_bserrno == 0); 595 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 596 bs = g_bs; 597 598 channel = spdk_bs_alloc_io_channel(bs); 599 CU_ASSERT(channel != NULL); 600 601 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 602 CU_ASSERT(g_bserrno == 0); 603 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 604 blobid = g_blobid; 605 606 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 607 CU_ASSERT(g_bserrno == 0); 608 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 609 blob = g_blob; 610 611 rc = spdk_bs_md_resize_blob(blob, 2); 612 CU_ASSERT(rc == 0); 613 614 /* 615 * Manually adjust the offset of the blob's second cluster. This allows 616 * us to make sure that the readv/write code correctly accounts for I/O 617 * that cross cluster boundaries. Start by asserting that the allocated 618 * clusters are where we expect before modifying the second cluster. 619 */ 620 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 621 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 622 blob->active.clusters[1] = 3 * 256; 623 624 memset(payload_write, 0xE5, sizeof(payload_write)); 625 iov_write[0].iov_base = payload_write; 626 iov_write[0].iov_len = 1 * 4096; 627 iov_write[1].iov_base = payload_write + 1 * 4096; 628 iov_write[1].iov_len = 5 * 4096; 629 iov_write[2].iov_base = payload_write + 6 * 4096; 630 iov_write[2].iov_len = 4 * 4096; 631 /* 632 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 633 * will get written to the first cluster, the last 4 to the second cluster. 634 */ 635 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 636 CU_ASSERT(g_bserrno == 0); 637 638 memset(payload_read, 0xAA, sizeof(payload_read)); 639 iov_read[0].iov_base = payload_read; 640 iov_read[0].iov_len = 3 * 4096; 641 iov_read[1].iov_base = payload_read + 3 * 4096; 642 iov_read[1].iov_len = 4 * 4096; 643 iov_read[2].iov_base = payload_read + 7 * 4096; 644 iov_read[2].iov_len = 3 * 4096; 645 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 646 CU_ASSERT(g_bserrno == 0); 647 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 648 649 buf = calloc(1, 256 * 4096); 650 SPDK_CU_ASSERT_FATAL(buf != NULL); 651 /* Check that cluster 2 on "disk" was not modified. */ 652 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 653 free(buf); 654 655 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 656 CU_ASSERT(g_bserrno == 0); 657 658 spdk_bs_free_io_channel(channel); 659 660 spdk_bs_unload(g_bs, bs_op_complete, NULL); 661 CU_ASSERT(g_bserrno == 0); 662 g_bs = NULL; 663 } 664 665 static uint32_t 666 bs_channel_get_req_count(struct spdk_io_channel *_channel) 667 { 668 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 669 struct spdk_bs_request_set *set; 670 uint32_t count = 0; 671 672 TAILQ_FOREACH(set, &channel->reqs, link) { 673 count++; 674 } 675 676 return count; 677 } 678 679 static void 680 blob_rw_verify_iov_nomem(void) 681 { 682 struct spdk_blob_store *bs; 683 struct spdk_bs_dev *dev; 684 struct spdk_blob *blob; 685 struct spdk_io_channel *channel; 686 spdk_blob_id blobid; 687 uint8_t payload_write[10 * 4096]; 688 struct iovec iov_write[3]; 689 uint32_t req_count; 690 int rc; 691 692 dev = init_dev(); 693 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 694 695 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 696 CU_ASSERT(g_bserrno == 0); 697 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 698 bs = g_bs; 699 700 channel = spdk_bs_alloc_io_channel(bs); 701 CU_ASSERT(channel != NULL); 702 703 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 704 CU_ASSERT(g_bserrno == 0); 705 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 706 blobid = g_blobid; 707 708 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 709 CU_ASSERT(g_bserrno == 0); 710 CU_ASSERT(g_blob != NULL); 711 blob = g_blob; 712 713 rc = spdk_bs_md_resize_blob(blob, 2); 714 CU_ASSERT(rc == 0); 715 716 /* 717 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 718 * will get written to the first cluster, the last 4 to the second cluster. 719 */ 720 iov_write[0].iov_base = payload_write; 721 iov_write[0].iov_len = 1 * 4096; 722 iov_write[1].iov_base = payload_write + 1 * 4096; 723 iov_write[1].iov_len = 5 * 4096; 724 iov_write[2].iov_base = payload_write + 6 * 4096; 725 iov_write[2].iov_len = 4 * 4096; 726 MOCK_SET(calloc, void *, NULL); 727 req_count = bs_channel_get_req_count(channel); 728 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 729 CU_ASSERT(g_bserrno = -ENOMEM); 730 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 731 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 732 733 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 734 CU_ASSERT(g_bserrno == 0); 735 736 spdk_bs_free_io_channel(channel); 737 738 spdk_bs_unload(g_bs, bs_op_complete, NULL); 739 CU_ASSERT(g_bserrno == 0); 740 g_bs = NULL; 741 } 742 743 static void 744 blob_iter(void) 745 { 746 struct spdk_blob_store *bs; 747 struct spdk_bs_dev *dev; 748 struct spdk_blob *blob; 749 spdk_blob_id blobid; 750 751 dev = init_dev(); 752 753 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 754 CU_ASSERT(g_bserrno == 0); 755 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 756 bs = g_bs; 757 758 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 759 CU_ASSERT(g_blob == NULL); 760 CU_ASSERT(g_bserrno == -ENOENT); 761 762 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 763 CU_ASSERT(g_bserrno == 0); 764 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 765 blobid = g_blobid; 766 767 spdk_bs_md_iter_first(bs, blob_op_with_handle_complete, NULL); 768 CU_ASSERT(g_blob != NULL); 769 CU_ASSERT(g_bserrno == 0); 770 blob = g_blob; 771 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 772 773 spdk_bs_md_iter_next(bs, &blob, blob_op_with_handle_complete, NULL); 774 CU_ASSERT(g_blob == NULL); 775 CU_ASSERT(g_bserrno == -ENOENT); 776 777 spdk_bs_unload(g_bs, bs_op_complete, NULL); 778 CU_ASSERT(g_bserrno == 0); 779 g_bs = NULL; 780 } 781 782 static void 783 blob_xattr(void) 784 { 785 struct spdk_blob_store *bs; 786 struct spdk_bs_dev *dev; 787 struct spdk_blob *blob; 788 spdk_blob_id blobid; 789 uint64_t length; 790 int rc; 791 const char *name1, *name2; 792 const void *value; 793 size_t value_len; 794 struct spdk_xattr_names *names; 795 796 dev = init_dev(); 797 798 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 799 CU_ASSERT(g_bserrno == 0); 800 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 801 bs = g_bs; 802 803 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 804 CU_ASSERT(g_bserrno == 0); 805 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 806 blobid = g_blobid; 807 808 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 809 CU_ASSERT(g_bserrno == 0); 810 CU_ASSERT(g_blob != NULL); 811 blob = g_blob; 812 813 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 814 CU_ASSERT(rc == 0); 815 816 length = 2345; 817 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 818 CU_ASSERT(rc == 0); 819 820 /* Overwrite "length" xattr. */ 821 length = 3456; 822 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 823 CU_ASSERT(rc == 0); 824 825 value = NULL; 826 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 827 CU_ASSERT(rc == 0); 828 SPDK_CU_ASSERT_FATAL(value != NULL); 829 CU_ASSERT(*(uint64_t *)value == length); 830 CU_ASSERT(value_len == 8); 831 832 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 833 CU_ASSERT(rc == -ENOENT); 834 835 names = NULL; 836 rc = spdk_bs_md_get_xattr_names(blob, &names); 837 CU_ASSERT(rc == 0); 838 SPDK_CU_ASSERT_FATAL(names != NULL); 839 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 840 name1 = spdk_xattr_names_get_name(names, 0); 841 SPDK_CU_ASSERT_FATAL(name1 != NULL); 842 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 843 name2 = spdk_xattr_names_get_name(names, 1); 844 SPDK_CU_ASSERT_FATAL(name2 != NULL); 845 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 846 CU_ASSERT(strcmp(name1, name2)); 847 spdk_xattr_names_free(names); 848 849 rc = spdk_blob_md_remove_xattr(blob, "name"); 850 CU_ASSERT(rc == 0); 851 852 rc = spdk_blob_md_remove_xattr(blob, "foobar"); 853 CU_ASSERT(rc == -ENOENT); 854 855 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 856 857 spdk_bs_unload(g_bs, bs_op_complete, NULL); 858 CU_ASSERT(g_bserrno == 0); 859 g_bs = NULL; 860 } 861 862 static void 863 bs_load(void) 864 { 865 struct spdk_bs_dev *dev; 866 spdk_blob_id blobid; 867 struct spdk_blob *blob; 868 struct spdk_bs_super_block *super_block; 869 uint64_t length; 870 int rc; 871 const void *value; 872 size_t value_len; 873 struct spdk_bs_opts opts; 874 875 g_scheduler_delay = true; 876 877 dev = init_dev(); 878 spdk_bs_opts_init(&opts); 879 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 880 881 /* Initialize a new blob store */ 882 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 883 CU_ASSERT(g_bserrno == 0); 884 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 885 886 /* Try to open a blobid that does not exist */ 887 spdk_bs_md_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 888 CU_ASSERT(g_bserrno == -ENOENT); 889 CU_ASSERT(g_blob == NULL); 890 891 /* Create a blob */ 892 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 893 CU_ASSERT(g_bserrno == 0); 894 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 895 blobid = g_blobid; 896 897 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 898 CU_ASSERT(g_bserrno == 0); 899 CU_ASSERT(g_blob != NULL); 900 blob = g_blob; 901 902 /* Try again to open valid blob but without the upper bit set */ 903 spdk_bs_md_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 904 CU_ASSERT(g_bserrno == -ENOENT); 905 CU_ASSERT(g_blob == NULL); 906 907 /* Set some xattrs */ 908 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 909 CU_ASSERT(rc == 0); 910 911 length = 2345; 912 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 913 CU_ASSERT(rc == 0); 914 915 /* Resize the blob */ 916 rc = spdk_bs_md_resize_blob(blob, 10); 917 CU_ASSERT(rc == 0); 918 919 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 920 CU_ASSERT(g_bserrno == 0); 921 blob = NULL; 922 g_blob = NULL; 923 g_blobid = SPDK_BLOBID_INVALID; 924 925 /* Unload the blob store */ 926 spdk_bs_unload(g_bs, bs_op_complete, NULL); 927 CU_ASSERT(g_bserrno == 0); 928 g_bs = NULL; 929 g_blob = NULL; 930 g_blobid = 0; 931 932 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 933 CU_ASSERT(super_block->clean == 1); 934 935 936 /* Load an existing blob store */ 937 dev = init_dev(); 938 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 939 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 940 CU_ASSERT(g_bserrno == 0); 941 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 942 943 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 944 CU_ASSERT(super_block->clean == 0); 945 946 spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 947 CU_ASSERT(g_bserrno == 0); 948 CU_ASSERT(g_blob != NULL); 949 blob = g_blob; 950 951 /* Get the xattrs */ 952 value = NULL; 953 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 954 CU_ASSERT(rc == 0); 955 SPDK_CU_ASSERT_FATAL(value != NULL); 956 CU_ASSERT(*(uint64_t *)value == length); 957 CU_ASSERT(value_len == 8); 958 959 rc = spdk_bs_md_get_xattr_value(blob, "foobar", &value, &value_len); 960 CU_ASSERT(rc == -ENOENT); 961 962 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 963 964 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 965 CU_ASSERT(g_bserrno == 0); 966 blob = NULL; 967 g_blob = NULL; 968 g_blobid = SPDK_BLOBID_INVALID; 969 970 spdk_bs_unload(g_bs, bs_op_complete, NULL); 971 CU_ASSERT(g_bserrno == 0); 972 g_bs = NULL; 973 g_scheduler_delay = false; 974 } 975 976 static void 977 bs_type(void) 978 { 979 struct spdk_bs_dev *dev; 980 struct spdk_bs_opts opts; 981 982 g_scheduler_delay = true; 983 984 dev = init_dev(); 985 spdk_bs_opts_init(&opts); 986 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 987 988 /* Initialize a new blob store */ 989 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 990 CU_ASSERT(g_bserrno == 0); 991 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 992 993 /* Unload the blob store */ 994 spdk_bs_unload(g_bs, bs_op_complete, NULL); 995 CU_ASSERT(g_bserrno == 0); 996 g_bs = NULL; 997 g_blob = NULL; 998 g_blobid = 0; 999 1000 /* Load non existing blobstore type */ 1001 dev = init_dev(); 1002 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1003 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1004 CU_ASSERT(g_bserrno != 0); 1005 1006 /* Load with empty blobstore type */ 1007 dev = init_dev(); 1008 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1009 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1010 CU_ASSERT(g_bserrno == 0); 1011 1012 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1013 CU_ASSERT(g_bserrno == 0); 1014 g_bs = NULL; 1015 1016 /* Initialize a new blob store with empty bstype */ 1017 dev = init_dev(); 1018 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1019 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1020 CU_ASSERT(g_bserrno == 0); 1021 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1022 1023 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1024 CU_ASSERT(g_bserrno == 0); 1025 g_bs = NULL; 1026 1027 /* Load non existing blobstore type */ 1028 dev = init_dev(); 1029 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1030 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1031 CU_ASSERT(g_bserrno != 0); 1032 1033 /* Load with empty blobstore type */ 1034 dev = init_dev(); 1035 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1036 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1037 CU_ASSERT(g_bserrno == 0); 1038 1039 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1040 CU_ASSERT(g_bserrno == 0); 1041 g_bs = NULL; 1042 g_scheduler_delay = false; 1043 } 1044 1045 static void 1046 bs_super_block(void) 1047 { 1048 struct spdk_bs_dev *dev; 1049 struct spdk_bs_super_block *super_block; 1050 struct spdk_bs_opts opts; 1051 struct spdk_bs_super_block_ver1 super_block_v1; 1052 1053 g_scheduler_delay = true; 1054 1055 dev = init_dev(); 1056 spdk_bs_opts_init(&opts); 1057 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1058 1059 /* Initialize a new blob store */ 1060 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1061 CU_ASSERT(g_bserrno == 0); 1062 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1063 1064 /* Unload the blob store */ 1065 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1066 CU_ASSERT(g_bserrno == 0); 1067 g_bs = NULL; 1068 g_blob = NULL; 1069 g_blobid = 0; 1070 1071 /* Load an existing blob store with version newer than supported */ 1072 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1073 super_block->version++; 1074 1075 dev = init_dev(); 1076 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1077 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1078 CU_ASSERT(g_bserrno != 0); 1079 1080 /* Create a new blob store with super block version 1 */ 1081 dev = init_dev(); 1082 super_block_v1.version = 1; 1083 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1084 super_block_v1.length = 0x1000; 1085 super_block_v1.clean = 1; 1086 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1087 super_block_v1.cluster_size = 0x100000; 1088 super_block_v1.used_page_mask_start = 0x01; 1089 super_block_v1.used_page_mask_len = 0x01; 1090 super_block_v1.used_cluster_mask_start = 0x02; 1091 super_block_v1.used_cluster_mask_len = 0x01; 1092 super_block_v1.md_start = 0x03; 1093 super_block_v1.md_len = 0x40; 1094 memset(super_block_v1.reserved, 0, 4036); 1095 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1096 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1097 1098 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1099 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1100 CU_ASSERT(g_bserrno == 0); 1101 1102 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1103 CU_ASSERT(g_bserrno == 0); 1104 g_bs = NULL; 1105 g_scheduler_delay = false; 1106 } 1107 1108 /* 1109 * Create a blobstore and then unload it. 1110 */ 1111 static void 1112 bs_unload(void) 1113 { 1114 struct spdk_bs_dev *dev; 1115 1116 dev = init_dev(); 1117 1118 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1119 CU_ASSERT(g_bserrno == 0); 1120 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1121 1122 g_bserrno = -1; 1123 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1124 CU_ASSERT(g_bserrno == 0); 1125 g_bs = NULL; 1126 } 1127 1128 /* 1129 * Create a blobstore with a cluster size different than the default, and ensure it is 1130 * persisted. 1131 */ 1132 static void 1133 bs_cluster_sz(void) 1134 { 1135 struct spdk_bs_dev *dev; 1136 struct spdk_bs_opts opts; 1137 uint32_t cluster_sz; 1138 1139 /* Set cluster size to zero */ 1140 dev = init_dev(); 1141 spdk_bs_opts_init(&opts); 1142 opts.cluster_sz = 0; 1143 1144 /* Initialize a new blob store */ 1145 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1146 CU_ASSERT(g_bserrno == -EINVAL); 1147 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1148 1149 /* 1150 * Set cluster size to blobstore page size, 1151 * to work it is required to be at least twice the blobstore page size. 1152 */ 1153 dev = init_dev(); 1154 spdk_bs_opts_init(&opts); 1155 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1156 1157 /* Initialize a new blob store */ 1158 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1159 CU_ASSERT(g_bserrno == -ENOMEM); 1160 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1161 1162 /* Set cluster size to twice the default */ 1163 dev = init_dev(); 1164 spdk_bs_opts_init(&opts); 1165 opts.cluster_sz *= 2; 1166 cluster_sz = opts.cluster_sz; 1167 1168 /* Initialize a new blob store */ 1169 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1170 CU_ASSERT(g_bserrno == 0); 1171 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1172 1173 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1174 1175 /* Unload the blob store */ 1176 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1177 CU_ASSERT(g_bserrno == 0); 1178 g_bs = NULL; 1179 g_blob = NULL; 1180 g_blobid = 0; 1181 1182 dev = init_dev(); 1183 /* Load an existing blob store */ 1184 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1185 CU_ASSERT(g_bserrno == 0); 1186 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1187 1188 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1189 1190 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1191 CU_ASSERT(g_bserrno == 0); 1192 g_bs = NULL; 1193 } 1194 1195 /* 1196 * Test resizing of the metadata blob. This requires creating enough blobs 1197 * so that one cluster is not enough to fit the metadata for those blobs. 1198 * To induce this condition to happen more quickly, we reduce the cluster 1199 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1200 */ 1201 static void 1202 bs_resize_md(void) 1203 { 1204 const int CLUSTER_PAGE_COUNT = 4; 1205 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1206 struct spdk_bs_dev *dev; 1207 struct spdk_bs_opts opts; 1208 uint32_t cluster_sz; 1209 spdk_blob_id blobids[NUM_BLOBS]; 1210 int i; 1211 1212 1213 dev = init_dev(); 1214 spdk_bs_opts_init(&opts); 1215 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1216 cluster_sz = opts.cluster_sz; 1217 1218 /* Initialize a new blob store */ 1219 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1220 CU_ASSERT(g_bserrno == 0); 1221 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1222 1223 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1224 1225 for (i = 0; i < NUM_BLOBS; i++) { 1226 g_bserrno = -1; 1227 g_blobid = SPDK_BLOBID_INVALID; 1228 spdk_bs_md_create_blob(g_bs, 1229 blob_op_with_id_complete, NULL); 1230 CU_ASSERT(g_bserrno == 0); 1231 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1232 blobids[i] = g_blobid; 1233 } 1234 1235 /* Unload the blob store */ 1236 g_bserrno = -1; 1237 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1238 CU_ASSERT(g_bserrno == 0); 1239 1240 /* Load an existing blob store */ 1241 g_bserrno = -1; 1242 g_bs = NULL; 1243 dev = init_dev(); 1244 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1245 CU_ASSERT(g_bserrno == 0); 1246 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1247 1248 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1249 1250 for (i = 0; i < NUM_BLOBS; i++) { 1251 g_bserrno = -1; 1252 g_blob = NULL; 1253 spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1254 CU_ASSERT(g_bserrno == 0); 1255 CU_ASSERT(g_blob != NULL); 1256 g_bserrno = -1; 1257 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1258 CU_ASSERT(g_bserrno == 0); 1259 } 1260 1261 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1262 CU_ASSERT(g_bserrno == 0); 1263 g_bs = NULL; 1264 } 1265 1266 /* Try to hit all of the corner cases associated with serializing 1267 * a blob to disk 1268 */ 1269 static void 1270 blob_serialize(void) 1271 { 1272 struct spdk_bs_dev *dev; 1273 struct spdk_bs_opts opts; 1274 struct spdk_blob_store *bs; 1275 spdk_blob_id blobid[2]; 1276 struct spdk_blob *blob[2]; 1277 uint64_t i; 1278 char *value; 1279 int rc; 1280 1281 dev = init_dev(); 1282 1283 /* Initialize a new blobstore with very small clusters */ 1284 spdk_bs_opts_init(&opts); 1285 opts.cluster_sz = dev->blocklen * 8; 1286 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1287 CU_ASSERT(g_bserrno == 0); 1288 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1289 bs = g_bs; 1290 1291 /* Create and open two blobs */ 1292 for (i = 0; i < 2; i++) { 1293 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1294 CU_ASSERT(g_bserrno == 0); 1295 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1296 blobid[i] = g_blobid; 1297 1298 /* Open a blob */ 1299 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1300 CU_ASSERT(g_bserrno == 0); 1301 CU_ASSERT(g_blob != NULL); 1302 blob[i] = g_blob; 1303 1304 /* Set a fairly large xattr on both blobs to eat up 1305 * metadata space 1306 */ 1307 value = calloc(dev->blocklen - 64, sizeof(char)); 1308 SPDK_CU_ASSERT_FATAL(value != NULL); 1309 memset(value, i, dev->blocklen / 2); 1310 rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1311 CU_ASSERT(rc == 0); 1312 free(value); 1313 } 1314 1315 /* Resize the blobs, alternating 1 cluster at a time. 1316 * This thwarts run length encoding and will cause spill 1317 * over of the extents. 1318 */ 1319 for (i = 0; i < 6; i++) { 1320 rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1); 1321 CU_ASSERT(rc == 0); 1322 } 1323 1324 for (i = 0; i < 2; i++) { 1325 spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL); 1326 CU_ASSERT(g_bserrno == 0); 1327 } 1328 1329 /* Close the blobs */ 1330 for (i = 0; i < 2; i++) { 1331 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1332 CU_ASSERT(g_bserrno == 0); 1333 } 1334 1335 /* Unload the blobstore */ 1336 spdk_bs_unload(bs, bs_op_complete, NULL); 1337 CU_ASSERT(g_bserrno == 0); 1338 g_bs = NULL; 1339 g_blob = NULL; 1340 g_blobid = 0; 1341 bs = NULL; 1342 1343 dev = init_dev(); 1344 /* Load an existing blob store */ 1345 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1346 CU_ASSERT(g_bserrno == 0); 1347 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1348 bs = g_bs; 1349 1350 for (i = 0; i < 2; i++) { 1351 blob[i] = NULL; 1352 1353 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1354 CU_ASSERT(g_bserrno == 0); 1355 CU_ASSERT(g_blob != NULL); 1356 blob[i] = g_blob; 1357 1358 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1359 1360 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1361 CU_ASSERT(g_bserrno == 0); 1362 } 1363 1364 spdk_bs_unload(bs, bs_op_complete, NULL); 1365 CU_ASSERT(g_bserrno == 0); 1366 g_bs = NULL; 1367 } 1368 1369 static void 1370 blob_crc(void) 1371 { 1372 struct spdk_blob_store *bs; 1373 struct spdk_bs_dev *dev; 1374 struct spdk_blob *blob; 1375 spdk_blob_id blobid; 1376 uint32_t page_num; 1377 int index; 1378 struct spdk_blob_md_page *page; 1379 1380 dev = init_dev(); 1381 1382 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1383 CU_ASSERT(g_bserrno == 0); 1384 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1385 bs = g_bs; 1386 1387 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1388 CU_ASSERT(g_bserrno == 0); 1389 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1390 blobid = g_blobid; 1391 1392 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1393 CU_ASSERT(g_bserrno == 0); 1394 CU_ASSERT(g_blob != NULL); 1395 blob = g_blob; 1396 1397 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1398 CU_ASSERT(g_bserrno == 0); 1399 CU_ASSERT(blob == NULL); 1400 1401 page_num = _spdk_bs_blobid_to_page(blobid); 1402 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1403 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1404 page->crc = 0; 1405 1406 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1407 CU_ASSERT(g_bserrno == -EINVAL); 1408 CU_ASSERT(g_blob == NULL); 1409 g_bserrno = 0; 1410 1411 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 1412 CU_ASSERT(g_bserrno == -EINVAL); 1413 1414 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1415 CU_ASSERT(g_bserrno == 0); 1416 g_bs = NULL; 1417 } 1418 1419 static void 1420 super_block_crc(void) 1421 { 1422 struct spdk_bs_dev *dev; 1423 struct spdk_bs_super_block *super_block; 1424 struct spdk_bs_opts opts; 1425 1426 dev = init_dev(); 1427 spdk_bs_opts_init(&opts); 1428 1429 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1430 CU_ASSERT(g_bserrno == 0); 1431 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1432 1433 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1434 CU_ASSERT(g_bserrno == 0); 1435 g_bs = NULL; 1436 1437 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1438 super_block->crc = 0; 1439 dev = init_dev(); 1440 1441 g_scheduler_delay = true; 1442 /* Load an existing blob store */ 1443 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1444 1445 CU_ASSERT(g_bserrno == -EILSEQ); 1446 _bs_flush_scheduler(); 1447 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1448 1449 g_scheduler_delay = false; 1450 } 1451 1452 int main(int argc, char **argv) 1453 { 1454 CU_pSuite suite = NULL; 1455 unsigned int num_failures; 1456 1457 if (CU_initialize_registry() != CUE_SUCCESS) { 1458 return CU_get_error(); 1459 } 1460 1461 suite = CU_add_suite("blob", NULL, NULL); 1462 if (suite == NULL) { 1463 CU_cleanup_registry(); 1464 return CU_get_error(); 1465 } 1466 1467 if ( 1468 CU_add_test(suite, "blob_init", blob_init) == NULL || 1469 CU_add_test(suite, "blob_open", blob_open) == NULL || 1470 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 1471 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 1472 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 1473 CU_add_test(suite, "blob_super", blob_super) == NULL || 1474 CU_add_test(suite, "blob_write", blob_write) == NULL || 1475 CU_add_test(suite, "blob_read", blob_read) == NULL || 1476 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 1477 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 1478 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 1479 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 1480 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 1481 CU_add_test(suite, "bs_load", bs_load) == NULL || 1482 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 1483 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 1484 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 1485 CU_add_test(suite, "bs_type", bs_type) == NULL || 1486 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 1487 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 1488 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 1489 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL 1490 ) { 1491 CU_cleanup_registry(); 1492 return CU_get_error(); 1493 } 1494 1495 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 1496 spdk_allocate_thread(_bs_send_msg, NULL, "thread0"); 1497 CU_basic_set_mode(CU_BRM_VERBOSE); 1498 CU_basic_run_tests(); 1499 num_failures = CU_get_number_of_failures(); 1500 CU_cleanup_registry(); 1501 spdk_free_thread(); 1502 free(g_dev_buffer); 1503 return num_failures; 1504 } 1505