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 struct spdk_blob_store *bs; 1116 spdk_blob_id blobid; 1117 struct spdk_blob *blob; 1118 1119 dev = init_dev(); 1120 1121 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1122 CU_ASSERT(g_bserrno == 0); 1123 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1124 bs = g_bs; 1125 1126 /* Create a blob and open it. */ 1127 g_bserrno = -1; 1128 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1129 CU_ASSERT(g_bserrno == 0); 1130 CU_ASSERT(g_blobid > 0); 1131 blobid = g_blobid; 1132 1133 g_bserrno = -1; 1134 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1135 CU_ASSERT(g_bserrno == 0); 1136 CU_ASSERT(g_blob != NULL); 1137 blob = g_blob; 1138 1139 /* Try to unload blobstore, should fail with open blob */ 1140 g_bserrno = -1; 1141 spdk_bs_unload(bs, bs_op_complete, NULL); 1142 CU_ASSERT(g_bserrno == -EBUSY); 1143 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1144 1145 /* Close the blob, then successfully unload blobstore */ 1146 g_bserrno = -1; 1147 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1148 CU_ASSERT(g_bserrno == 0); 1149 CU_ASSERT(blob == NULL); 1150 1151 g_bserrno = -1; 1152 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1153 CU_ASSERT(g_bserrno == 0); 1154 g_bs = NULL; 1155 } 1156 1157 /* 1158 * Create a blobstore with a cluster size different than the default, and ensure it is 1159 * persisted. 1160 */ 1161 static void 1162 bs_cluster_sz(void) 1163 { 1164 struct spdk_bs_dev *dev; 1165 struct spdk_bs_opts opts; 1166 uint32_t cluster_sz; 1167 1168 /* Set cluster size to zero */ 1169 dev = init_dev(); 1170 spdk_bs_opts_init(&opts); 1171 opts.cluster_sz = 0; 1172 1173 /* Initialize a new blob store */ 1174 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1175 CU_ASSERT(g_bserrno == -EINVAL); 1176 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1177 1178 /* 1179 * Set cluster size to blobstore page size, 1180 * to work it is required to be at least twice the blobstore page size. 1181 */ 1182 dev = init_dev(); 1183 spdk_bs_opts_init(&opts); 1184 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1185 1186 /* Initialize a new blob store */ 1187 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1188 CU_ASSERT(g_bserrno == -ENOMEM); 1189 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1190 1191 /* Set cluster size to twice the default */ 1192 dev = init_dev(); 1193 spdk_bs_opts_init(&opts); 1194 opts.cluster_sz *= 2; 1195 cluster_sz = opts.cluster_sz; 1196 1197 /* Initialize a new blob store */ 1198 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1199 CU_ASSERT(g_bserrno == 0); 1200 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1201 1202 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1203 1204 /* Unload the blob store */ 1205 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1206 CU_ASSERT(g_bserrno == 0); 1207 g_bs = NULL; 1208 g_blob = NULL; 1209 g_blobid = 0; 1210 1211 dev = init_dev(); 1212 /* Load an existing blob store */ 1213 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1214 CU_ASSERT(g_bserrno == 0); 1215 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1216 1217 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1218 1219 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1220 CU_ASSERT(g_bserrno == 0); 1221 g_bs = NULL; 1222 } 1223 1224 /* 1225 * Test resizing of the metadata blob. This requires creating enough blobs 1226 * so that one cluster is not enough to fit the metadata for those blobs. 1227 * To induce this condition to happen more quickly, we reduce the cluster 1228 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1229 */ 1230 static void 1231 bs_resize_md(void) 1232 { 1233 const int CLUSTER_PAGE_COUNT = 4; 1234 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1235 struct spdk_bs_dev *dev; 1236 struct spdk_bs_opts opts; 1237 uint32_t cluster_sz; 1238 spdk_blob_id blobids[NUM_BLOBS]; 1239 int i; 1240 1241 1242 dev = init_dev(); 1243 spdk_bs_opts_init(&opts); 1244 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1245 cluster_sz = opts.cluster_sz; 1246 1247 /* Initialize a new blob store */ 1248 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1249 CU_ASSERT(g_bserrno == 0); 1250 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1251 1252 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1253 1254 for (i = 0; i < NUM_BLOBS; i++) { 1255 g_bserrno = -1; 1256 g_blobid = SPDK_BLOBID_INVALID; 1257 spdk_bs_md_create_blob(g_bs, 1258 blob_op_with_id_complete, NULL); 1259 CU_ASSERT(g_bserrno == 0); 1260 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1261 blobids[i] = g_blobid; 1262 } 1263 1264 /* Unload the blob store */ 1265 g_bserrno = -1; 1266 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1267 CU_ASSERT(g_bserrno == 0); 1268 1269 /* Load an existing blob store */ 1270 g_bserrno = -1; 1271 g_bs = NULL; 1272 dev = init_dev(); 1273 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1274 CU_ASSERT(g_bserrno == 0); 1275 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1276 1277 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1278 1279 for (i = 0; i < NUM_BLOBS; i++) { 1280 g_bserrno = -1; 1281 g_blob = NULL; 1282 spdk_bs_md_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1283 CU_ASSERT(g_bserrno == 0); 1284 CU_ASSERT(g_blob != NULL); 1285 g_bserrno = -1; 1286 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1287 CU_ASSERT(g_bserrno == 0); 1288 } 1289 1290 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1291 CU_ASSERT(g_bserrno == 0); 1292 g_bs = NULL; 1293 } 1294 1295 static void 1296 bs_destroy(void) 1297 { 1298 struct spdk_bs_dev *dev; 1299 struct spdk_bs_opts opts; 1300 1301 g_scheduler_delay = true; 1302 1303 _bs_flush_scheduler(); 1304 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1305 1306 /* Initialize a new blob store */ 1307 dev = init_dev(); 1308 spdk_bs_opts_init(&opts); 1309 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1310 CU_ASSERT(g_bserrno == 0); 1311 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1312 1313 /* Destroy the blob store */ 1314 g_bserrno = -1; 1315 spdk_bs_destroy(g_bs, 0, bs_op_complete, NULL); 1316 /* Callback is called after device is destroyed in next scheduler run. */ 1317 _bs_flush_scheduler(); 1318 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1319 CU_ASSERT(g_bserrno == 0); 1320 1321 /* Loading an non-existent blob store should fail. */ 1322 g_bserrno = -1; 1323 g_bs = NULL; 1324 dev = init_dev(); 1325 1326 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1327 CU_ASSERT(g_bserrno != 0); 1328 g_scheduler_delay = false; 1329 } 1330 1331 /* Try to hit all of the corner cases associated with serializing 1332 * a blob to disk 1333 */ 1334 static void 1335 blob_serialize(void) 1336 { 1337 struct spdk_bs_dev *dev; 1338 struct spdk_bs_opts opts; 1339 struct spdk_blob_store *bs; 1340 spdk_blob_id blobid[2]; 1341 struct spdk_blob *blob[2]; 1342 uint64_t i; 1343 char *value; 1344 int rc; 1345 1346 dev = init_dev(); 1347 1348 /* Initialize a new blobstore with very small clusters */ 1349 spdk_bs_opts_init(&opts); 1350 opts.cluster_sz = dev->blocklen * 8; 1351 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1352 CU_ASSERT(g_bserrno == 0); 1353 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1354 bs = g_bs; 1355 1356 /* Create and open two blobs */ 1357 for (i = 0; i < 2; i++) { 1358 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1359 CU_ASSERT(g_bserrno == 0); 1360 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1361 blobid[i] = g_blobid; 1362 1363 /* Open a blob */ 1364 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1365 CU_ASSERT(g_bserrno == 0); 1366 CU_ASSERT(g_blob != NULL); 1367 blob[i] = g_blob; 1368 1369 /* Set a fairly large xattr on both blobs to eat up 1370 * metadata space 1371 */ 1372 value = calloc(dev->blocklen - 64, sizeof(char)); 1373 SPDK_CU_ASSERT_FATAL(value != NULL); 1374 memset(value, i, dev->blocklen / 2); 1375 rc = spdk_blob_md_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1376 CU_ASSERT(rc == 0); 1377 free(value); 1378 } 1379 1380 /* Resize the blobs, alternating 1 cluster at a time. 1381 * This thwarts run length encoding and will cause spill 1382 * over of the extents. 1383 */ 1384 for (i = 0; i < 6; i++) { 1385 rc = spdk_bs_md_resize_blob(blob[i % 2], (i / 2) + 1); 1386 CU_ASSERT(rc == 0); 1387 } 1388 1389 for (i = 0; i < 2; i++) { 1390 spdk_bs_md_sync_blob(blob[i], blob_op_complete, NULL); 1391 CU_ASSERT(g_bserrno == 0); 1392 } 1393 1394 /* Close the blobs */ 1395 for (i = 0; i < 2; i++) { 1396 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1397 CU_ASSERT(g_bserrno == 0); 1398 } 1399 1400 /* Unload the blobstore */ 1401 spdk_bs_unload(bs, bs_op_complete, NULL); 1402 CU_ASSERT(g_bserrno == 0); 1403 g_bs = NULL; 1404 g_blob = NULL; 1405 g_blobid = 0; 1406 bs = NULL; 1407 1408 dev = init_dev(); 1409 /* Load an existing blob store */ 1410 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1411 CU_ASSERT(g_bserrno == 0); 1412 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1413 bs = g_bs; 1414 1415 for (i = 0; i < 2; i++) { 1416 blob[i] = NULL; 1417 1418 spdk_bs_md_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1419 CU_ASSERT(g_bserrno == 0); 1420 CU_ASSERT(g_blob != NULL); 1421 blob[i] = g_blob; 1422 1423 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1424 1425 spdk_bs_md_close_blob(&blob[i], blob_op_complete, NULL); 1426 CU_ASSERT(g_bserrno == 0); 1427 } 1428 1429 spdk_bs_unload(bs, bs_op_complete, NULL); 1430 CU_ASSERT(g_bserrno == 0); 1431 g_bs = NULL; 1432 } 1433 1434 static void 1435 blob_crc(void) 1436 { 1437 struct spdk_blob_store *bs; 1438 struct spdk_bs_dev *dev; 1439 struct spdk_blob *blob; 1440 spdk_blob_id blobid; 1441 uint32_t page_num; 1442 int index; 1443 struct spdk_blob_md_page *page; 1444 1445 dev = init_dev(); 1446 1447 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1448 CU_ASSERT(g_bserrno == 0); 1449 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1450 bs = g_bs; 1451 1452 spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL); 1453 CU_ASSERT(g_bserrno == 0); 1454 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1455 blobid = g_blobid; 1456 1457 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1458 CU_ASSERT(g_bserrno == 0); 1459 CU_ASSERT(g_blob != NULL); 1460 blob = g_blob; 1461 1462 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1463 CU_ASSERT(g_bserrno == 0); 1464 CU_ASSERT(blob == NULL); 1465 1466 page_num = _spdk_bs_blobid_to_page(blobid); 1467 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1468 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1469 page->crc = 0; 1470 1471 spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1472 CU_ASSERT(g_bserrno == -EINVAL); 1473 CU_ASSERT(g_blob == NULL); 1474 g_bserrno = 0; 1475 1476 spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL); 1477 CU_ASSERT(g_bserrno == -EINVAL); 1478 1479 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1480 CU_ASSERT(g_bserrno == 0); 1481 g_bs = NULL; 1482 } 1483 1484 static void 1485 super_block_crc(void) 1486 { 1487 struct spdk_bs_dev *dev; 1488 struct spdk_bs_super_block *super_block; 1489 struct spdk_bs_opts opts; 1490 1491 dev = init_dev(); 1492 spdk_bs_opts_init(&opts); 1493 1494 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1495 CU_ASSERT(g_bserrno == 0); 1496 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1497 1498 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1499 CU_ASSERT(g_bserrno == 0); 1500 g_bs = NULL; 1501 1502 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1503 super_block->crc = 0; 1504 dev = init_dev(); 1505 1506 g_scheduler_delay = true; 1507 /* Load an existing blob store */ 1508 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1509 1510 CU_ASSERT(g_bserrno == -EILSEQ); 1511 _bs_flush_scheduler(); 1512 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1513 1514 g_scheduler_delay = false; 1515 } 1516 1517 /* For blob dirty shutdown test case we do the following sub-test cases: 1518 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 1519 * dirty shutdown and reload the blob store and verify the xattrs. 1520 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 1521 * reload the blob store and verify the clusters number. 1522 * 3 Create the second blob and then dirty shutdown, reload the blob store 1523 * and verify the second blob. 1524 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 1525 * and verify the second blob is invalid. 1526 * 5 Create the second blob again and also create the third blob, modify the 1527 * md of second blob which makes the md invalid, and then dirty shutdown, 1528 * reload the blob store verify the second blob, it should invalid and also 1529 * verify the third blob, it should correct. 1530 */ 1531 static void 1532 blob_dirty_shutdown(void) 1533 { 1534 int rc; 1535 int index; 1536 struct spdk_bs_dev *dev; 1537 spdk_blob_id blobid1, blobid2, blobid3; 1538 struct spdk_blob *blob; 1539 uint64_t length; 1540 const void *value; 1541 size_t value_len; 1542 uint32_t page_num; 1543 struct spdk_blob_md_page *page; 1544 struct spdk_bs_opts opts; 1545 1546 dev = init_dev(); 1547 spdk_bs_opts_init(&opts); 1548 /* Initialize a new blob store */ 1549 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1550 CU_ASSERT(g_bserrno == 0); 1551 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1552 1553 /* Create first blob */ 1554 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1555 CU_ASSERT(g_bserrno == 0); 1556 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1557 blobid1 = g_blobid; 1558 1559 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1560 CU_ASSERT(g_bserrno == 0); 1561 CU_ASSERT(g_blob != NULL); 1562 blob = g_blob; 1563 1564 /* Set some xattrs */ 1565 rc = spdk_blob_md_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1566 CU_ASSERT(rc == 0); 1567 1568 length = 2345; 1569 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1570 CU_ASSERT(rc == 0); 1571 1572 /* Resize the blob */ 1573 rc = spdk_bs_md_resize_blob(blob, 10); 1574 CU_ASSERT(rc == 0); 1575 1576 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1577 blob = NULL; 1578 g_blob = NULL; 1579 g_blobid = SPDK_BLOBID_INVALID; 1580 1581 /* Dirty shutdown */ 1582 _spdk_bs_free(g_bs); 1583 1584 /* reload blobstore */ 1585 dev = init_dev(); 1586 spdk_bs_opts_init(&opts); 1587 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1588 CU_ASSERT(g_bserrno == 0); 1589 1590 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1591 CU_ASSERT(g_bserrno == 0); 1592 CU_ASSERT(g_blob != NULL); 1593 blob = g_blob; 1594 1595 /* Get the xattrs */ 1596 value = NULL; 1597 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 1598 CU_ASSERT(rc == 0); 1599 SPDK_CU_ASSERT_FATAL(value != NULL); 1600 CU_ASSERT(*(uint64_t *)value == length); 1601 CU_ASSERT(value_len == 8); 1602 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1603 1604 /* Resize the blob */ 1605 rc = spdk_bs_md_resize_blob(blob, 20); 1606 CU_ASSERT(rc == 0); 1607 1608 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1609 CU_ASSERT(g_bserrno == 0); 1610 blob = NULL; 1611 g_blob = NULL; 1612 g_blobid = SPDK_BLOBID_INVALID; 1613 1614 /* Dirty shutdown */ 1615 _spdk_bs_free(g_bs); 1616 1617 /* reload the blobstore */ 1618 dev = init_dev(); 1619 spdk_bs_opts_init(&opts); 1620 /* Load an existing blob store */ 1621 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1622 CU_ASSERT(g_bserrno == 0); 1623 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1624 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1625 CU_ASSERT(g_bserrno == 0); 1626 CU_ASSERT(g_blob != NULL); 1627 blob = g_blob; 1628 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 1629 1630 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1631 CU_ASSERT(g_bserrno == 0); 1632 blob = NULL; 1633 g_blob = NULL; 1634 g_blobid = SPDK_BLOBID_INVALID; 1635 1636 /* Create second blob */ 1637 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1638 CU_ASSERT(g_bserrno == 0); 1639 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1640 blobid2 = g_blobid; 1641 1642 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1643 CU_ASSERT(g_bserrno == 0); 1644 CU_ASSERT(g_blob != NULL); 1645 blob = g_blob; 1646 1647 /* Set some xattrs */ 1648 rc = spdk_blob_md_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1649 CU_ASSERT(rc == 0); 1650 1651 length = 5432; 1652 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1653 CU_ASSERT(rc == 0); 1654 1655 /* Resize the blob */ 1656 rc = spdk_bs_md_resize_blob(blob, 10); 1657 CU_ASSERT(rc == 0); 1658 1659 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1660 blob = NULL; 1661 g_blob = NULL; 1662 g_blobid = SPDK_BLOBID_INVALID; 1663 1664 /* Dirty shutdown */ 1665 _spdk_bs_free(g_bs); 1666 1667 /* reload the blobstore */ 1668 dev = init_dev(); 1669 spdk_bs_opts_init(&opts); 1670 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1671 CU_ASSERT(g_bserrno == 0); 1672 1673 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1674 CU_ASSERT(g_bserrno == 0); 1675 CU_ASSERT(g_blob != NULL); 1676 blob = g_blob; 1677 1678 /* Get the xattrs */ 1679 value = NULL; 1680 rc = spdk_bs_md_get_xattr_value(blob, "length", &value, &value_len); 1681 CU_ASSERT(rc == 0); 1682 SPDK_CU_ASSERT_FATAL(value != NULL); 1683 CU_ASSERT(*(uint64_t *)value == length); 1684 CU_ASSERT(value_len == 8); 1685 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1686 1687 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1688 CU_ASSERT(g_bserrno == 0); 1689 spdk_bs_md_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 1690 CU_ASSERT(g_bserrno == 0); 1691 1692 /* Dirty shutdown */ 1693 _spdk_bs_free(g_bs); 1694 /* reload the blobstore */ 1695 dev = init_dev(); 1696 spdk_bs_opts_init(&opts); 1697 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1698 CU_ASSERT(g_bserrno == 0); 1699 1700 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1701 CU_ASSERT(g_bserrno != 0); 1702 CU_ASSERT(g_blob == NULL); 1703 1704 spdk_bs_md_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1705 CU_ASSERT(g_bserrno == 0); 1706 CU_ASSERT(g_blob != NULL); 1707 spdk_bs_md_close_blob(&g_blob, blob_op_complete, NULL); 1708 CU_ASSERT(g_bserrno == 0); 1709 1710 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1711 CU_ASSERT(g_bserrno == 0); 1712 g_bs = NULL; 1713 1714 /* reload the blobstore */ 1715 dev = init_dev(); 1716 spdk_bs_opts_init(&opts); 1717 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1718 CU_ASSERT(g_bserrno == 0); 1719 1720 /* Create second blob */ 1721 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1722 CU_ASSERT(g_bserrno == 0); 1723 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1724 blobid2 = g_blobid; 1725 1726 /* Create third blob */ 1727 spdk_bs_md_create_blob(g_bs, blob_op_with_id_complete, NULL); 1728 CU_ASSERT(g_bserrno == 0); 1729 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1730 blobid3 = g_blobid; 1731 1732 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1733 CU_ASSERT(g_bserrno == 0); 1734 CU_ASSERT(g_blob != NULL); 1735 blob = g_blob; 1736 1737 /* Set some xattrs for second blob */ 1738 rc = spdk_blob_md_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1739 CU_ASSERT(rc == 0); 1740 1741 length = 5432; 1742 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1743 CU_ASSERT(rc == 0); 1744 1745 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1746 blob = NULL; 1747 g_blob = NULL; 1748 g_blobid = SPDK_BLOBID_INVALID; 1749 1750 spdk_bs_md_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 1751 CU_ASSERT(g_bserrno == 0); 1752 CU_ASSERT(g_blob != NULL); 1753 blob = g_blob; 1754 1755 /* Set some xattrs for third blob */ 1756 rc = spdk_blob_md_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 1757 CU_ASSERT(rc == 0); 1758 1759 length = 5432; 1760 rc = spdk_blob_md_set_xattr(blob, "length", &length, sizeof(length)); 1761 CU_ASSERT(rc == 0); 1762 1763 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1764 blob = NULL; 1765 g_blob = NULL; 1766 g_blobid = SPDK_BLOBID_INVALID; 1767 1768 /* Mark second blob as invalid */ 1769 page_num = _spdk_bs_blobid_to_page(blobid2); 1770 1771 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 1772 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1773 page->sequence_num = 1; 1774 page->crc = _spdk_blob_md_page_calc_crc(page); 1775 1776 /* Dirty shutdown */ 1777 _spdk_bs_free(g_bs); 1778 /* reload the blobstore */ 1779 dev = init_dev(); 1780 spdk_bs_opts_init(&opts); 1781 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1782 CU_ASSERT(g_bserrno == 0); 1783 1784 spdk_bs_md_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1785 CU_ASSERT(g_bserrno != 0); 1786 CU_ASSERT(g_blob == NULL); 1787 1788 spdk_bs_md_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 1789 CU_ASSERT(g_bserrno == 0); 1790 CU_ASSERT(g_blob != NULL); 1791 blob = g_blob; 1792 1793 spdk_bs_md_close_blob(&blob, blob_op_complete, NULL); 1794 blob = NULL; 1795 g_blob = NULL; 1796 g_blobid = SPDK_BLOBID_INVALID; 1797 1798 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1799 CU_ASSERT(g_bserrno == 0); 1800 g_bs = NULL; 1801 } 1802 1803 int main(int argc, char **argv) 1804 { 1805 CU_pSuite suite = NULL; 1806 unsigned int num_failures; 1807 1808 if (CU_initialize_registry() != CUE_SUCCESS) { 1809 return CU_get_error(); 1810 } 1811 1812 suite = CU_add_suite("blob", NULL, NULL); 1813 if (suite == NULL) { 1814 CU_cleanup_registry(); 1815 return CU_get_error(); 1816 } 1817 1818 if ( 1819 CU_add_test(suite, "blob_init", blob_init) == NULL || 1820 CU_add_test(suite, "blob_open", blob_open) == NULL || 1821 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 1822 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 1823 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 1824 CU_add_test(suite, "blob_super", blob_super) == NULL || 1825 CU_add_test(suite, "blob_write", blob_write) == NULL || 1826 CU_add_test(suite, "blob_read", blob_read) == NULL || 1827 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 1828 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 1829 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 1830 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 1831 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 1832 CU_add_test(suite, "bs_load", bs_load) == NULL || 1833 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 1834 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 1835 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 1836 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 1837 CU_add_test(suite, "bs_type", bs_type) == NULL || 1838 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 1839 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 1840 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 1841 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 1842 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL 1843 ) { 1844 CU_cleanup_registry(); 1845 return CU_get_error(); 1846 } 1847 1848 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 1849 spdk_allocate_thread(_bs_send_msg, NULL, "thread0"); 1850 CU_basic_set_mode(CU_BRM_VERBOSE); 1851 CU_basic_run_tests(); 1852 num_failures = CU_get_number_of_failures(); 1853 CU_cleanup_registry(); 1854 spdk_free_thread(); 1855 free(g_dev_buffer); 1856 return num_failures; 1857 } 1858