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_create_blob(bs, blob_op_with_id_complete, NULL); 189 CU_ASSERT(g_bserrno == 0); 190 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 191 blobid = g_blobid; 192 193 /* Set the blob as the super blob */ 194 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 195 CU_ASSERT(g_bserrno == 0); 196 197 /* Get the super blob */ 198 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 199 CU_ASSERT(g_bserrno == 0); 200 CU_ASSERT(blobid == g_blobid); 201 202 spdk_bs_unload(g_bs, bs_op_complete, NULL); 203 CU_ASSERT(g_bserrno == 0); 204 g_bs = NULL; 205 } 206 207 static void 208 blob_open(void) 209 { 210 struct spdk_blob_store *bs; 211 struct spdk_bs_dev *dev; 212 struct spdk_blob *blob; 213 spdk_blob_id blobid, blobid2; 214 215 dev = init_dev(); 216 217 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 218 CU_ASSERT(g_bserrno == 0); 219 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 220 bs = g_bs; 221 222 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 223 CU_ASSERT(g_bserrno == 0); 224 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 225 blobid = g_blobid; 226 227 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 228 CU_ASSERT(g_bserrno == 0); 229 CU_ASSERT(g_blob != NULL); 230 blob = g_blob; 231 232 blobid2 = spdk_blob_get_id(blob); 233 CU_ASSERT(blobid == blobid2); 234 235 /* Try to open file again. It should return success. */ 236 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 237 CU_ASSERT(g_bserrno == 0); 238 CU_ASSERT(blob == g_blob); 239 240 spdk_blob_close(blob, blob_op_complete, NULL); 241 CU_ASSERT(g_bserrno == 0); 242 243 /* 244 * Close the file a second time, releasing the second reference. This 245 * should succeed. 246 */ 247 blob = g_blob; 248 spdk_blob_close(blob, blob_op_complete, NULL); 249 CU_ASSERT(g_bserrno == 0); 250 251 /* 252 * Try to open file again. It should succeed. This tests the case 253 * where the file is opened, closed, then re-opened again. 254 */ 255 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 256 CU_ASSERT(g_bserrno == 0); 257 CU_ASSERT(g_blob != NULL); 258 blob = g_blob; 259 260 spdk_blob_close(blob, blob_op_complete, NULL); 261 CU_ASSERT(g_bserrno == 0); 262 263 spdk_bs_unload(g_bs, bs_op_complete, NULL); 264 CU_ASSERT(g_bserrno == 0); 265 g_bs = NULL; 266 } 267 268 static void 269 blob_create(void) 270 { 271 struct spdk_blob_store *bs; 272 struct spdk_bs_dev *dev; 273 struct spdk_blob *blob; 274 struct spdk_blob_opts opts; 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 blob with 10 clusters */ 285 286 spdk_blob_opts_init(&opts); 287 opts.num_clusters = 10; 288 289 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 290 CU_ASSERT(g_bserrno == 0); 291 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 292 blobid = g_blobid; 293 294 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 295 CU_ASSERT(g_bserrno == 0); 296 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 297 blob = g_blob; 298 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 299 300 spdk_blob_close(blob, blob_op_complete, NULL); 301 CU_ASSERT(g_bserrno == 0); 302 303 /* Create blob with 0 clusters */ 304 305 spdk_blob_opts_init(&opts); 306 opts.num_clusters = 0; 307 308 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 309 CU_ASSERT(g_bserrno == 0); 310 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 311 blobid = g_blobid; 312 313 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 314 CU_ASSERT(g_bserrno == 0); 315 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 316 blob = g_blob; 317 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 318 319 spdk_blob_close(blob, blob_op_complete, NULL); 320 CU_ASSERT(g_bserrno == 0); 321 322 /* Create blob with default options (opts == NULL) */ 323 324 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 325 CU_ASSERT(g_bserrno == 0); 326 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 327 blobid = g_blobid; 328 329 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 330 CU_ASSERT(g_bserrno == 0); 331 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 332 blob = g_blob; 333 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 334 335 spdk_blob_close(blob, blob_op_complete, NULL); 336 CU_ASSERT(g_bserrno == 0); 337 338 spdk_bs_unload(g_bs, bs_op_complete, NULL); 339 CU_ASSERT(g_bserrno == 0); 340 g_bs = NULL; 341 } 342 static void 343 blob_delete(void) 344 { 345 struct spdk_blob_store *bs; 346 struct spdk_bs_dev *dev; 347 spdk_blob_id blobid; 348 349 dev = init_dev(); 350 351 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 352 CU_ASSERT(g_bserrno == 0); 353 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 354 bs = g_bs; 355 356 /* Create a blob and then delete it. */ 357 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 358 CU_ASSERT(g_bserrno == 0); 359 CU_ASSERT(g_blobid > 0); 360 blobid = g_blobid; 361 362 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 363 CU_ASSERT(g_bserrno == 0); 364 365 /* Try to open the blob */ 366 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 367 CU_ASSERT(g_bserrno == -ENOENT); 368 369 spdk_bs_unload(g_bs, bs_op_complete, NULL); 370 CU_ASSERT(g_bserrno == 0); 371 g_bs = NULL; 372 } 373 374 static void 375 blob_resize(void) 376 { 377 struct spdk_blob_store *bs; 378 struct spdk_bs_dev *dev; 379 struct spdk_blob *blob; 380 spdk_blob_id blobid; 381 uint64_t free_clusters; 382 int rc; 383 384 dev = init_dev(); 385 386 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 387 CU_ASSERT(g_bserrno == 0); 388 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 389 bs = g_bs; 390 free_clusters = spdk_bs_free_cluster_count(bs); 391 392 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 393 CU_ASSERT(g_bserrno == 0); 394 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 395 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 396 blobid = g_blobid; 397 398 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 399 CU_ASSERT(g_bserrno == 0); 400 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 401 blob = g_blob; 402 403 /* Confirm that resize fails if blob is marked read-only. */ 404 __blob_to_data(blob)->md_ro = true; 405 rc = spdk_blob_resize(blob, 5); 406 CU_ASSERT(rc == -EPERM); 407 __blob_to_data(blob)->md_ro = false; 408 409 /* The blob started at 0 clusters. Resize it to be 5. */ 410 rc = spdk_blob_resize(blob, 5); 411 CU_ASSERT(rc == 0); 412 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 413 414 /* Shrink the blob to 3 clusters. This will not actually release 415 * the old clusters until the blob is synced. 416 */ 417 rc = spdk_blob_resize(blob, 3); 418 CU_ASSERT(rc == 0); 419 /* Verify there are still 5 clusters in use */ 420 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 421 422 spdk_blob_sync_md(blob, blob_op_complete, NULL); 423 CU_ASSERT(g_bserrno == 0); 424 /* Now there are only 3 clusters in use */ 425 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 426 427 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 428 rc = spdk_blob_resize(blob, 10); 429 CU_ASSERT(rc == 0); 430 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 431 432 spdk_blob_close(blob, blob_op_complete, NULL); 433 CU_ASSERT(g_bserrno == 0); 434 435 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 436 CU_ASSERT(g_bserrno == 0); 437 438 spdk_bs_unload(g_bs, bs_op_complete, NULL); 439 CU_ASSERT(g_bserrno == 0); 440 g_bs = NULL; 441 } 442 443 static void 444 channel_ops(void) 445 { 446 struct spdk_blob_store *bs; 447 struct spdk_bs_dev *dev; 448 struct spdk_io_channel *channel; 449 450 dev = init_dev(); 451 452 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 453 CU_ASSERT(g_bserrno == 0); 454 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 455 bs = g_bs; 456 457 channel = spdk_bs_alloc_io_channel(bs); 458 CU_ASSERT(channel != NULL); 459 460 spdk_bs_free_io_channel(channel); 461 462 spdk_bs_unload(g_bs, bs_op_complete, NULL); 463 CU_ASSERT(g_bserrno == 0); 464 g_bs = NULL; 465 } 466 467 static void 468 blob_write(void) 469 { 470 struct spdk_blob_store *bs; 471 struct spdk_bs_dev *dev; 472 struct spdk_blob *blob; 473 struct spdk_io_channel *channel; 474 spdk_blob_id blobid; 475 uint64_t pages_per_cluster; 476 uint8_t payload[10 * 4096]; 477 int rc; 478 479 dev = init_dev(); 480 481 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 482 CU_ASSERT(g_bserrno == 0); 483 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 484 bs = g_bs; 485 486 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 487 488 channel = spdk_bs_alloc_io_channel(bs); 489 CU_ASSERT(channel != NULL); 490 491 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 492 CU_ASSERT(g_bserrno == 0); 493 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 494 blobid = g_blobid; 495 496 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 497 CU_ASSERT(g_bserrno == 0); 498 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 499 blob = g_blob; 500 501 /* Write to a blob with 0 size */ 502 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 503 CU_ASSERT(g_bserrno == -EINVAL); 504 505 /* Resize the blob */ 506 rc = spdk_blob_resize(blob, 5); 507 CU_ASSERT(rc == 0); 508 509 /* Confirm that write fails if blob is marked read-only. */ 510 __blob_to_data(blob)->data_ro = true; 511 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 512 CU_ASSERT(g_bserrno == -EPERM); 513 __blob_to_data(blob)->data_ro = false; 514 515 /* Write to the blob */ 516 spdk_bs_io_write_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 517 CU_ASSERT(g_bserrno == 0); 518 519 /* Write starting beyond the end */ 520 spdk_bs_io_write_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 521 NULL); 522 CU_ASSERT(g_bserrno == -EINVAL); 523 524 /* Write starting at a valid location but going off the end */ 525 spdk_bs_io_write_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 526 blob_op_complete, NULL); 527 CU_ASSERT(g_bserrno == -EINVAL); 528 529 spdk_blob_close(blob, blob_op_complete, NULL); 530 CU_ASSERT(g_bserrno == 0); 531 532 spdk_bs_free_io_channel(channel); 533 534 spdk_bs_unload(g_bs, bs_op_complete, NULL); 535 CU_ASSERT(g_bserrno == 0); 536 g_bs = NULL; 537 } 538 539 static void 540 blob_read(void) 541 { 542 struct spdk_blob_store *bs; 543 struct spdk_bs_dev *dev; 544 struct spdk_blob *blob; 545 struct spdk_io_channel *channel; 546 spdk_blob_id blobid; 547 uint64_t pages_per_cluster; 548 uint8_t payload[10 * 4096]; 549 int rc; 550 551 dev = init_dev(); 552 553 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 554 CU_ASSERT(g_bserrno == 0); 555 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 556 bs = g_bs; 557 558 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 559 560 channel = spdk_bs_alloc_io_channel(bs); 561 CU_ASSERT(channel != NULL); 562 563 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 564 CU_ASSERT(g_bserrno == 0); 565 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 566 blobid = g_blobid; 567 568 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 569 CU_ASSERT(g_bserrno == 0); 570 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 571 blob = g_blob; 572 573 /* Read from a blob with 0 size */ 574 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 575 CU_ASSERT(g_bserrno == -EINVAL); 576 577 /* Resize the blob */ 578 rc = spdk_blob_resize(blob, 5); 579 CU_ASSERT(rc == 0); 580 581 /* Confirm that read passes if blob is marked read-only. */ 582 __blob_to_data(blob)->data_ro = true; 583 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 584 CU_ASSERT(g_bserrno == 0); 585 __blob_to_data(blob)->data_ro = false; 586 587 /* Read from the blob */ 588 spdk_bs_io_read_blob(blob, channel, payload, 0, 1, blob_op_complete, NULL); 589 CU_ASSERT(g_bserrno == 0); 590 591 /* Read starting beyond the end */ 592 spdk_bs_io_read_blob(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 593 NULL); 594 CU_ASSERT(g_bserrno == -EINVAL); 595 596 /* Read starting at a valid location but going off the end */ 597 spdk_bs_io_read_blob(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 598 blob_op_complete, NULL); 599 CU_ASSERT(g_bserrno == -EINVAL); 600 601 spdk_blob_close(blob, blob_op_complete, NULL); 602 CU_ASSERT(g_bserrno == 0); 603 604 spdk_bs_free_io_channel(channel); 605 606 spdk_bs_unload(g_bs, bs_op_complete, NULL); 607 CU_ASSERT(g_bserrno == 0); 608 g_bs = NULL; 609 } 610 611 static void 612 blob_rw_verify(void) 613 { 614 struct spdk_blob_store *bs; 615 struct spdk_bs_dev *dev; 616 struct spdk_blob *blob; 617 struct spdk_io_channel *channel; 618 spdk_blob_id blobid; 619 uint8_t payload_read[10 * 4096]; 620 uint8_t payload_write[10 * 4096]; 621 int rc; 622 623 dev = init_dev(); 624 625 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 626 CU_ASSERT(g_bserrno == 0); 627 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 628 bs = g_bs; 629 630 channel = spdk_bs_alloc_io_channel(bs); 631 CU_ASSERT(channel != NULL); 632 633 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 634 CU_ASSERT(g_bserrno == 0); 635 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 636 blobid = g_blobid; 637 638 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 639 CU_ASSERT(g_bserrno == 0); 640 CU_ASSERT(g_blob != NULL); 641 blob = g_blob; 642 643 rc = spdk_blob_resize(blob, 32); 644 CU_ASSERT(rc == 0); 645 646 memset(payload_write, 0xE5, sizeof(payload_write)); 647 spdk_bs_io_write_blob(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 648 CU_ASSERT(g_bserrno == 0); 649 650 memset(payload_read, 0x00, sizeof(payload_read)); 651 spdk_bs_io_read_blob(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 652 CU_ASSERT(g_bserrno == 0); 653 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 654 655 spdk_blob_close(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 void 666 blob_rw_verify_iov(void) 667 { 668 struct spdk_blob_store *bs; 669 struct spdk_bs_dev *dev; 670 struct spdk_blob *blob; 671 struct spdk_io_channel *channel; 672 spdk_blob_id blobid; 673 uint8_t payload_read[10 * 4096]; 674 uint8_t payload_write[10 * 4096]; 675 struct iovec iov_read[3]; 676 struct iovec iov_write[3]; 677 void *buf; 678 int rc; 679 680 dev = init_dev(); 681 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 682 683 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 684 CU_ASSERT(g_bserrno == 0); 685 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 686 bs = g_bs; 687 688 channel = spdk_bs_alloc_io_channel(bs); 689 CU_ASSERT(channel != NULL); 690 691 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 692 CU_ASSERT(g_bserrno == 0); 693 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 694 blobid = g_blobid; 695 696 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 697 CU_ASSERT(g_bserrno == 0); 698 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 699 blob = g_blob; 700 701 rc = spdk_blob_resize(blob, 2); 702 CU_ASSERT(rc == 0); 703 704 /* 705 * Manually adjust the offset of the blob's second cluster. This allows 706 * us to make sure that the readv/write code correctly accounts for I/O 707 * that cross cluster boundaries. Start by asserting that the allocated 708 * clusters are where we expect before modifying the second cluster. 709 */ 710 CU_ASSERT(__blob_to_data(blob)->active.clusters[0] == 1 * 256); 711 CU_ASSERT(__blob_to_data(blob)->active.clusters[1] == 2 * 256); 712 __blob_to_data(blob)->active.clusters[1] = 3 * 256; 713 714 memset(payload_write, 0xE5, sizeof(payload_write)); 715 iov_write[0].iov_base = payload_write; 716 iov_write[0].iov_len = 1 * 4096; 717 iov_write[1].iov_base = payload_write + 1 * 4096; 718 iov_write[1].iov_len = 5 * 4096; 719 iov_write[2].iov_base = payload_write + 6 * 4096; 720 iov_write[2].iov_len = 4 * 4096; 721 /* 722 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 723 * will get written to the first cluster, the last 4 to the second cluster. 724 */ 725 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 726 CU_ASSERT(g_bserrno == 0); 727 728 memset(payload_read, 0xAA, sizeof(payload_read)); 729 iov_read[0].iov_base = payload_read; 730 iov_read[0].iov_len = 3 * 4096; 731 iov_read[1].iov_base = payload_read + 3 * 4096; 732 iov_read[1].iov_len = 4 * 4096; 733 iov_read[2].iov_base = payload_read + 7 * 4096; 734 iov_read[2].iov_len = 3 * 4096; 735 spdk_bs_io_readv_blob(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 736 CU_ASSERT(g_bserrno == 0); 737 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 738 739 buf = calloc(1, 256 * 4096); 740 SPDK_CU_ASSERT_FATAL(buf != NULL); 741 /* Check that cluster 2 on "disk" was not modified. */ 742 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 743 free(buf); 744 745 spdk_blob_close(blob, blob_op_complete, NULL); 746 CU_ASSERT(g_bserrno == 0); 747 748 spdk_bs_free_io_channel(channel); 749 750 spdk_bs_unload(g_bs, bs_op_complete, NULL); 751 CU_ASSERT(g_bserrno == 0); 752 g_bs = NULL; 753 } 754 755 static uint32_t 756 bs_channel_get_req_count(struct spdk_io_channel *_channel) 757 { 758 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 759 struct spdk_bs_request_set *set; 760 uint32_t count = 0; 761 762 TAILQ_FOREACH(set, &channel->reqs, link) { 763 count++; 764 } 765 766 return count; 767 } 768 769 static void 770 blob_rw_verify_iov_nomem(void) 771 { 772 struct spdk_blob_store *bs; 773 struct spdk_bs_dev *dev; 774 struct spdk_blob *blob; 775 struct spdk_io_channel *channel; 776 spdk_blob_id blobid; 777 uint8_t payload_write[10 * 4096]; 778 struct iovec iov_write[3]; 779 uint32_t req_count; 780 int rc; 781 782 dev = init_dev(); 783 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 784 785 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 786 CU_ASSERT(g_bserrno == 0); 787 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 788 bs = g_bs; 789 790 channel = spdk_bs_alloc_io_channel(bs); 791 CU_ASSERT(channel != NULL); 792 793 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 794 CU_ASSERT(g_bserrno == 0); 795 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 796 blobid = g_blobid; 797 798 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 799 CU_ASSERT(g_bserrno == 0); 800 CU_ASSERT(g_blob != NULL); 801 blob = g_blob; 802 803 rc = spdk_blob_resize(blob, 2); 804 CU_ASSERT(rc == 0); 805 806 /* 807 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 808 * will get written to the first cluster, the last 4 to the second cluster. 809 */ 810 iov_write[0].iov_base = payload_write; 811 iov_write[0].iov_len = 1 * 4096; 812 iov_write[1].iov_base = payload_write + 1 * 4096; 813 iov_write[1].iov_len = 5 * 4096; 814 iov_write[2].iov_base = payload_write + 6 * 4096; 815 iov_write[2].iov_len = 4 * 4096; 816 MOCK_SET(calloc, void *, NULL); 817 req_count = bs_channel_get_req_count(channel); 818 spdk_bs_io_writev_blob(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 819 CU_ASSERT(g_bserrno = -ENOMEM); 820 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 821 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 822 823 spdk_blob_close(blob, blob_op_complete, NULL); 824 CU_ASSERT(g_bserrno == 0); 825 826 spdk_bs_free_io_channel(channel); 827 828 spdk_bs_unload(g_bs, bs_op_complete, NULL); 829 CU_ASSERT(g_bserrno == 0); 830 g_bs = NULL; 831 } 832 833 static void 834 blob_rw_iov_read_only(void) 835 { 836 struct spdk_blob_store *bs; 837 struct spdk_bs_dev *dev; 838 struct spdk_blob *blob; 839 struct spdk_io_channel *channel; 840 spdk_blob_id blobid; 841 uint8_t payload_read[4096]; 842 uint8_t payload_write[4096]; 843 struct iovec iov_read; 844 struct iovec iov_write; 845 int rc; 846 847 dev = init_dev(); 848 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 849 850 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 851 CU_ASSERT(g_bserrno == 0); 852 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 853 bs = g_bs; 854 855 channel = spdk_bs_alloc_io_channel(bs); 856 CU_ASSERT(channel != NULL); 857 858 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 859 CU_ASSERT(g_bserrno == 0); 860 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 861 blobid = g_blobid; 862 863 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 864 CU_ASSERT(g_bserrno == 0); 865 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 866 blob = g_blob; 867 868 rc = spdk_blob_resize(blob, 2); 869 CU_ASSERT(rc == 0); 870 871 /* Verify that writev failed if read_only flag is set. */ 872 __blob_to_data(blob)->data_ro = true; 873 iov_write.iov_base = payload_write; 874 iov_write.iov_len = sizeof(payload_write); 875 spdk_bs_io_writev_blob(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 876 CU_ASSERT(g_bserrno == -EPERM); 877 878 /* Verify that reads pass if data_ro flag is set. */ 879 iov_read.iov_base = payload_read; 880 iov_read.iov_len = sizeof(payload_read); 881 spdk_bs_io_readv_blob(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 882 CU_ASSERT(g_bserrno == 0); 883 884 spdk_blob_close(blob, blob_op_complete, NULL); 885 CU_ASSERT(g_bserrno == 0); 886 887 spdk_bs_free_io_channel(channel); 888 889 spdk_bs_unload(g_bs, bs_op_complete, NULL); 890 CU_ASSERT(g_bserrno == 0); 891 g_bs = NULL; 892 } 893 894 static void 895 blob_iter(void) 896 { 897 struct spdk_blob_store *bs; 898 struct spdk_bs_dev *dev; 899 struct spdk_blob *blob; 900 spdk_blob_id blobid; 901 902 dev = init_dev(); 903 904 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 905 CU_ASSERT(g_bserrno == 0); 906 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 907 bs = g_bs; 908 909 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 910 CU_ASSERT(g_blob == NULL); 911 CU_ASSERT(g_bserrno == -ENOENT); 912 913 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 914 CU_ASSERT(g_bserrno == 0); 915 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 916 blobid = g_blobid; 917 918 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 919 CU_ASSERT(g_blob != NULL); 920 CU_ASSERT(g_bserrno == 0); 921 blob = g_blob; 922 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 923 924 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 925 CU_ASSERT(g_blob == NULL); 926 CU_ASSERT(g_bserrno == -ENOENT); 927 928 spdk_bs_unload(g_bs, bs_op_complete, NULL); 929 CU_ASSERT(g_bserrno == 0); 930 g_bs = NULL; 931 } 932 933 static void 934 blob_xattr(void) 935 { 936 struct spdk_blob_store *bs; 937 struct spdk_bs_dev *dev; 938 struct spdk_blob *blob; 939 spdk_blob_id blobid; 940 uint64_t length; 941 int rc; 942 const char *name1, *name2; 943 const void *value; 944 size_t value_len; 945 struct spdk_xattr_names *names; 946 947 dev = init_dev(); 948 949 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 950 CU_ASSERT(g_bserrno == 0); 951 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 952 bs = g_bs; 953 954 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 955 CU_ASSERT(g_bserrno == 0); 956 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 957 blobid = g_blobid; 958 959 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 960 CU_ASSERT(g_bserrno == 0); 961 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 962 blob = g_blob; 963 964 /* Test that set_xattr fails if md_ro flag is set. */ 965 __blob_to_data(blob)->md_ro = true; 966 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 967 CU_ASSERT(rc == -EPERM); 968 969 __blob_to_data(blob)->md_ro = false; 970 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 971 CU_ASSERT(rc == 0); 972 973 length = 2345; 974 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 975 CU_ASSERT(rc == 0); 976 977 /* Overwrite "length" xattr. */ 978 length = 3456; 979 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 980 CU_ASSERT(rc == 0); 981 982 /* get_xattr should still work even if md_ro flag is set. */ 983 value = NULL; 984 __blob_to_data(blob)->md_ro = true; 985 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 986 CU_ASSERT(rc == 0); 987 SPDK_CU_ASSERT_FATAL(value != NULL); 988 CU_ASSERT(*(uint64_t *)value == length); 989 CU_ASSERT(value_len == 8); 990 __blob_to_data(blob)->md_ro = false; 991 992 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 993 CU_ASSERT(rc == -ENOENT); 994 995 names = NULL; 996 rc = spdk_blob_get_xattr_names(blob, &names); 997 CU_ASSERT(rc == 0); 998 SPDK_CU_ASSERT_FATAL(names != NULL); 999 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1000 name1 = spdk_xattr_names_get_name(names, 0); 1001 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1002 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1003 name2 = spdk_xattr_names_get_name(names, 1); 1004 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1005 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1006 CU_ASSERT(strcmp(name1, name2)); 1007 spdk_xattr_names_free(names); 1008 1009 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1010 __blob_to_data(blob)->md_ro = true; 1011 rc = spdk_blob_remove_xattr(blob, "name"); 1012 CU_ASSERT(rc == -EPERM); 1013 1014 __blob_to_data(blob)->md_ro = false; 1015 rc = spdk_blob_remove_xattr(blob, "name"); 1016 CU_ASSERT(rc == 0); 1017 1018 rc = spdk_blob_remove_xattr(blob, "foobar"); 1019 CU_ASSERT(rc == -ENOENT); 1020 1021 spdk_blob_close(blob, blob_op_complete, NULL); 1022 1023 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1024 CU_ASSERT(g_bserrno == 0); 1025 g_bs = NULL; 1026 } 1027 1028 static void 1029 bs_load(void) 1030 { 1031 struct spdk_bs_dev *dev; 1032 spdk_blob_id blobid; 1033 struct spdk_blob *blob; 1034 struct spdk_bs_super_block *super_block; 1035 uint64_t length; 1036 int rc; 1037 const void *value; 1038 size_t value_len; 1039 struct spdk_bs_opts opts; 1040 1041 g_scheduler_delay = true; 1042 1043 dev = init_dev(); 1044 spdk_bs_opts_init(&opts); 1045 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1046 1047 /* Initialize a new blob store */ 1048 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1049 CU_ASSERT(g_bserrno == 0); 1050 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1051 1052 /* Try to open a blobid that does not exist */ 1053 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1054 CU_ASSERT(g_bserrno == -ENOENT); 1055 CU_ASSERT(g_blob == NULL); 1056 1057 /* Create a blob */ 1058 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1059 CU_ASSERT(g_bserrno == 0); 1060 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1061 blobid = g_blobid; 1062 1063 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1064 CU_ASSERT(g_bserrno == 0); 1065 CU_ASSERT(g_blob != NULL); 1066 blob = g_blob; 1067 1068 /* Try again to open valid blob but without the upper bit set */ 1069 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1070 CU_ASSERT(g_bserrno == -ENOENT); 1071 CU_ASSERT(g_blob == NULL); 1072 1073 /* Set some xattrs */ 1074 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1075 CU_ASSERT(rc == 0); 1076 1077 length = 2345; 1078 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1079 CU_ASSERT(rc == 0); 1080 1081 /* Resize the blob */ 1082 rc = spdk_blob_resize(blob, 10); 1083 CU_ASSERT(rc == 0); 1084 1085 spdk_blob_close(blob, blob_op_complete, NULL); 1086 CU_ASSERT(g_bserrno == 0); 1087 blob = NULL; 1088 g_blob = NULL; 1089 g_blobid = SPDK_BLOBID_INVALID; 1090 1091 /* Unload the blob store */ 1092 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1093 CU_ASSERT(g_bserrno == 0); 1094 g_bs = NULL; 1095 g_blob = NULL; 1096 g_blobid = 0; 1097 1098 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1099 CU_ASSERT(super_block->clean == 1); 1100 1101 1102 /* Load an existing blob store */ 1103 dev = init_dev(); 1104 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1105 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1106 CU_ASSERT(g_bserrno == 0); 1107 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1108 1109 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1110 CU_ASSERT(super_block->clean == 0); 1111 1112 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1113 CU_ASSERT(g_bserrno == 0); 1114 CU_ASSERT(g_blob != NULL); 1115 blob = g_blob; 1116 1117 /* Get the xattrs */ 1118 value = NULL; 1119 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1120 CU_ASSERT(rc == 0); 1121 SPDK_CU_ASSERT_FATAL(value != NULL); 1122 CU_ASSERT(*(uint64_t *)value == length); 1123 CU_ASSERT(value_len == 8); 1124 1125 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1126 CU_ASSERT(rc == -ENOENT); 1127 1128 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1129 1130 spdk_blob_close(blob, blob_op_complete, NULL); 1131 CU_ASSERT(g_bserrno == 0); 1132 blob = NULL; 1133 g_blob = NULL; 1134 g_blobid = SPDK_BLOBID_INVALID; 1135 1136 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1137 CU_ASSERT(g_bserrno == 0); 1138 g_bs = NULL; 1139 g_scheduler_delay = false; 1140 } 1141 1142 static void 1143 bs_type(void) 1144 { 1145 struct spdk_bs_dev *dev; 1146 struct spdk_bs_opts opts; 1147 1148 g_scheduler_delay = true; 1149 1150 dev = init_dev(); 1151 spdk_bs_opts_init(&opts); 1152 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1153 1154 /* Initialize a new blob store */ 1155 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1156 CU_ASSERT(g_bserrno == 0); 1157 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1158 1159 /* Unload the blob store */ 1160 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1161 CU_ASSERT(g_bserrno == 0); 1162 g_bs = NULL; 1163 g_blob = NULL; 1164 g_blobid = 0; 1165 1166 /* Load non existing blobstore type */ 1167 dev = init_dev(); 1168 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1169 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1170 CU_ASSERT(g_bserrno != 0); 1171 1172 /* Load with empty blobstore type */ 1173 dev = init_dev(); 1174 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1175 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1176 CU_ASSERT(g_bserrno == 0); 1177 1178 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1179 CU_ASSERT(g_bserrno == 0); 1180 g_bs = NULL; 1181 1182 /* Initialize a new blob store with empty bstype */ 1183 dev = init_dev(); 1184 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1185 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1186 CU_ASSERT(g_bserrno == 0); 1187 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1188 1189 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1190 CU_ASSERT(g_bserrno == 0); 1191 g_bs = NULL; 1192 1193 /* Load non existing blobstore type */ 1194 dev = init_dev(); 1195 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1196 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1197 CU_ASSERT(g_bserrno != 0); 1198 1199 /* Load with empty blobstore type */ 1200 dev = init_dev(); 1201 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1202 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1203 CU_ASSERT(g_bserrno == 0); 1204 1205 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1206 CU_ASSERT(g_bserrno == 0); 1207 g_bs = NULL; 1208 g_scheduler_delay = false; 1209 } 1210 1211 static void 1212 bs_super_block(void) 1213 { 1214 struct spdk_bs_dev *dev; 1215 struct spdk_bs_super_block *super_block; 1216 struct spdk_bs_opts opts; 1217 struct spdk_bs_super_block_ver1 super_block_v1; 1218 1219 g_scheduler_delay = true; 1220 1221 dev = init_dev(); 1222 spdk_bs_opts_init(&opts); 1223 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1224 1225 /* Initialize a new blob store */ 1226 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1227 CU_ASSERT(g_bserrno == 0); 1228 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1229 1230 /* Unload the blob store */ 1231 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1232 CU_ASSERT(g_bserrno == 0); 1233 g_bs = NULL; 1234 g_blob = NULL; 1235 g_blobid = 0; 1236 1237 /* Load an existing blob store with version newer than supported */ 1238 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1239 super_block->version++; 1240 1241 dev = init_dev(); 1242 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1243 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1244 CU_ASSERT(g_bserrno != 0); 1245 1246 /* Create a new blob store with super block version 1 */ 1247 dev = init_dev(); 1248 super_block_v1.version = 1; 1249 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1250 super_block_v1.length = 0x1000; 1251 super_block_v1.clean = 1; 1252 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1253 super_block_v1.cluster_size = 0x100000; 1254 super_block_v1.used_page_mask_start = 0x01; 1255 super_block_v1.used_page_mask_len = 0x01; 1256 super_block_v1.used_cluster_mask_start = 0x02; 1257 super_block_v1.used_cluster_mask_len = 0x01; 1258 super_block_v1.md_start = 0x03; 1259 super_block_v1.md_len = 0x40; 1260 memset(super_block_v1.reserved, 0, 4036); 1261 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1262 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1263 1264 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1265 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1266 CU_ASSERT(g_bserrno == 0); 1267 1268 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1269 CU_ASSERT(g_bserrno == 0); 1270 g_bs = NULL; 1271 g_scheduler_delay = false; 1272 } 1273 1274 /* 1275 * Create a blobstore and then unload it. 1276 */ 1277 static void 1278 bs_unload(void) 1279 { 1280 struct spdk_bs_dev *dev; 1281 struct spdk_blob_store *bs; 1282 spdk_blob_id blobid; 1283 struct spdk_blob *blob; 1284 1285 dev = init_dev(); 1286 1287 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1288 CU_ASSERT(g_bserrno == 0); 1289 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1290 bs = g_bs; 1291 1292 /* Create a blob and open it. */ 1293 g_bserrno = -1; 1294 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1295 CU_ASSERT(g_bserrno == 0); 1296 CU_ASSERT(g_blobid > 0); 1297 blobid = g_blobid; 1298 1299 g_bserrno = -1; 1300 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1301 CU_ASSERT(g_bserrno == 0); 1302 CU_ASSERT(g_blob != NULL); 1303 blob = g_blob; 1304 1305 /* Try to unload blobstore, should fail with open blob */ 1306 g_bserrno = -1; 1307 spdk_bs_unload(bs, bs_op_complete, NULL); 1308 CU_ASSERT(g_bserrno == -EBUSY); 1309 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1310 1311 /* Close the blob, then successfully unload blobstore */ 1312 g_bserrno = -1; 1313 spdk_blob_close(blob, blob_op_complete, NULL); 1314 CU_ASSERT(g_bserrno == 0); 1315 1316 g_bserrno = -1; 1317 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1318 CU_ASSERT(g_bserrno == 0); 1319 g_bs = NULL; 1320 } 1321 1322 /* 1323 * Create a blobstore with a cluster size different than the default, and ensure it is 1324 * persisted. 1325 */ 1326 static void 1327 bs_cluster_sz(void) 1328 { 1329 struct spdk_bs_dev *dev; 1330 struct spdk_bs_opts opts; 1331 uint32_t cluster_sz; 1332 1333 /* Set cluster size to zero */ 1334 dev = init_dev(); 1335 spdk_bs_opts_init(&opts); 1336 opts.cluster_sz = 0; 1337 1338 /* Initialize a new blob store */ 1339 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1340 CU_ASSERT(g_bserrno == -EINVAL); 1341 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1342 1343 /* 1344 * Set cluster size to blobstore page size, 1345 * to work it is required to be at least twice the blobstore page size. 1346 */ 1347 dev = init_dev(); 1348 spdk_bs_opts_init(&opts); 1349 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1350 1351 /* Initialize a new blob store */ 1352 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1353 CU_ASSERT(g_bserrno == -ENOMEM); 1354 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1355 1356 /* 1357 * Set cluster size to lower than page size, 1358 * to work it is required to be at least twice the blobstore page size. 1359 */ 1360 dev = init_dev(); 1361 spdk_bs_opts_init(&opts); 1362 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1363 1364 /* Initialize a new blob store */ 1365 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1366 CU_ASSERT(g_bserrno == -ENOMEM); 1367 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1368 1369 /* Set cluster size to twice the default */ 1370 dev = init_dev(); 1371 spdk_bs_opts_init(&opts); 1372 opts.cluster_sz *= 2; 1373 cluster_sz = opts.cluster_sz; 1374 1375 /* Initialize a new blob store */ 1376 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1377 CU_ASSERT(g_bserrno == 0); 1378 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1379 1380 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1381 1382 /* Unload the blob store */ 1383 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1384 CU_ASSERT(g_bserrno == 0); 1385 g_bs = NULL; 1386 g_blob = NULL; 1387 g_blobid = 0; 1388 1389 dev = init_dev(); 1390 /* Load an existing blob store */ 1391 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1392 CU_ASSERT(g_bserrno == 0); 1393 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1394 1395 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1396 1397 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1398 CU_ASSERT(g_bserrno == 0); 1399 g_bs = NULL; 1400 } 1401 1402 /* 1403 * Create a blobstore, reload it and ensure total usable cluster count 1404 * stays the same. 1405 */ 1406 static void 1407 bs_usable_clusters(void) 1408 { 1409 struct spdk_bs_dev *dev; 1410 struct spdk_bs_opts opts; 1411 uint32_t clusters; 1412 int i, rc; 1413 1414 /* Init blobstore */ 1415 dev = init_dev(); 1416 spdk_bs_opts_init(&opts); 1417 1418 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1419 CU_ASSERT(g_bserrno == 0); 1420 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1421 1422 clusters = spdk_bs_total_data_cluster_count(g_bs); 1423 1424 /* Unload the blob store */ 1425 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1426 CU_ASSERT(g_bserrno == 0); 1427 g_bs = NULL; 1428 1429 dev = init_dev(); 1430 /* Load an existing blob store */ 1431 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1432 CU_ASSERT(g_bserrno == 0); 1433 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1434 1435 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1436 1437 /* Create and resize blobs to make sure that useable cluster count won't change */ 1438 for (i = 0; i < 4; i++) { 1439 g_bserrno = -1; 1440 g_blobid = SPDK_BLOBID_INVALID; 1441 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1442 CU_ASSERT(g_bserrno == 0); 1443 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1444 1445 g_bserrno = -1; 1446 g_blob = NULL; 1447 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1448 CU_ASSERT(g_bserrno == 0); 1449 CU_ASSERT(g_blob != NULL); 1450 1451 rc = spdk_blob_resize(g_blob, 10); 1452 CU_ASSERT(rc == 0); 1453 1454 g_bserrno = -1; 1455 spdk_blob_close(g_blob, blob_op_complete, NULL); 1456 CU_ASSERT(g_bserrno == 0); 1457 1458 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1459 } 1460 1461 /* Reload the blob store to make sure that nothing changed */ 1462 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1463 CU_ASSERT(g_bserrno == 0); 1464 g_bs = NULL; 1465 1466 dev = init_dev(); 1467 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1468 CU_ASSERT(g_bserrno == 0); 1469 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1470 1471 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1472 1473 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1474 CU_ASSERT(g_bserrno == 0); 1475 g_bs = NULL; 1476 } 1477 1478 /* 1479 * Test resizing of the metadata blob. This requires creating enough blobs 1480 * so that one cluster is not enough to fit the metadata for those blobs. 1481 * To induce this condition to happen more quickly, we reduce the cluster 1482 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1483 */ 1484 static void 1485 bs_resize_md(void) 1486 { 1487 const int CLUSTER_PAGE_COUNT = 4; 1488 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1489 struct spdk_bs_dev *dev; 1490 struct spdk_bs_opts opts; 1491 uint32_t cluster_sz; 1492 spdk_blob_id blobids[NUM_BLOBS]; 1493 int i; 1494 1495 1496 dev = init_dev(); 1497 spdk_bs_opts_init(&opts); 1498 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1499 cluster_sz = opts.cluster_sz; 1500 1501 /* Initialize a new blob store */ 1502 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1503 CU_ASSERT(g_bserrno == 0); 1504 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1505 1506 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1507 1508 for (i = 0; i < NUM_BLOBS; i++) { 1509 g_bserrno = -1; 1510 g_blobid = SPDK_BLOBID_INVALID; 1511 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1512 CU_ASSERT(g_bserrno == 0); 1513 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1514 blobids[i] = g_blobid; 1515 } 1516 1517 /* Unload the blob store */ 1518 g_bserrno = -1; 1519 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1520 CU_ASSERT(g_bserrno == 0); 1521 1522 /* Load an existing blob store */ 1523 g_bserrno = -1; 1524 g_bs = NULL; 1525 dev = init_dev(); 1526 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1527 CU_ASSERT(g_bserrno == 0); 1528 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1529 1530 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1531 1532 for (i = 0; i < NUM_BLOBS; i++) { 1533 g_bserrno = -1; 1534 g_blob = NULL; 1535 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1536 CU_ASSERT(g_bserrno == 0); 1537 CU_ASSERT(g_blob != NULL); 1538 g_bserrno = -1; 1539 spdk_blob_close(g_blob, blob_op_complete, NULL); 1540 CU_ASSERT(g_bserrno == 0); 1541 } 1542 1543 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1544 CU_ASSERT(g_bserrno == 0); 1545 g_bs = NULL; 1546 } 1547 1548 static void 1549 bs_destroy(void) 1550 { 1551 struct spdk_bs_dev *dev; 1552 struct spdk_bs_opts opts; 1553 1554 g_scheduler_delay = true; 1555 1556 _bs_flush_scheduler(); 1557 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1558 1559 /* Initialize a new blob store */ 1560 dev = init_dev(); 1561 spdk_bs_opts_init(&opts); 1562 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1563 CU_ASSERT(g_bserrno == 0); 1564 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1565 1566 /* Destroy the blob store */ 1567 g_bserrno = -1; 1568 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 1569 /* Callback is called after device is destroyed in next scheduler run. */ 1570 _bs_flush_scheduler(); 1571 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1572 CU_ASSERT(g_bserrno == 0); 1573 1574 /* Loading an non-existent blob store should fail. */ 1575 g_bserrno = -1; 1576 g_bs = NULL; 1577 dev = init_dev(); 1578 1579 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1580 CU_ASSERT(g_bserrno != 0); 1581 g_scheduler_delay = false; 1582 } 1583 1584 /* Try to hit all of the corner cases associated with serializing 1585 * a blob to disk 1586 */ 1587 static void 1588 blob_serialize(void) 1589 { 1590 struct spdk_bs_dev *dev; 1591 struct spdk_bs_opts opts; 1592 struct spdk_blob_store *bs; 1593 spdk_blob_id blobid[2]; 1594 struct spdk_blob *blob[2]; 1595 uint64_t i; 1596 char *value; 1597 int rc; 1598 1599 dev = init_dev(); 1600 1601 /* Initialize a new blobstore with very small clusters */ 1602 spdk_bs_opts_init(&opts); 1603 opts.cluster_sz = dev->blocklen * 8; 1604 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1605 CU_ASSERT(g_bserrno == 0); 1606 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1607 bs = g_bs; 1608 1609 /* Create and open two blobs */ 1610 for (i = 0; i < 2; i++) { 1611 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1612 CU_ASSERT(g_bserrno == 0); 1613 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1614 blobid[i] = g_blobid; 1615 1616 /* Open a blob */ 1617 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1618 CU_ASSERT(g_bserrno == 0); 1619 CU_ASSERT(g_blob != NULL); 1620 blob[i] = g_blob; 1621 1622 /* Set a fairly large xattr on both blobs to eat up 1623 * metadata space 1624 */ 1625 value = calloc(dev->blocklen - 64, sizeof(char)); 1626 SPDK_CU_ASSERT_FATAL(value != NULL); 1627 memset(value, i, dev->blocklen / 2); 1628 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 1629 CU_ASSERT(rc == 0); 1630 free(value); 1631 } 1632 1633 /* Resize the blobs, alternating 1 cluster at a time. 1634 * This thwarts run length encoding and will cause spill 1635 * over of the extents. 1636 */ 1637 for (i = 0; i < 6; i++) { 1638 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 1639 CU_ASSERT(rc == 0); 1640 } 1641 1642 for (i = 0; i < 2; i++) { 1643 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 1644 CU_ASSERT(g_bserrno == 0); 1645 } 1646 1647 /* Close the blobs */ 1648 for (i = 0; i < 2; i++) { 1649 spdk_blob_close(blob[i], blob_op_complete, NULL); 1650 CU_ASSERT(g_bserrno == 0); 1651 } 1652 1653 /* Unload the blobstore */ 1654 spdk_bs_unload(bs, bs_op_complete, NULL); 1655 CU_ASSERT(g_bserrno == 0); 1656 g_bs = NULL; 1657 g_blob = NULL; 1658 g_blobid = 0; 1659 bs = NULL; 1660 1661 dev = init_dev(); 1662 /* Load an existing blob store */ 1663 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1664 CU_ASSERT(g_bserrno == 0); 1665 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1666 bs = g_bs; 1667 1668 for (i = 0; i < 2; i++) { 1669 blob[i] = NULL; 1670 1671 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 1672 CU_ASSERT(g_bserrno == 0); 1673 CU_ASSERT(g_blob != NULL); 1674 blob[i] = g_blob; 1675 1676 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 1677 1678 spdk_blob_close(blob[i], blob_op_complete, NULL); 1679 CU_ASSERT(g_bserrno == 0); 1680 } 1681 1682 spdk_bs_unload(bs, bs_op_complete, NULL); 1683 CU_ASSERT(g_bserrno == 0); 1684 g_bs = NULL; 1685 } 1686 1687 static void 1688 blob_crc(void) 1689 { 1690 struct spdk_blob_store *bs; 1691 struct spdk_bs_dev *dev; 1692 struct spdk_blob *blob; 1693 spdk_blob_id blobid; 1694 uint32_t page_num; 1695 int index; 1696 struct spdk_blob_md_page *page; 1697 1698 dev = init_dev(); 1699 1700 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1701 CU_ASSERT(g_bserrno == 0); 1702 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1703 bs = g_bs; 1704 1705 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1706 CU_ASSERT(g_bserrno == 0); 1707 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1708 blobid = g_blobid; 1709 1710 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1711 CU_ASSERT(g_bserrno == 0); 1712 CU_ASSERT(g_blob != NULL); 1713 blob = g_blob; 1714 1715 spdk_blob_close(blob, blob_op_complete, NULL); 1716 CU_ASSERT(g_bserrno == 0); 1717 1718 page_num = _spdk_bs_blobid_to_page(blobid); 1719 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 1720 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 1721 page->crc = 0; 1722 1723 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1724 CU_ASSERT(g_bserrno == -EINVAL); 1725 CU_ASSERT(g_blob == NULL); 1726 g_bserrno = 0; 1727 1728 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 1729 CU_ASSERT(g_bserrno == -EINVAL); 1730 1731 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1732 CU_ASSERT(g_bserrno == 0); 1733 g_bs = NULL; 1734 } 1735 1736 static void 1737 super_block_crc(void) 1738 { 1739 struct spdk_bs_dev *dev; 1740 struct spdk_bs_super_block *super_block; 1741 struct spdk_bs_opts opts; 1742 1743 dev = init_dev(); 1744 spdk_bs_opts_init(&opts); 1745 1746 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1747 CU_ASSERT(g_bserrno == 0); 1748 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1749 1750 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1751 CU_ASSERT(g_bserrno == 0); 1752 g_bs = NULL; 1753 1754 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1755 super_block->crc = 0; 1756 dev = init_dev(); 1757 1758 g_scheduler_delay = true; 1759 /* Load an existing blob store */ 1760 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1761 1762 CU_ASSERT(g_bserrno == -EILSEQ); 1763 _bs_flush_scheduler(); 1764 CU_ASSERT(TAILQ_EMPTY(&g_scheduled_ops)); 1765 1766 g_scheduler_delay = false; 1767 } 1768 1769 /* For blob dirty shutdown test case we do the following sub-test cases: 1770 * 1 Initialize new blob store and create 1 blob with some xattrs, then we 1771 * dirty shutdown and reload the blob store and verify the xattrs. 1772 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 1773 * reload the blob store and verify the clusters number. 1774 * 3 Create the second blob and then dirty shutdown, reload the blob store 1775 * and verify the second blob. 1776 * 4 Delete the second blob and then dirty shutdown, reload teh blob store 1777 * and verify the second blob is invalid. 1778 * 5 Create the second blob again and also create the third blob, modify the 1779 * md of second blob which makes the md invalid, and then dirty shutdown, 1780 * reload the blob store verify the second blob, it should invalid and also 1781 * verify the third blob, it should correct. 1782 */ 1783 static void 1784 blob_dirty_shutdown(void) 1785 { 1786 int rc; 1787 int index; 1788 struct spdk_bs_dev *dev; 1789 spdk_blob_id blobid1, blobid2, blobid3; 1790 struct spdk_blob *blob; 1791 uint64_t length; 1792 const void *value; 1793 size_t value_len; 1794 uint32_t page_num; 1795 struct spdk_blob_md_page *page; 1796 struct spdk_bs_opts opts; 1797 1798 dev = init_dev(); 1799 spdk_bs_opts_init(&opts); 1800 /* Initialize a new blob store */ 1801 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1802 CU_ASSERT(g_bserrno == 0); 1803 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1804 1805 /* Create first blob */ 1806 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1807 CU_ASSERT(g_bserrno == 0); 1808 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1809 blobid1 = g_blobid; 1810 1811 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1812 CU_ASSERT(g_bserrno == 0); 1813 CU_ASSERT(g_blob != NULL); 1814 blob = g_blob; 1815 1816 /* Set some xattrs */ 1817 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1818 CU_ASSERT(rc == 0); 1819 1820 length = 2345; 1821 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1822 CU_ASSERT(rc == 0); 1823 1824 /* Resize the blob */ 1825 rc = spdk_blob_resize(blob, 10); 1826 CU_ASSERT(rc == 0); 1827 1828 spdk_blob_close(blob, blob_op_complete, NULL); 1829 blob = NULL; 1830 g_blob = NULL; 1831 g_blobid = SPDK_BLOBID_INVALID; 1832 1833 /* Dirty shutdown */ 1834 _spdk_bs_free(g_bs); 1835 1836 /* reload blobstore */ 1837 dev = init_dev(); 1838 spdk_bs_opts_init(&opts); 1839 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1840 CU_ASSERT(g_bserrno == 0); 1841 1842 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1843 CU_ASSERT(g_bserrno == 0); 1844 CU_ASSERT(g_blob != NULL); 1845 blob = g_blob; 1846 1847 /* Get the xattrs */ 1848 value = NULL; 1849 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1850 CU_ASSERT(rc == 0); 1851 SPDK_CU_ASSERT_FATAL(value != NULL); 1852 CU_ASSERT(*(uint64_t *)value == length); 1853 CU_ASSERT(value_len == 8); 1854 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1855 1856 /* Resize the blob */ 1857 rc = spdk_blob_resize(blob, 20); 1858 CU_ASSERT(rc == 0); 1859 1860 spdk_blob_close(blob, blob_op_complete, NULL); 1861 CU_ASSERT(g_bserrno == 0); 1862 blob = NULL; 1863 g_blob = NULL; 1864 g_blobid = SPDK_BLOBID_INVALID; 1865 1866 /* Dirty shutdown */ 1867 _spdk_bs_free(g_bs); 1868 1869 /* reload the blobstore */ 1870 dev = init_dev(); 1871 spdk_bs_opts_init(&opts); 1872 /* Load an existing blob store */ 1873 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1874 CU_ASSERT(g_bserrno == 0); 1875 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1876 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1877 CU_ASSERT(g_bserrno == 0); 1878 CU_ASSERT(g_blob != NULL); 1879 blob = g_blob; 1880 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 1881 1882 spdk_blob_close(blob, blob_op_complete, NULL); 1883 CU_ASSERT(g_bserrno == 0); 1884 blob = NULL; 1885 g_blob = NULL; 1886 g_blobid = SPDK_BLOBID_INVALID; 1887 1888 /* Create second blob */ 1889 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1890 CU_ASSERT(g_bserrno == 0); 1891 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1892 blobid2 = g_blobid; 1893 1894 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1895 CU_ASSERT(g_bserrno == 0); 1896 CU_ASSERT(g_blob != NULL); 1897 blob = g_blob; 1898 1899 /* Set some xattrs */ 1900 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1901 CU_ASSERT(rc == 0); 1902 1903 length = 5432; 1904 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1905 CU_ASSERT(rc == 0); 1906 1907 /* Resize the blob */ 1908 rc = spdk_blob_resize(blob, 10); 1909 CU_ASSERT(rc == 0); 1910 1911 spdk_blob_close(blob, blob_op_complete, NULL); 1912 blob = NULL; 1913 g_blob = NULL; 1914 g_blobid = SPDK_BLOBID_INVALID; 1915 1916 /* Dirty shutdown */ 1917 _spdk_bs_free(g_bs); 1918 1919 /* reload the blobstore */ 1920 dev = init_dev(); 1921 spdk_bs_opts_init(&opts); 1922 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1923 CU_ASSERT(g_bserrno == 0); 1924 1925 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1926 CU_ASSERT(g_bserrno == 0); 1927 CU_ASSERT(g_blob != NULL); 1928 blob = g_blob; 1929 1930 /* Get the xattrs */ 1931 value = NULL; 1932 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1933 CU_ASSERT(rc == 0); 1934 SPDK_CU_ASSERT_FATAL(value != NULL); 1935 CU_ASSERT(*(uint64_t *)value == length); 1936 CU_ASSERT(value_len == 8); 1937 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1938 1939 spdk_blob_close(blob, blob_op_complete, NULL); 1940 CU_ASSERT(g_bserrno == 0); 1941 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 1942 CU_ASSERT(g_bserrno == 0); 1943 1944 /* Dirty shutdown */ 1945 _spdk_bs_free(g_bs); 1946 /* reload the blobstore */ 1947 dev = init_dev(); 1948 spdk_bs_opts_init(&opts); 1949 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1950 CU_ASSERT(g_bserrno == 0); 1951 1952 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1953 CU_ASSERT(g_bserrno != 0); 1954 CU_ASSERT(g_blob == NULL); 1955 1956 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 1957 CU_ASSERT(g_bserrno == 0); 1958 CU_ASSERT(g_blob != NULL); 1959 spdk_blob_close(g_blob, blob_op_complete, NULL); 1960 CU_ASSERT(g_bserrno == 0); 1961 1962 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1963 CU_ASSERT(g_bserrno == 0); 1964 g_bs = NULL; 1965 1966 /* reload the blobstore */ 1967 dev = init_dev(); 1968 spdk_bs_opts_init(&opts); 1969 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1970 CU_ASSERT(g_bserrno == 0); 1971 1972 /* Create second blob */ 1973 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1974 CU_ASSERT(g_bserrno == 0); 1975 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1976 blobid2 = g_blobid; 1977 1978 /* Create third blob */ 1979 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1980 CU_ASSERT(g_bserrno == 0); 1981 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1982 blobid3 = g_blobid; 1983 1984 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 1985 CU_ASSERT(g_bserrno == 0); 1986 CU_ASSERT(g_blob != NULL); 1987 blob = g_blob; 1988 1989 /* Set some xattrs for second blob */ 1990 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 1991 CU_ASSERT(rc == 0); 1992 1993 length = 5432; 1994 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1995 CU_ASSERT(rc == 0); 1996 1997 spdk_blob_close(blob, blob_op_complete, NULL); 1998 blob = NULL; 1999 g_blob = NULL; 2000 g_blobid = SPDK_BLOBID_INVALID; 2001 2002 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2003 CU_ASSERT(g_bserrno == 0); 2004 CU_ASSERT(g_blob != NULL); 2005 blob = g_blob; 2006 2007 /* Set some xattrs for third blob */ 2008 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2009 CU_ASSERT(rc == 0); 2010 2011 length = 5432; 2012 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2013 CU_ASSERT(rc == 0); 2014 2015 spdk_blob_close(blob, blob_op_complete, NULL); 2016 blob = NULL; 2017 g_blob = NULL; 2018 g_blobid = SPDK_BLOBID_INVALID; 2019 2020 /* Mark second blob as invalid */ 2021 page_num = _spdk_bs_blobid_to_page(blobid2); 2022 2023 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2024 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2025 page->sequence_num = 1; 2026 page->crc = _spdk_blob_md_page_calc_crc(page); 2027 2028 /* Dirty shutdown */ 2029 _spdk_bs_free(g_bs); 2030 /* reload the blobstore */ 2031 dev = init_dev(); 2032 spdk_bs_opts_init(&opts); 2033 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2034 CU_ASSERT(g_bserrno == 0); 2035 2036 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2037 CU_ASSERT(g_bserrno != 0); 2038 CU_ASSERT(g_blob == NULL); 2039 2040 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2041 CU_ASSERT(g_bserrno == 0); 2042 CU_ASSERT(g_blob != NULL); 2043 blob = g_blob; 2044 2045 spdk_blob_close(blob, blob_op_complete, NULL); 2046 blob = NULL; 2047 g_blob = NULL; 2048 g_blobid = SPDK_BLOBID_INVALID; 2049 2050 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2051 CU_ASSERT(g_bserrno == 0); 2052 g_bs = NULL; 2053 } 2054 2055 static void 2056 blob_flags(void) 2057 { 2058 struct spdk_bs_dev *dev; 2059 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2060 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2061 struct spdk_bs_opts opts; 2062 2063 dev = init_dev(); 2064 spdk_bs_opts_init(&opts); 2065 2066 /* Initialize a new blob store */ 2067 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2068 CU_ASSERT(g_bserrno == 0); 2069 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2070 2071 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2072 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2073 CU_ASSERT(g_bserrno == 0); 2074 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2075 blobid_invalid = g_blobid; 2076 2077 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2078 CU_ASSERT(g_bserrno == 0); 2079 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2080 blobid_data_ro = g_blobid; 2081 2082 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2083 CU_ASSERT(g_bserrno == 0); 2084 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2085 blobid_md_ro = g_blobid; 2086 2087 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2088 CU_ASSERT(g_bserrno == 0); 2089 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2090 blob_invalid = g_blob; 2091 2092 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2093 CU_ASSERT(g_bserrno == 0); 2094 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2095 blob_data_ro = g_blob; 2096 2097 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2098 CU_ASSERT(g_bserrno == 0); 2099 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2100 blob_md_ro = g_blob; 2101 2102 __blob_to_data(blob_invalid)->invalid_flags = (1ULL << 63); 2103 __blob_to_data(blob_invalid)->state = SPDK_BLOB_STATE_DIRTY; 2104 __blob_to_data(blob_data_ro)->data_ro_flags = (1ULL << 62); 2105 __blob_to_data(blob_data_ro)->state = SPDK_BLOB_STATE_DIRTY; 2106 __blob_to_data(blob_md_ro)->md_ro_flags = (1ULL << 61); 2107 __blob_to_data(blob_md_ro)->state = SPDK_BLOB_STATE_DIRTY; 2108 2109 g_bserrno = -1; 2110 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2111 CU_ASSERT(g_bserrno == 0); 2112 g_bserrno = -1; 2113 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2114 CU_ASSERT(g_bserrno == 0); 2115 g_bserrno = -1; 2116 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2117 CU_ASSERT(g_bserrno == 0); 2118 2119 g_bserrno = -1; 2120 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2121 CU_ASSERT(g_bserrno == 0); 2122 blob_invalid = NULL; 2123 g_bserrno = -1; 2124 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2125 CU_ASSERT(g_bserrno == 0); 2126 blob_data_ro = NULL; 2127 g_bserrno = -1; 2128 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2129 CU_ASSERT(g_bserrno == 0); 2130 blob_md_ro = NULL; 2131 2132 g_blob = NULL; 2133 g_blobid = SPDK_BLOBID_INVALID; 2134 2135 /* Unload the blob store */ 2136 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2137 CU_ASSERT(g_bserrno == 0); 2138 g_bs = NULL; 2139 2140 /* Load an existing blob store */ 2141 dev = init_dev(); 2142 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2143 CU_ASSERT(g_bserrno == 0); 2144 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2145 2146 g_blob = NULL; 2147 g_bserrno = 0; 2148 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2149 CU_ASSERT(g_bserrno != 0); 2150 CU_ASSERT(g_blob == NULL); 2151 2152 g_blob = NULL; 2153 g_bserrno = -1; 2154 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2155 CU_ASSERT(g_bserrno == 0); 2156 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2157 blob_data_ro = g_blob; 2158 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2159 CU_ASSERT(__blob_to_data(blob_data_ro)->data_ro == true); 2160 CU_ASSERT(__blob_to_data(blob_data_ro)->md_ro == true); 2161 2162 g_blob = NULL; 2163 g_bserrno = -1; 2164 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2165 CU_ASSERT(g_bserrno == 0); 2166 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2167 blob_md_ro = g_blob; 2168 CU_ASSERT(__blob_to_data(blob_md_ro)->data_ro == false); 2169 CU_ASSERT(__blob_to_data(blob_md_ro)->md_ro == true); 2170 2171 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2172 CU_ASSERT(g_bserrno == 0); 2173 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2174 CU_ASSERT(g_bserrno == 0); 2175 2176 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2177 CU_ASSERT(g_bserrno == 0); 2178 } 2179 2180 static void 2181 bs_version(void) 2182 { 2183 struct spdk_bs_super_block *super; 2184 struct spdk_bs_dev *dev; 2185 struct spdk_bs_opts opts; 2186 spdk_blob_id blobid; 2187 2188 dev = init_dev(); 2189 spdk_bs_opts_init(&opts); 2190 2191 /* Initialize a new blob store */ 2192 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2193 CU_ASSERT(g_bserrno == 0); 2194 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2195 2196 /* Unload the blob store */ 2197 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2198 CU_ASSERT(g_bserrno == 0); 2199 g_bs = NULL; 2200 2201 /* 2202 * Change the bs version on disk. This will allow us to 2203 * test that the version does not get modified automatically 2204 * when loading and unloading the blobstore. 2205 */ 2206 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2207 CU_ASSERT(super->version == SPDK_BS_VERSION); 2208 CU_ASSERT(super->clean == 1); 2209 super->version = 2; 2210 /* 2211 * Version 2 metadata does not have a used blobid mask, so clear 2212 * those fields in the super block and zero the corresponding 2213 * region on "disk". We will use this to ensure blob IDs are 2214 * correctly reconstructed. 2215 */ 2216 memset(&g_dev_buffer[super->used_blobid_mask_start * PAGE_SIZE], 0, 2217 super->used_blobid_mask_len * PAGE_SIZE); 2218 super->used_blobid_mask_start = 0; 2219 super->used_blobid_mask_len = 0; 2220 super->crc = _spdk_blob_md_page_calc_crc(super); 2221 2222 /* Load an existing blob store */ 2223 dev = init_dev(); 2224 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2225 CU_ASSERT(g_bserrno == 0); 2226 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2227 CU_ASSERT(super->clean == 0); 2228 2229 /* 2230 * Create a blob - just to make sure that when we unload it 2231 * results in writing the super block (since metadata pages 2232 * were allocated. 2233 */ 2234 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2235 CU_ASSERT(g_bserrno == 0); 2236 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2237 blobid = g_blobid; 2238 2239 /* Unload the blob store */ 2240 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2241 CU_ASSERT(g_bserrno == 0); 2242 g_bs = NULL; 2243 CU_ASSERT(super->version == 2); 2244 CU_ASSERT(super->used_blobid_mask_start == 0); 2245 CU_ASSERT(super->used_blobid_mask_len == 0); 2246 2247 dev = init_dev(); 2248 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2249 CU_ASSERT(g_bserrno == 0); 2250 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2251 2252 g_blob = NULL; 2253 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2254 CU_ASSERT(g_bserrno == 0); 2255 CU_ASSERT(g_blob != NULL); 2256 2257 spdk_blob_close(g_blob, blob_op_complete, NULL); 2258 CU_ASSERT(g_bserrno == 0); 2259 2260 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2261 CU_ASSERT(g_bserrno == 0); 2262 g_bs = NULL; 2263 CU_ASSERT(super->version == 2); 2264 CU_ASSERT(super->used_blobid_mask_start == 0); 2265 CU_ASSERT(super->used_blobid_mask_len == 0); 2266 } 2267 2268 int main(int argc, char **argv) 2269 { 2270 CU_pSuite suite = NULL; 2271 unsigned int num_failures; 2272 2273 if (CU_initialize_registry() != CUE_SUCCESS) { 2274 return CU_get_error(); 2275 } 2276 2277 suite = CU_add_suite("blob", NULL, NULL); 2278 if (suite == NULL) { 2279 CU_cleanup_registry(); 2280 return CU_get_error(); 2281 } 2282 2283 if ( 2284 CU_add_test(suite, "blob_init", blob_init) == NULL || 2285 CU_add_test(suite, "blob_open", blob_open) == NULL || 2286 CU_add_test(suite, "blob_create", blob_create) == NULL || 2287 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 2288 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 2289 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 2290 CU_add_test(suite, "blob_super", blob_super) == NULL || 2291 CU_add_test(suite, "blob_write", blob_write) == NULL || 2292 CU_add_test(suite, "blob_read", blob_read) == NULL || 2293 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 2294 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 2295 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 2296 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 2297 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 2298 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 2299 CU_add_test(suite, "bs_load", bs_load) == NULL || 2300 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 2301 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 2302 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 2303 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 2304 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 2305 CU_add_test(suite, "bs_type", bs_type) == NULL || 2306 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 2307 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 2308 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 2309 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 2310 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 2311 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 2312 CU_add_test(suite, "bs_version", bs_version) == NULL 2313 ) { 2314 CU_cleanup_registry(); 2315 return CU_get_error(); 2316 } 2317 2318 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 2319 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 2320 CU_basic_set_mode(CU_BRM_VERBOSE); 2321 CU_basic_run_tests(); 2322 num_failures = CU_get_number_of_failures(); 2323 CU_cleanup_registry(); 2324 spdk_free_thread(); 2325 free(g_dev_buffer); 2326 return num_failures; 2327 } 2328