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