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 "common/lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "blob/blobstore.c" 42 #include "blob/request.c" 43 #include "blob/zeroes.c" 44 #include "blob/blob_bs_dev.c" 45 46 struct spdk_blob_store *g_bs; 47 spdk_blob_id g_blobid; 48 struct spdk_blob *g_blob; 49 int g_bserrno; 50 struct spdk_xattr_names *g_names; 51 int g_done; 52 char *g_xattr_names[] = {"first", "second", "third"}; 53 char *g_xattr_values[] = {"one", "two", "three"}; 54 uint64_t g_ctx = 1729; 55 56 bool g_scheduler_delay = false; 57 58 struct scheduled_ops { 59 spdk_thread_fn fn; 60 void *ctx; 61 62 TAILQ_ENTRY(scheduled_ops) ops_queue; 63 }; 64 65 static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops); 66 67 struct spdk_bs_super_block_ver1 { 68 uint8_t signature[8]; 69 uint32_t version; 70 uint32_t length; 71 uint32_t clean; /* If there was a clean shutdown, this is 1. */ 72 spdk_blob_id super_blob; 73 74 uint32_t cluster_size; /* In bytes */ 75 76 uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */ 77 uint32_t used_page_mask_len; /* Count, in pages */ 78 79 uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */ 80 uint32_t used_cluster_mask_len; /* Count, in pages */ 81 82 uint32_t md_start; /* Offset from beginning of disk, in pages */ 83 uint32_t md_len; /* Count, in pages */ 84 85 uint8_t reserved[4036]; 86 uint32_t crc; 87 } __attribute__((packed)); 88 SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size"); 89 90 91 static void 92 _get_xattr_value(void *arg, const char *name, 93 const void **value, size_t *value_len) 94 { 95 uint64_t i; 96 97 SPDK_CU_ASSERT_FATAL(value_len != NULL); 98 SPDK_CU_ASSERT_FATAL(value != NULL); 99 CU_ASSERT(arg == &g_ctx) 100 101 for (i = 0; i < sizeof(g_xattr_names); i++) { 102 if (!strcmp(name, g_xattr_names[i])) { 103 *value_len = strlen(g_xattr_values[i]); 104 *value = g_xattr_values[i]; 105 break; 106 } 107 } 108 } 109 110 static void 111 _get_xattr_value_null(void *arg, const char *name, 112 const void **value, size_t *value_len) 113 { 114 SPDK_CU_ASSERT_FATAL(value_len != NULL); 115 SPDK_CU_ASSERT_FATAL(value != NULL); 116 CU_ASSERT(arg == NULL) 117 118 *value_len = 0; 119 *value = NULL; 120 } 121 122 123 static void 124 _bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx) 125 { 126 if (g_scheduler_delay) { 127 struct scheduled_ops *ops = calloc(1, sizeof(*ops)); 128 129 SPDK_CU_ASSERT_FATAL(ops != NULL); 130 ops->fn = fn; 131 ops->ctx = ctx; 132 TAILQ_INSERT_TAIL(&g_scheduled_ops, ops, ops_queue); 133 } else { 134 fn(ctx); 135 } 136 } 137 138 #if 0 139 static void 140 _bs_flush_scheduler(void) 141 { 142 struct scheduled_ops *ops; 143 144 while (!TAILQ_EMPTY(&g_scheduled_ops)) { 145 ops = TAILQ_FIRST(&g_scheduled_ops); 146 TAILQ_REMOVE(&g_scheduled_ops, ops, ops_queue); 147 ops->fn(ops->ctx); 148 free(ops); 149 } 150 } 151 #endif 152 153 static void 154 bs_op_complete(void *cb_arg, int bserrno) 155 { 156 g_bserrno = bserrno; 157 } 158 159 static void 160 bs_op_with_handle_complete(void *cb_arg, struct spdk_blob_store *bs, 161 int bserrno) 162 { 163 g_bs = bs; 164 g_bserrno = bserrno; 165 } 166 167 static void 168 blob_op_complete(void *cb_arg, int bserrno) 169 { 170 g_bserrno = bserrno; 171 } 172 173 static void 174 blob_op_with_id_complete(void *cb_arg, spdk_blob_id blobid, int bserrno) 175 { 176 g_blobid = blobid; 177 g_bserrno = bserrno; 178 } 179 180 static void 181 blob_op_with_handle_complete(void *cb_arg, struct spdk_blob *blb, int bserrno) 182 { 183 g_blob = blb; 184 g_bserrno = bserrno; 185 } 186 187 static void 188 blob_init(void) 189 { 190 struct spdk_bs_dev *dev; 191 192 dev = init_dev(); 193 194 /* should fail for an unsupported blocklen */ 195 dev->blocklen = 500; 196 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 197 CU_ASSERT(g_bserrno == -EINVAL); 198 199 dev = init_dev(); 200 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 201 CU_ASSERT(g_bserrno == 0); 202 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 203 204 spdk_bs_unload(g_bs, bs_op_complete, NULL); 205 CU_ASSERT(g_bserrno == 0); 206 g_bs = NULL; 207 } 208 209 static void 210 blob_super(void) 211 { 212 struct spdk_blob_store *bs; 213 struct spdk_bs_dev *dev; 214 spdk_blob_id blobid; 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 /* Get the super blob without having set one */ 224 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 225 CU_ASSERT(g_bserrno == -ENOENT); 226 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 227 228 /* Create a blob */ 229 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 230 CU_ASSERT(g_bserrno == 0); 231 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 232 blobid = g_blobid; 233 234 /* Set the blob as the super blob */ 235 spdk_bs_set_super(bs, blobid, blob_op_complete, NULL); 236 CU_ASSERT(g_bserrno == 0); 237 238 /* Get the super blob */ 239 spdk_bs_get_super(bs, blob_op_with_id_complete, NULL); 240 CU_ASSERT(g_bserrno == 0); 241 CU_ASSERT(blobid == g_blobid); 242 243 spdk_bs_unload(g_bs, bs_op_complete, NULL); 244 CU_ASSERT(g_bserrno == 0); 245 g_bs = NULL; 246 } 247 248 static void 249 blob_open(void) 250 { 251 struct spdk_blob_store *bs; 252 struct spdk_bs_dev *dev; 253 struct spdk_blob *blob; 254 spdk_blob_id blobid, blobid2; 255 256 dev = init_dev(); 257 258 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 259 CU_ASSERT(g_bserrno == 0); 260 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 261 bs = g_bs; 262 263 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 264 CU_ASSERT(g_bserrno == 0); 265 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 266 blobid = g_blobid; 267 268 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 269 CU_ASSERT(g_bserrno == 0); 270 CU_ASSERT(g_blob != NULL); 271 blob = g_blob; 272 273 blobid2 = spdk_blob_get_id(blob); 274 CU_ASSERT(blobid == blobid2); 275 276 /* Try to open file again. It should return success. */ 277 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 278 CU_ASSERT(g_bserrno == 0); 279 CU_ASSERT(blob == g_blob); 280 281 spdk_blob_close(blob, blob_op_complete, NULL); 282 CU_ASSERT(g_bserrno == 0); 283 284 /* 285 * Close the file a second time, releasing the second reference. This 286 * should succeed. 287 */ 288 blob = g_blob; 289 spdk_blob_close(blob, blob_op_complete, NULL); 290 CU_ASSERT(g_bserrno == 0); 291 292 /* 293 * Try to open file again. It should succeed. This tests the case 294 * where the file is opened, closed, then re-opened again. 295 */ 296 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 297 CU_ASSERT(g_bserrno == 0); 298 CU_ASSERT(g_blob != NULL); 299 blob = g_blob; 300 301 spdk_blob_close(blob, blob_op_complete, NULL); 302 CU_ASSERT(g_bserrno == 0); 303 304 spdk_bs_unload(g_bs, bs_op_complete, NULL); 305 CU_ASSERT(g_bserrno == 0); 306 g_bs = NULL; 307 } 308 309 static void 310 blob_create(void) 311 { 312 struct spdk_blob_store *bs; 313 struct spdk_bs_dev *dev; 314 struct spdk_blob *blob; 315 struct spdk_blob_opts opts; 316 spdk_blob_id blobid; 317 318 dev = init_dev(); 319 320 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 321 CU_ASSERT(g_bserrno == 0); 322 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 323 bs = g_bs; 324 325 /* Create blob with 10 clusters */ 326 327 spdk_blob_opts_init(&opts); 328 opts.num_clusters = 10; 329 330 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 331 CU_ASSERT(g_bserrno == 0); 332 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 333 blobid = g_blobid; 334 335 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 336 CU_ASSERT(g_bserrno == 0); 337 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 338 blob = g_blob; 339 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 340 341 spdk_blob_close(blob, blob_op_complete, NULL); 342 CU_ASSERT(g_bserrno == 0); 343 344 /* Create blob with 0 clusters */ 345 346 spdk_blob_opts_init(&opts); 347 opts.num_clusters = 0; 348 349 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 350 CU_ASSERT(g_bserrno == 0); 351 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 352 blobid = g_blobid; 353 354 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 355 CU_ASSERT(g_bserrno == 0); 356 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 357 blob = g_blob; 358 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 359 360 spdk_blob_close(blob, blob_op_complete, NULL); 361 CU_ASSERT(g_bserrno == 0); 362 363 /* Create blob with default options (opts == NULL) */ 364 365 spdk_bs_create_blob_ext(bs, NULL, blob_op_with_id_complete, NULL); 366 CU_ASSERT(g_bserrno == 0); 367 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 368 blobid = g_blobid; 369 370 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 371 CU_ASSERT(g_bserrno == 0); 372 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 373 blob = g_blob; 374 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0) 375 376 spdk_blob_close(blob, blob_op_complete, NULL); 377 CU_ASSERT(g_bserrno == 0); 378 379 /* Try to create blob with size larger than blobstore */ 380 381 spdk_blob_opts_init(&opts); 382 opts.num_clusters = bs->total_clusters + 1; 383 384 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 385 CU_ASSERT(g_bserrno == -ENOSPC); 386 387 spdk_bs_unload(g_bs, bs_op_complete, NULL); 388 CU_ASSERT(g_bserrno == 0); 389 g_bs = NULL; 390 391 } 392 393 static void 394 blob_create_internal(void) 395 { 396 struct spdk_blob_store *bs; 397 struct spdk_bs_dev *dev; 398 struct spdk_blob *blob; 399 struct spdk_blob_opts opts; 400 struct spdk_blob_xattr_opts internal_xattrs; 401 const void *value; 402 size_t value_len; 403 spdk_blob_id blobid; 404 int rc; 405 406 dev = init_dev(); 407 408 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 409 CU_ASSERT(g_bserrno == 0); 410 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 411 bs = g_bs; 412 413 /* Create blob with custom xattrs */ 414 415 spdk_blob_opts_init(&opts); 416 _spdk_blob_xattrs_init(&internal_xattrs); 417 internal_xattrs.count = 3; 418 internal_xattrs.names = g_xattr_names; 419 internal_xattrs.get_value = _get_xattr_value; 420 internal_xattrs.ctx = &g_ctx; 421 422 _spdk_bs_create_blob(bs, &opts, &internal_xattrs, blob_op_with_id_complete, NULL); 423 CU_ASSERT(g_bserrno == 0); 424 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 425 blobid = g_blobid; 426 427 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 428 CU_ASSERT(g_bserrno == 0); 429 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 430 blob = g_blob; 431 432 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len, true); 433 CU_ASSERT(rc == 0); 434 SPDK_CU_ASSERT_FATAL(value != NULL); 435 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 436 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 437 438 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len, true); 439 CU_ASSERT(rc == 0); 440 SPDK_CU_ASSERT_FATAL(value != NULL); 441 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 442 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 443 444 rc = _spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len, true); 445 CU_ASSERT(rc == 0); 446 SPDK_CU_ASSERT_FATAL(value != NULL); 447 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 448 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 449 450 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 451 CU_ASSERT(rc != 0); 452 453 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 454 CU_ASSERT(rc != 0); 455 456 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 457 CU_ASSERT(rc != 0); 458 459 spdk_blob_close(blob, blob_op_complete, NULL); 460 CU_ASSERT(g_bserrno == 0); 461 462 /* Create blob with NULL internal options */ 463 464 _spdk_bs_create_blob(bs, NULL, NULL, blob_op_with_id_complete, NULL); 465 CU_ASSERT(g_bserrno == 0); 466 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 467 blobid = g_blobid; 468 469 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 470 CU_ASSERT(g_bserrno == 0); 471 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 472 CU_ASSERT(TAILQ_FIRST(&g_blob->xattrs_internal) == NULL); 473 474 blob = g_blob; 475 476 spdk_blob_close(blob, blob_op_complete, NULL); 477 CU_ASSERT(g_bserrno == 0); 478 479 spdk_bs_unload(g_bs, bs_op_complete, NULL); 480 CU_ASSERT(g_bserrno == 0); 481 g_bs = NULL; 482 483 } 484 485 static void 486 blob_thin_provision(void) 487 { 488 struct spdk_blob_store *bs; 489 struct spdk_bs_dev *dev; 490 struct spdk_blob *blob; 491 struct spdk_blob_opts opts; 492 struct spdk_bs_opts bs_opts; 493 spdk_blob_id blobid; 494 495 dev = init_dev(); 496 spdk_bs_opts_init(&bs_opts); 497 strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 498 499 /* Initialize a new blob store */ 500 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 501 CU_ASSERT(g_bserrno == 0); 502 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 503 504 bs = g_bs; 505 506 /* Create blob with thin provisioning enabled */ 507 508 spdk_blob_opts_init(&opts); 509 opts.thin_provision = true; 510 opts.num_clusters = 10; 511 512 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 513 CU_ASSERT(g_bserrno == 0); 514 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 515 blobid = g_blobid; 516 517 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 518 CU_ASSERT(g_bserrno == 0); 519 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 520 blob = g_blob; 521 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 522 523 spdk_blob_close(blob, blob_op_complete, NULL); 524 CU_ASSERT(g_bserrno == 0); 525 526 spdk_bs_unload(g_bs, bs_op_complete, NULL); 527 CU_ASSERT(g_bserrno == 0); 528 g_bs = NULL; 529 530 /* Load an existing blob store and check if invalid_flags is set */ 531 dev = init_dev(); 532 strncpy(bs_opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 533 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 534 CU_ASSERT(g_bserrno == 0); 535 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 536 537 bs = g_bs; 538 539 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 540 CU_ASSERT(g_bserrno == 0); 541 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 542 blob = g_blob; 543 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 544 545 spdk_blob_close(blob, blob_op_complete, NULL); 546 CU_ASSERT(g_bserrno == 0); 547 548 spdk_bs_unload(g_bs, bs_op_complete, NULL); 549 CU_ASSERT(g_bserrno == 0); 550 g_bs = NULL; 551 } 552 553 static void 554 blob_delete(void) 555 { 556 struct spdk_blob_store *bs; 557 struct spdk_bs_dev *dev; 558 spdk_blob_id blobid; 559 560 dev = init_dev(); 561 562 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 563 CU_ASSERT(g_bserrno == 0); 564 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 565 bs = g_bs; 566 567 /* Create a blob and then delete it. */ 568 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 569 CU_ASSERT(g_bserrno == 0); 570 CU_ASSERT(g_blobid > 0); 571 blobid = g_blobid; 572 573 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 574 CU_ASSERT(g_bserrno == 0); 575 576 /* Try to open the blob */ 577 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 578 CU_ASSERT(g_bserrno == -ENOENT); 579 580 spdk_bs_unload(g_bs, bs_op_complete, NULL); 581 CU_ASSERT(g_bserrno == 0); 582 g_bs = NULL; 583 } 584 585 static void 586 blob_resize(void) 587 { 588 struct spdk_blob_store *bs; 589 struct spdk_bs_dev *dev; 590 struct spdk_blob *blob; 591 spdk_blob_id blobid; 592 uint64_t free_clusters; 593 int rc; 594 595 dev = init_dev(); 596 597 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 598 CU_ASSERT(g_bserrno == 0); 599 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 600 bs = g_bs; 601 free_clusters = spdk_bs_free_cluster_count(bs); 602 603 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 604 CU_ASSERT(g_bserrno == 0); 605 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 606 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 607 blobid = g_blobid; 608 609 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 610 CU_ASSERT(g_bserrno == 0); 611 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 612 blob = g_blob; 613 614 /* Confirm that resize fails if blob is marked read-only. */ 615 blob->md_ro = true; 616 rc = spdk_blob_resize(blob, 5); 617 CU_ASSERT(rc == -EPERM); 618 blob->md_ro = false; 619 620 /* The blob started at 0 clusters. Resize it to be 5. */ 621 rc = spdk_blob_resize(blob, 5); 622 CU_ASSERT(rc == 0); 623 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 624 625 /* Shrink the blob to 3 clusters. This will not actually release 626 * the old clusters until the blob is synced. 627 */ 628 rc = spdk_blob_resize(blob, 3); 629 CU_ASSERT(rc == 0); 630 /* Verify there are still 5 clusters in use */ 631 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 632 633 spdk_blob_sync_md(blob, blob_op_complete, NULL); 634 CU_ASSERT(g_bserrno == 0); 635 /* Now there are only 3 clusters in use */ 636 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 637 638 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 639 rc = spdk_blob_resize(blob, 10); 640 CU_ASSERT(rc == 0); 641 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 642 643 /* Try to resize the blob to size larger than blobstore. */ 644 rc = spdk_blob_resize(blob, bs->total_clusters + 1); 645 CU_ASSERT(rc == -ENOSPC); 646 647 spdk_blob_close(blob, blob_op_complete, NULL); 648 CU_ASSERT(g_bserrno == 0); 649 650 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 651 CU_ASSERT(g_bserrno == 0); 652 653 spdk_bs_unload(g_bs, bs_op_complete, NULL); 654 CU_ASSERT(g_bserrno == 0); 655 g_bs = NULL; 656 } 657 658 static void 659 blob_read_only(void) 660 { 661 struct spdk_blob_store *bs; 662 struct spdk_bs_dev *dev; 663 struct spdk_blob *blob; 664 struct spdk_bs_opts opts; 665 spdk_blob_id blobid; 666 int rc; 667 668 dev = init_dev(); 669 spdk_bs_opts_init(&opts); 670 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 671 672 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 673 CU_ASSERT(g_bserrno == 0); 674 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 675 bs = g_bs; 676 677 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 678 CU_ASSERT(g_bserrno == 0); 679 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 680 blobid = g_blobid; 681 682 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 683 CU_ASSERT(g_bserrno == 0); 684 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 685 blob = g_blob; 686 687 rc = spdk_blob_set_read_only(blob); 688 CU_ASSERT(rc == 0); 689 690 CU_ASSERT(blob->data_ro == false); 691 CU_ASSERT(blob->md_ro == false); 692 693 spdk_blob_sync_md(blob, bs_op_complete, NULL); 694 695 CU_ASSERT(blob->data_ro == true); 696 CU_ASSERT(blob->md_ro == true); 697 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 698 699 spdk_blob_close(blob, blob_op_complete, NULL); 700 CU_ASSERT(g_bserrno == 0); 701 702 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 703 CU_ASSERT(g_bserrno == 0); 704 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 705 blob = g_blob; 706 707 CU_ASSERT(blob->data_ro == true); 708 CU_ASSERT(blob->md_ro == true); 709 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 710 711 spdk_blob_close(blob, blob_op_complete, NULL); 712 CU_ASSERT(g_bserrno == 0); 713 714 spdk_bs_unload(g_bs, bs_op_complete, NULL); 715 CU_ASSERT(g_bserrno == 0); 716 g_bs = NULL; 717 g_blob = NULL; 718 g_blobid = 0; 719 720 /* Load an existing blob store */ 721 dev = init_dev(); 722 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 723 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 724 CU_ASSERT(g_bserrno == 0); 725 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 726 727 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 728 CU_ASSERT(g_bserrno == 0); 729 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 730 blob = g_blob; 731 732 CU_ASSERT(blob->data_ro == true); 733 CU_ASSERT(blob->md_ro == true); 734 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 735 736 spdk_blob_close(blob, blob_op_complete, NULL); 737 CU_ASSERT(g_bserrno == 0); 738 739 spdk_bs_unload(g_bs, bs_op_complete, NULL); 740 CU_ASSERT(g_bserrno == 0); 741 742 } 743 744 static void 745 channel_ops(void) 746 { 747 struct spdk_blob_store *bs; 748 struct spdk_bs_dev *dev; 749 struct spdk_io_channel *channel; 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 channel = spdk_bs_alloc_io_channel(bs); 759 CU_ASSERT(channel != NULL); 760 761 spdk_bs_free_io_channel(channel); 762 763 spdk_bs_unload(g_bs, bs_op_complete, NULL); 764 CU_ASSERT(g_bserrno == 0); 765 g_bs = NULL; 766 } 767 768 static void 769 blob_write(void) 770 { 771 struct spdk_blob_store *bs; 772 struct spdk_bs_dev *dev; 773 struct spdk_blob *blob; 774 struct spdk_io_channel *channel; 775 spdk_blob_id blobid; 776 uint64_t pages_per_cluster; 777 uint8_t payload[10 * 4096]; 778 int rc; 779 780 dev = init_dev(); 781 782 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 783 CU_ASSERT(g_bserrno == 0); 784 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 785 bs = g_bs; 786 787 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 788 789 channel = spdk_bs_alloc_io_channel(bs); 790 CU_ASSERT(channel != NULL); 791 792 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 793 CU_ASSERT(g_bserrno == 0); 794 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 795 blobid = g_blobid; 796 797 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 798 CU_ASSERT(g_bserrno == 0); 799 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 800 blob = g_blob; 801 802 /* Write to a blob with 0 size */ 803 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 804 CU_ASSERT(g_bserrno == -EINVAL); 805 806 /* Resize the blob */ 807 rc = spdk_blob_resize(blob, 5); 808 CU_ASSERT(rc == 0); 809 810 /* Confirm that write fails if blob is marked read-only. */ 811 blob->data_ro = true; 812 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 813 CU_ASSERT(g_bserrno == -EPERM); 814 blob->data_ro = false; 815 816 /* Write to the blob */ 817 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 818 CU_ASSERT(g_bserrno == 0); 819 820 /* Write starting beyond the end */ 821 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 822 NULL); 823 CU_ASSERT(g_bserrno == -EINVAL); 824 825 /* Write starting at a valid location but going off the end */ 826 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 827 blob_op_complete, NULL); 828 CU_ASSERT(g_bserrno == -EINVAL); 829 830 spdk_blob_close(blob, blob_op_complete, NULL); 831 CU_ASSERT(g_bserrno == 0); 832 833 spdk_bs_free_io_channel(channel); 834 835 spdk_bs_unload(g_bs, bs_op_complete, NULL); 836 CU_ASSERT(g_bserrno == 0); 837 g_bs = NULL; 838 } 839 840 static void 841 blob_read(void) 842 { 843 struct spdk_blob_store *bs; 844 struct spdk_bs_dev *dev; 845 struct spdk_blob *blob; 846 struct spdk_io_channel *channel; 847 spdk_blob_id blobid; 848 uint64_t pages_per_cluster; 849 uint8_t payload[10 * 4096]; 850 int rc; 851 852 dev = init_dev(); 853 854 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 855 CU_ASSERT(g_bserrno == 0); 856 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 857 bs = g_bs; 858 859 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 860 861 channel = spdk_bs_alloc_io_channel(bs); 862 CU_ASSERT(channel != NULL); 863 864 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 865 CU_ASSERT(g_bserrno == 0); 866 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 867 blobid = g_blobid; 868 869 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 870 CU_ASSERT(g_bserrno == 0); 871 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 872 blob = g_blob; 873 874 /* Read from a blob with 0 size */ 875 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 876 CU_ASSERT(g_bserrno == -EINVAL); 877 878 /* Resize the blob */ 879 rc = spdk_blob_resize(blob, 5); 880 CU_ASSERT(rc == 0); 881 882 /* Confirm that read passes if blob is marked read-only. */ 883 blob->data_ro = true; 884 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 885 CU_ASSERT(g_bserrno == 0); 886 blob->data_ro = false; 887 888 /* Read from the blob */ 889 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 890 CU_ASSERT(g_bserrno == 0); 891 892 /* Read starting beyond the end */ 893 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 894 NULL); 895 CU_ASSERT(g_bserrno == -EINVAL); 896 897 /* Read starting at a valid location but going off the end */ 898 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 899 blob_op_complete, NULL); 900 CU_ASSERT(g_bserrno == -EINVAL); 901 902 spdk_blob_close(blob, blob_op_complete, NULL); 903 CU_ASSERT(g_bserrno == 0); 904 905 spdk_bs_free_io_channel(channel); 906 907 spdk_bs_unload(g_bs, bs_op_complete, NULL); 908 CU_ASSERT(g_bserrno == 0); 909 g_bs = NULL; 910 } 911 912 static void 913 blob_rw_verify(void) 914 { 915 struct spdk_blob_store *bs; 916 struct spdk_bs_dev *dev; 917 struct spdk_blob *blob; 918 struct spdk_io_channel *channel; 919 spdk_blob_id blobid; 920 uint8_t payload_read[10 * 4096]; 921 uint8_t payload_write[10 * 4096]; 922 int rc; 923 924 dev = init_dev(); 925 926 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 927 CU_ASSERT(g_bserrno == 0); 928 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 929 bs = g_bs; 930 931 channel = spdk_bs_alloc_io_channel(bs); 932 CU_ASSERT(channel != NULL); 933 934 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 935 CU_ASSERT(g_bserrno == 0); 936 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 937 blobid = g_blobid; 938 939 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 940 CU_ASSERT(g_bserrno == 0); 941 CU_ASSERT(g_blob != NULL); 942 blob = g_blob; 943 944 rc = spdk_blob_resize(blob, 32); 945 CU_ASSERT(rc == 0); 946 947 memset(payload_write, 0xE5, sizeof(payload_write)); 948 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 949 CU_ASSERT(g_bserrno == 0); 950 951 memset(payload_read, 0x00, sizeof(payload_read)); 952 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 953 CU_ASSERT(g_bserrno == 0); 954 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 955 956 spdk_blob_close(blob, blob_op_complete, NULL); 957 CU_ASSERT(g_bserrno == 0); 958 959 spdk_bs_free_io_channel(channel); 960 961 spdk_bs_unload(g_bs, bs_op_complete, NULL); 962 CU_ASSERT(g_bserrno == 0); 963 g_bs = NULL; 964 } 965 966 static void 967 blob_rw_verify_iov(void) 968 { 969 struct spdk_blob_store *bs; 970 struct spdk_bs_dev *dev; 971 struct spdk_blob *blob; 972 struct spdk_io_channel *channel; 973 spdk_blob_id blobid; 974 uint8_t payload_read[10 * 4096]; 975 uint8_t payload_write[10 * 4096]; 976 struct iovec iov_read[3]; 977 struct iovec iov_write[3]; 978 void *buf; 979 int rc; 980 981 dev = init_dev(); 982 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 983 984 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 985 CU_ASSERT(g_bserrno == 0); 986 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 987 bs = g_bs; 988 989 channel = spdk_bs_alloc_io_channel(bs); 990 CU_ASSERT(channel != NULL); 991 992 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 993 CU_ASSERT(g_bserrno == 0); 994 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 995 blobid = g_blobid; 996 997 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 998 CU_ASSERT(g_bserrno == 0); 999 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1000 blob = g_blob; 1001 1002 rc = spdk_blob_resize(blob, 2); 1003 CU_ASSERT(rc == 0); 1004 1005 /* 1006 * Manually adjust the offset of the blob's second cluster. This allows 1007 * us to make sure that the readv/write code correctly accounts for I/O 1008 * that cross cluster boundaries. Start by asserting that the allocated 1009 * clusters are where we expect before modifying the second cluster. 1010 */ 1011 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1012 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1013 blob->active.clusters[1] = 3 * 256; 1014 1015 memset(payload_write, 0xE5, sizeof(payload_write)); 1016 iov_write[0].iov_base = payload_write; 1017 iov_write[0].iov_len = 1 * 4096; 1018 iov_write[1].iov_base = payload_write + 1 * 4096; 1019 iov_write[1].iov_len = 5 * 4096; 1020 iov_write[2].iov_base = payload_write + 6 * 4096; 1021 iov_write[2].iov_len = 4 * 4096; 1022 /* 1023 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1024 * will get written to the first cluster, the last 4 to the second cluster. 1025 */ 1026 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1027 CU_ASSERT(g_bserrno == 0); 1028 1029 memset(payload_read, 0xAA, sizeof(payload_read)); 1030 iov_read[0].iov_base = payload_read; 1031 iov_read[0].iov_len = 3 * 4096; 1032 iov_read[1].iov_base = payload_read + 3 * 4096; 1033 iov_read[1].iov_len = 4 * 4096; 1034 iov_read[2].iov_base = payload_read + 7 * 4096; 1035 iov_read[2].iov_len = 3 * 4096; 1036 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1037 CU_ASSERT(g_bserrno == 0); 1038 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1039 1040 buf = calloc(1, 256 * 4096); 1041 SPDK_CU_ASSERT_FATAL(buf != NULL); 1042 /* Check that cluster 2 on "disk" was not modified. */ 1043 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1044 free(buf); 1045 1046 spdk_blob_close(blob, blob_op_complete, NULL); 1047 CU_ASSERT(g_bserrno == 0); 1048 1049 spdk_bs_free_io_channel(channel); 1050 1051 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1052 CU_ASSERT(g_bserrno == 0); 1053 g_bs = NULL; 1054 } 1055 1056 static uint32_t 1057 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1058 { 1059 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1060 struct spdk_bs_request_set *set; 1061 uint32_t count = 0; 1062 1063 TAILQ_FOREACH(set, &channel->reqs, link) { 1064 count++; 1065 } 1066 1067 return count; 1068 } 1069 1070 static void 1071 blob_rw_verify_iov_nomem(void) 1072 { 1073 struct spdk_blob_store *bs; 1074 struct spdk_bs_dev *dev; 1075 struct spdk_blob *blob; 1076 struct spdk_io_channel *channel; 1077 spdk_blob_id blobid; 1078 uint8_t payload_write[10 * 4096]; 1079 struct iovec iov_write[3]; 1080 uint32_t req_count; 1081 int rc; 1082 1083 dev = init_dev(); 1084 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1085 1086 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1087 CU_ASSERT(g_bserrno == 0); 1088 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1089 bs = g_bs; 1090 1091 channel = spdk_bs_alloc_io_channel(bs); 1092 CU_ASSERT(channel != NULL); 1093 1094 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1095 CU_ASSERT(g_bserrno == 0); 1096 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1097 blobid = g_blobid; 1098 1099 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1100 CU_ASSERT(g_bserrno == 0); 1101 CU_ASSERT(g_blob != NULL); 1102 blob = g_blob; 1103 1104 rc = spdk_blob_resize(blob, 2); 1105 CU_ASSERT(rc == 0); 1106 1107 /* 1108 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1109 * will get written to the first cluster, the last 4 to the second cluster. 1110 */ 1111 iov_write[0].iov_base = payload_write; 1112 iov_write[0].iov_len = 1 * 4096; 1113 iov_write[1].iov_base = payload_write + 1 * 4096; 1114 iov_write[1].iov_len = 5 * 4096; 1115 iov_write[2].iov_base = payload_write + 6 * 4096; 1116 iov_write[2].iov_len = 4 * 4096; 1117 MOCK_SET(calloc, void *, NULL); 1118 req_count = bs_channel_get_req_count(channel); 1119 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1120 CU_ASSERT(g_bserrno = -ENOMEM); 1121 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1122 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 1123 1124 spdk_blob_close(blob, blob_op_complete, NULL); 1125 CU_ASSERT(g_bserrno == 0); 1126 1127 spdk_bs_free_io_channel(channel); 1128 1129 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1130 CU_ASSERT(g_bserrno == 0); 1131 g_bs = NULL; 1132 } 1133 1134 static void 1135 blob_rw_iov_read_only(void) 1136 { 1137 struct spdk_blob_store *bs; 1138 struct spdk_bs_dev *dev; 1139 struct spdk_blob *blob; 1140 struct spdk_io_channel *channel; 1141 spdk_blob_id blobid; 1142 uint8_t payload_read[4096]; 1143 uint8_t payload_write[4096]; 1144 struct iovec iov_read; 1145 struct iovec iov_write; 1146 int rc; 1147 1148 dev = init_dev(); 1149 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1150 1151 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1152 CU_ASSERT(g_bserrno == 0); 1153 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1154 bs = g_bs; 1155 1156 channel = spdk_bs_alloc_io_channel(bs); 1157 CU_ASSERT(channel != NULL); 1158 1159 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1160 CU_ASSERT(g_bserrno == 0); 1161 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1162 blobid = g_blobid; 1163 1164 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1165 CU_ASSERT(g_bserrno == 0); 1166 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1167 blob = g_blob; 1168 1169 rc = spdk_blob_resize(blob, 2); 1170 CU_ASSERT(rc == 0); 1171 1172 /* Verify that writev failed if read_only flag is set. */ 1173 blob->data_ro = true; 1174 iov_write.iov_base = payload_write; 1175 iov_write.iov_len = sizeof(payload_write); 1176 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1177 CU_ASSERT(g_bserrno == -EPERM); 1178 1179 /* Verify that reads pass if data_ro flag is set. */ 1180 iov_read.iov_base = payload_read; 1181 iov_read.iov_len = sizeof(payload_read); 1182 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1183 CU_ASSERT(g_bserrno == 0); 1184 1185 spdk_blob_close(blob, blob_op_complete, NULL); 1186 CU_ASSERT(g_bserrno == 0); 1187 1188 spdk_bs_free_io_channel(channel); 1189 1190 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1191 CU_ASSERT(g_bserrno == 0); 1192 g_bs = NULL; 1193 } 1194 1195 static void 1196 blob_unmap(void) 1197 { 1198 struct spdk_blob_store *bs; 1199 struct spdk_bs_dev *dev; 1200 struct spdk_blob *blob; 1201 struct spdk_io_channel *channel; 1202 spdk_blob_id blobid; 1203 struct spdk_blob_opts opts; 1204 uint8_t payload[4096]; 1205 int rc; 1206 int i; 1207 1208 dev = init_dev(); 1209 1210 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1211 CU_ASSERT(g_bserrno == 0); 1212 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1213 bs = g_bs; 1214 1215 channel = spdk_bs_alloc_io_channel(bs); 1216 CU_ASSERT(channel != NULL); 1217 1218 spdk_blob_opts_init(&opts); 1219 opts.num_clusters = 10; 1220 1221 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1222 CU_ASSERT(g_bserrno == 0); 1223 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1224 blobid = g_blobid; 1225 1226 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1227 CU_ASSERT(g_bserrno == 0); 1228 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1229 blob = g_blob; 1230 1231 rc = spdk_blob_resize(blob, 10); 1232 CU_ASSERT(rc == 0); 1233 1234 memset(payload, 0, sizeof(payload)); 1235 payload[0] = 0xFF; 1236 1237 /* 1238 * Set first byte of every cluster to 0xFF. 1239 * First cluster on device is reserved so let's start from cluster number 1 1240 */ 1241 for (i = 1; i < 11; i++) { 1242 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 1243 } 1244 1245 /* Confirm writes */ 1246 for (i = 0; i < 10; i++) { 1247 payload[0] = 0; 1248 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 1249 blob_op_complete, NULL); 1250 CU_ASSERT(g_bserrno == 0); 1251 CU_ASSERT(payload[0] == 0xFF); 1252 } 1253 1254 /* Mark some clusters as unallocated */ 1255 blob->active.clusters[1] = 0; 1256 blob->active.clusters[2] = 0; 1257 blob->active.clusters[3] = 0; 1258 blob->active.clusters[6] = 0; 1259 blob->active.clusters[8] = 0; 1260 1261 /* Unmap clusters by resizing to 0 */ 1262 rc = spdk_blob_resize(blob, 0); 1263 CU_ASSERT(rc == 0); 1264 1265 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1266 CU_ASSERT(g_bserrno == 0); 1267 1268 /* Confirm that only 'allocated' clusters were unmaped */ 1269 for (i = 1; i < 11; i++) { 1270 switch (i) { 1271 case 2: 1272 case 3: 1273 case 4: 1274 case 7: 1275 case 9: 1276 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 1277 break; 1278 default: 1279 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 1280 break; 1281 } 1282 } 1283 1284 spdk_blob_close(blob, blob_op_complete, NULL); 1285 CU_ASSERT(g_bserrno == 0); 1286 1287 spdk_bs_free_io_channel(channel); 1288 1289 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1290 CU_ASSERT(g_bserrno == 0); 1291 g_bs = NULL; 1292 } 1293 1294 1295 static void 1296 blob_iter(void) 1297 { 1298 struct spdk_blob_store *bs; 1299 struct spdk_bs_dev *dev; 1300 struct spdk_blob *blob; 1301 spdk_blob_id blobid; 1302 1303 dev = init_dev(); 1304 1305 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1306 CU_ASSERT(g_bserrno == 0); 1307 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1308 bs = g_bs; 1309 1310 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1311 CU_ASSERT(g_blob == NULL); 1312 CU_ASSERT(g_bserrno == -ENOENT); 1313 1314 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1315 CU_ASSERT(g_bserrno == 0); 1316 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1317 blobid = g_blobid; 1318 1319 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1320 CU_ASSERT(g_blob != NULL); 1321 CU_ASSERT(g_bserrno == 0); 1322 blob = g_blob; 1323 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1324 1325 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1326 CU_ASSERT(g_blob == NULL); 1327 CU_ASSERT(g_bserrno == -ENOENT); 1328 1329 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1330 CU_ASSERT(g_bserrno == 0); 1331 g_bs = NULL; 1332 } 1333 1334 static void 1335 blob_xattr(void) 1336 { 1337 struct spdk_blob_store *bs; 1338 struct spdk_bs_dev *dev; 1339 struct spdk_blob *blob; 1340 spdk_blob_id blobid; 1341 uint64_t length; 1342 int rc; 1343 const char *name1, *name2; 1344 const void *value; 1345 size_t value_len; 1346 struct spdk_xattr_names *names; 1347 1348 dev = init_dev(); 1349 1350 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1351 CU_ASSERT(g_bserrno == 0); 1352 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1353 bs = g_bs; 1354 1355 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1356 CU_ASSERT(g_bserrno == 0); 1357 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1358 blobid = g_blobid; 1359 1360 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1361 CU_ASSERT(g_bserrno == 0); 1362 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1363 blob = g_blob; 1364 1365 /* Test that set_xattr fails if md_ro flag is set. */ 1366 blob->md_ro = true; 1367 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1368 CU_ASSERT(rc == -EPERM); 1369 1370 blob->md_ro = false; 1371 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1372 CU_ASSERT(rc == 0); 1373 1374 length = 2345; 1375 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1376 CU_ASSERT(rc == 0); 1377 1378 /* Overwrite "length" xattr. */ 1379 length = 3456; 1380 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1381 CU_ASSERT(rc == 0); 1382 1383 /* get_xattr should still work even if md_ro flag is set. */ 1384 value = NULL; 1385 blob->md_ro = true; 1386 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1387 CU_ASSERT(rc == 0); 1388 SPDK_CU_ASSERT_FATAL(value != NULL); 1389 CU_ASSERT(*(uint64_t *)value == length); 1390 CU_ASSERT(value_len == 8); 1391 blob->md_ro = false; 1392 1393 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1394 CU_ASSERT(rc == -ENOENT); 1395 1396 names = NULL; 1397 rc = spdk_blob_get_xattr_names(blob, &names); 1398 CU_ASSERT(rc == 0); 1399 SPDK_CU_ASSERT_FATAL(names != NULL); 1400 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1401 name1 = spdk_xattr_names_get_name(names, 0); 1402 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1403 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1404 name2 = spdk_xattr_names_get_name(names, 1); 1405 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1406 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1407 CU_ASSERT(strcmp(name1, name2)); 1408 spdk_xattr_names_free(names); 1409 1410 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1411 blob->md_ro = true; 1412 rc = spdk_blob_remove_xattr(blob, "name"); 1413 CU_ASSERT(rc == -EPERM); 1414 1415 blob->md_ro = false; 1416 rc = spdk_blob_remove_xattr(blob, "name"); 1417 CU_ASSERT(rc == 0); 1418 1419 rc = spdk_blob_remove_xattr(blob, "foobar"); 1420 CU_ASSERT(rc == -ENOENT); 1421 1422 /* Set internal xattr */ 1423 length = 7898; 1424 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 1425 CU_ASSERT(rc == 0); 1426 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1427 CU_ASSERT(rc == 0); 1428 CU_ASSERT(*(uint64_t *)value == length); 1429 /* try to get public xattr with same name */ 1430 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1431 CU_ASSERT(rc != 0); 1432 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 1433 CU_ASSERT(rc != 0); 1434 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 1435 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 1436 SPDK_BLOB_INTERNAL_XATTR) 1437 1438 spdk_blob_close(blob, blob_op_complete, NULL); 1439 1440 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1441 1442 /* Check if xattrs are persisted */ 1443 dev = init_dev(); 1444 1445 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1446 CU_ASSERT(g_bserrno == 0); 1447 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1448 1449 bs = g_bs; 1450 1451 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1452 CU_ASSERT(g_bserrno == 0); 1453 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1454 blob = g_blob; 1455 1456 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1457 CU_ASSERT(rc == 0); 1458 CU_ASSERT(*(uint64_t *)value == length); 1459 1460 /* try to get internal xattr trough public call */ 1461 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1462 CU_ASSERT(rc != 0); 1463 1464 rc = _spdk_blob_remove_xattr(blob, "internal", true); 1465 CU_ASSERT(rc == 0); 1466 1467 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 1468 1469 CU_ASSERT(g_bserrno == 0); 1470 g_bs = NULL; 1471 } 1472 1473 static void 1474 bs_load(void) 1475 { 1476 struct spdk_bs_dev *dev; 1477 spdk_blob_id blobid; 1478 struct spdk_blob *blob; 1479 struct spdk_bs_super_block *super_block; 1480 uint64_t length; 1481 int rc; 1482 const void *value; 1483 size_t value_len; 1484 struct spdk_bs_opts opts; 1485 1486 dev = init_dev(); 1487 spdk_bs_opts_init(&opts); 1488 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1489 1490 /* Initialize a new blob store */ 1491 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1492 CU_ASSERT(g_bserrno == 0); 1493 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1494 1495 /* Try to open a blobid that does not exist */ 1496 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1497 CU_ASSERT(g_bserrno == -ENOENT); 1498 CU_ASSERT(g_blob == NULL); 1499 1500 /* Create a blob */ 1501 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1502 CU_ASSERT(g_bserrno == 0); 1503 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1504 blobid = g_blobid; 1505 1506 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1507 CU_ASSERT(g_bserrno == 0); 1508 CU_ASSERT(g_blob != NULL); 1509 blob = g_blob; 1510 1511 /* Try again to open valid blob but without the upper bit set */ 1512 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1513 CU_ASSERT(g_bserrno == -ENOENT); 1514 CU_ASSERT(g_blob == NULL); 1515 1516 /* Set some xattrs */ 1517 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1518 CU_ASSERT(rc == 0); 1519 1520 length = 2345; 1521 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1522 CU_ASSERT(rc == 0); 1523 1524 /* Resize the blob */ 1525 rc = spdk_blob_resize(blob, 10); 1526 CU_ASSERT(rc == 0); 1527 1528 spdk_blob_close(blob, blob_op_complete, NULL); 1529 CU_ASSERT(g_bserrno == 0); 1530 blob = NULL; 1531 g_blob = NULL; 1532 g_blobid = SPDK_BLOBID_INVALID; 1533 1534 /* Unload the blob store */ 1535 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1536 CU_ASSERT(g_bserrno == 0); 1537 g_bs = NULL; 1538 g_blob = NULL; 1539 g_blobid = 0; 1540 1541 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1542 CU_ASSERT(super_block->clean == 1); 1543 1544 /* Load should fail for device with an unsupported blocklen */ 1545 dev = init_dev(); 1546 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 1547 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1548 CU_ASSERT(g_bserrno == -EINVAL); 1549 1550 /* Load should when max_md_ops is set to zero */ 1551 dev = init_dev(); 1552 spdk_bs_opts_init(&opts); 1553 opts.max_md_ops = 0; 1554 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1555 CU_ASSERT(g_bserrno == -EINVAL); 1556 1557 /* Load should when max_channel_ops is set to zero */ 1558 dev = init_dev(); 1559 spdk_bs_opts_init(&opts); 1560 opts.max_channel_ops = 0; 1561 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1562 CU_ASSERT(g_bserrno == -EINVAL); 1563 1564 /* Load an existing blob store */ 1565 dev = init_dev(); 1566 spdk_bs_opts_init(&opts); 1567 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1568 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1569 CU_ASSERT(g_bserrno == 0); 1570 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1571 1572 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1573 CU_ASSERT(super_block->clean == 0); 1574 1575 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1576 CU_ASSERT(g_bserrno == 0); 1577 CU_ASSERT(g_blob != NULL); 1578 blob = g_blob; 1579 1580 /* Get the xattrs */ 1581 value = NULL; 1582 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1583 CU_ASSERT(rc == 0); 1584 SPDK_CU_ASSERT_FATAL(value != NULL); 1585 CU_ASSERT(*(uint64_t *)value == length); 1586 CU_ASSERT(value_len == 8); 1587 1588 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1589 CU_ASSERT(rc == -ENOENT); 1590 1591 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1592 1593 spdk_blob_close(blob, blob_op_complete, NULL); 1594 CU_ASSERT(g_bserrno == 0); 1595 blob = NULL; 1596 g_blob = NULL; 1597 g_blobid = SPDK_BLOBID_INVALID; 1598 1599 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1600 CU_ASSERT(g_bserrno == 0); 1601 g_bs = NULL; 1602 } 1603 1604 static void 1605 bs_type(void) 1606 { 1607 struct spdk_bs_dev *dev; 1608 struct spdk_bs_opts opts; 1609 1610 dev = init_dev(); 1611 spdk_bs_opts_init(&opts); 1612 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1613 1614 /* Initialize a new blob store */ 1615 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1616 CU_ASSERT(g_bserrno == 0); 1617 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1618 1619 /* Unload the blob store */ 1620 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1621 CU_ASSERT(g_bserrno == 0); 1622 g_bs = NULL; 1623 g_blob = NULL; 1624 g_blobid = 0; 1625 1626 /* Load non existing blobstore type */ 1627 dev = init_dev(); 1628 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1629 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1630 CU_ASSERT(g_bserrno != 0); 1631 1632 /* Load with empty blobstore type */ 1633 dev = init_dev(); 1634 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1635 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1636 CU_ASSERT(g_bserrno == 0); 1637 1638 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1639 CU_ASSERT(g_bserrno == 0); 1640 g_bs = NULL; 1641 1642 /* Initialize a new blob store with empty bstype */ 1643 dev = init_dev(); 1644 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1645 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1646 CU_ASSERT(g_bserrno == 0); 1647 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1648 1649 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1650 CU_ASSERT(g_bserrno == 0); 1651 g_bs = NULL; 1652 1653 /* Load non existing blobstore type */ 1654 dev = init_dev(); 1655 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1656 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1657 CU_ASSERT(g_bserrno != 0); 1658 1659 /* Load with empty blobstore type */ 1660 dev = init_dev(); 1661 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1662 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1663 CU_ASSERT(g_bserrno == 0); 1664 1665 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1666 CU_ASSERT(g_bserrno == 0); 1667 g_bs = NULL; 1668 } 1669 1670 static void 1671 bs_super_block(void) 1672 { 1673 struct spdk_bs_dev *dev; 1674 struct spdk_bs_super_block *super_block; 1675 struct spdk_bs_opts opts; 1676 struct spdk_bs_super_block_ver1 super_block_v1; 1677 1678 dev = init_dev(); 1679 spdk_bs_opts_init(&opts); 1680 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1681 1682 /* Initialize a new blob store */ 1683 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1684 CU_ASSERT(g_bserrno == 0); 1685 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1686 1687 /* Unload the blob store */ 1688 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1689 CU_ASSERT(g_bserrno == 0); 1690 g_bs = NULL; 1691 g_blob = NULL; 1692 g_blobid = 0; 1693 1694 /* Load an existing blob store with version newer than supported */ 1695 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1696 super_block->version++; 1697 1698 dev = init_dev(); 1699 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1700 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1701 CU_ASSERT(g_bserrno != 0); 1702 1703 /* Create a new blob store with super block version 1 */ 1704 dev = init_dev(); 1705 super_block_v1.version = 1; 1706 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1707 super_block_v1.length = 0x1000; 1708 super_block_v1.clean = 1; 1709 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1710 super_block_v1.cluster_size = 0x100000; 1711 super_block_v1.used_page_mask_start = 0x01; 1712 super_block_v1.used_page_mask_len = 0x01; 1713 super_block_v1.used_cluster_mask_start = 0x02; 1714 super_block_v1.used_cluster_mask_len = 0x01; 1715 super_block_v1.md_start = 0x03; 1716 super_block_v1.md_len = 0x40; 1717 memset(super_block_v1.reserved, 0, 4036); 1718 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1719 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1720 1721 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1722 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1723 CU_ASSERT(g_bserrno == 0); 1724 1725 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1726 CU_ASSERT(g_bserrno == 0); 1727 g_bs = NULL; 1728 } 1729 1730 /* 1731 * Create a blobstore and then unload it. 1732 */ 1733 static void 1734 bs_unload(void) 1735 { 1736 struct spdk_bs_dev *dev; 1737 struct spdk_blob_store *bs; 1738 spdk_blob_id blobid; 1739 struct spdk_blob *blob; 1740 1741 dev = init_dev(); 1742 1743 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1744 CU_ASSERT(g_bserrno == 0); 1745 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1746 bs = g_bs; 1747 1748 /* Create a blob and open it. */ 1749 g_bserrno = -1; 1750 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1751 CU_ASSERT(g_bserrno == 0); 1752 CU_ASSERT(g_blobid > 0); 1753 blobid = g_blobid; 1754 1755 g_bserrno = -1; 1756 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1757 CU_ASSERT(g_bserrno == 0); 1758 CU_ASSERT(g_blob != NULL); 1759 blob = g_blob; 1760 1761 /* Try to unload blobstore, should fail with open blob */ 1762 g_bserrno = -1; 1763 spdk_bs_unload(bs, bs_op_complete, NULL); 1764 CU_ASSERT(g_bserrno == -EBUSY); 1765 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1766 1767 /* Close the blob, then successfully unload blobstore */ 1768 g_bserrno = -1; 1769 spdk_blob_close(blob, blob_op_complete, NULL); 1770 CU_ASSERT(g_bserrno == 0); 1771 1772 g_bserrno = -1; 1773 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1774 CU_ASSERT(g_bserrno == 0); 1775 g_bs = NULL; 1776 } 1777 1778 /* 1779 * Create a blobstore with a cluster size different than the default, and ensure it is 1780 * persisted. 1781 */ 1782 static void 1783 bs_cluster_sz(void) 1784 { 1785 struct spdk_bs_dev *dev; 1786 struct spdk_bs_opts opts; 1787 uint32_t cluster_sz; 1788 1789 /* Set cluster size to zero */ 1790 dev = init_dev(); 1791 spdk_bs_opts_init(&opts); 1792 opts.cluster_sz = 0; 1793 1794 /* Initialize a new blob store */ 1795 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1796 CU_ASSERT(g_bserrno == -EINVAL); 1797 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1798 1799 /* 1800 * Set cluster size to blobstore page size, 1801 * to work it is required to be at least twice the blobstore page size. 1802 */ 1803 dev = init_dev(); 1804 spdk_bs_opts_init(&opts); 1805 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1806 1807 /* Initialize a new blob store */ 1808 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1809 CU_ASSERT(g_bserrno == -ENOMEM); 1810 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1811 1812 /* 1813 * Set cluster size to lower than page size, 1814 * to work it is required to be at least twice the blobstore page size. 1815 */ 1816 dev = init_dev(); 1817 spdk_bs_opts_init(&opts); 1818 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1819 1820 /* Initialize a new blob store */ 1821 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1822 CU_ASSERT(g_bserrno == -ENOMEM); 1823 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1824 1825 /* Set cluster size to twice the default */ 1826 dev = init_dev(); 1827 spdk_bs_opts_init(&opts); 1828 opts.cluster_sz *= 2; 1829 cluster_sz = opts.cluster_sz; 1830 1831 /* Initialize a new blob store */ 1832 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1833 CU_ASSERT(g_bserrno == 0); 1834 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1835 1836 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1837 1838 /* Unload the blob store */ 1839 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1840 CU_ASSERT(g_bserrno == 0); 1841 g_bs = NULL; 1842 g_blob = NULL; 1843 g_blobid = 0; 1844 1845 dev = init_dev(); 1846 /* Load an existing blob store */ 1847 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1848 CU_ASSERT(g_bserrno == 0); 1849 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1850 1851 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1852 1853 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1854 CU_ASSERT(g_bserrno == 0); 1855 g_bs = NULL; 1856 } 1857 1858 /* 1859 * Create a blobstore, reload it and ensure total usable cluster count 1860 * stays the same. 1861 */ 1862 static void 1863 bs_usable_clusters(void) 1864 { 1865 struct spdk_bs_dev *dev; 1866 struct spdk_bs_opts opts; 1867 uint32_t clusters; 1868 int i, rc; 1869 1870 /* Init blobstore */ 1871 dev = init_dev(); 1872 spdk_bs_opts_init(&opts); 1873 1874 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1875 CU_ASSERT(g_bserrno == 0); 1876 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1877 1878 clusters = spdk_bs_total_data_cluster_count(g_bs); 1879 1880 /* Unload the blob store */ 1881 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1882 CU_ASSERT(g_bserrno == 0); 1883 g_bs = NULL; 1884 1885 dev = init_dev(); 1886 /* Load an existing blob store */ 1887 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1888 CU_ASSERT(g_bserrno == 0); 1889 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1890 1891 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1892 1893 /* Create and resize blobs to make sure that useable cluster count won't change */ 1894 for (i = 0; i < 4; i++) { 1895 g_bserrno = -1; 1896 g_blobid = SPDK_BLOBID_INVALID; 1897 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1898 CU_ASSERT(g_bserrno == 0); 1899 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1900 1901 g_bserrno = -1; 1902 g_blob = NULL; 1903 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1904 CU_ASSERT(g_bserrno == 0); 1905 CU_ASSERT(g_blob != NULL); 1906 1907 rc = spdk_blob_resize(g_blob, 10); 1908 CU_ASSERT(rc == 0); 1909 1910 g_bserrno = -1; 1911 spdk_blob_close(g_blob, blob_op_complete, NULL); 1912 CU_ASSERT(g_bserrno == 0); 1913 1914 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1915 } 1916 1917 /* Reload the blob store to make sure that nothing changed */ 1918 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1919 CU_ASSERT(g_bserrno == 0); 1920 g_bs = NULL; 1921 1922 dev = init_dev(); 1923 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1924 CU_ASSERT(g_bserrno == 0); 1925 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1926 1927 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1928 1929 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1930 CU_ASSERT(g_bserrno == 0); 1931 g_bs = NULL; 1932 } 1933 1934 /* 1935 * Test resizing of the metadata blob. This requires creating enough blobs 1936 * so that one cluster is not enough to fit the metadata for those blobs. 1937 * To induce this condition to happen more quickly, we reduce the cluster 1938 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1939 */ 1940 static void 1941 bs_resize_md(void) 1942 { 1943 const int CLUSTER_PAGE_COUNT = 4; 1944 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1945 struct spdk_bs_dev *dev; 1946 struct spdk_bs_opts opts; 1947 uint32_t cluster_sz; 1948 spdk_blob_id blobids[NUM_BLOBS]; 1949 int i; 1950 1951 1952 dev = init_dev(); 1953 spdk_bs_opts_init(&opts); 1954 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1955 cluster_sz = opts.cluster_sz; 1956 1957 /* Initialize a new blob store */ 1958 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1959 CU_ASSERT(g_bserrno == 0); 1960 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1961 1962 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1963 1964 for (i = 0; i < NUM_BLOBS; i++) { 1965 g_bserrno = -1; 1966 g_blobid = SPDK_BLOBID_INVALID; 1967 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1968 CU_ASSERT(g_bserrno == 0); 1969 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1970 blobids[i] = g_blobid; 1971 } 1972 1973 /* Unload the blob store */ 1974 g_bserrno = -1; 1975 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1976 CU_ASSERT(g_bserrno == 0); 1977 1978 /* Load an existing blob store */ 1979 g_bserrno = -1; 1980 g_bs = NULL; 1981 dev = init_dev(); 1982 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1983 CU_ASSERT(g_bserrno == 0); 1984 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1985 1986 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1987 1988 for (i = 0; i < NUM_BLOBS; i++) { 1989 g_bserrno = -1; 1990 g_blob = NULL; 1991 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1992 CU_ASSERT(g_bserrno == 0); 1993 CU_ASSERT(g_blob != NULL); 1994 g_bserrno = -1; 1995 spdk_blob_close(g_blob, blob_op_complete, NULL); 1996 CU_ASSERT(g_bserrno == 0); 1997 } 1998 1999 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2000 CU_ASSERT(g_bserrno == 0); 2001 g_bs = NULL; 2002 } 2003 2004 static void 2005 bs_destroy(void) 2006 { 2007 struct spdk_bs_dev *dev; 2008 struct spdk_bs_opts opts; 2009 2010 /* Initialize a new blob store */ 2011 dev = init_dev(); 2012 spdk_bs_opts_init(&opts); 2013 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2014 CU_ASSERT(g_bserrno == 0); 2015 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2016 2017 /* Destroy the blob store */ 2018 g_bserrno = -1; 2019 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2020 CU_ASSERT(g_bserrno == 0); 2021 2022 /* Loading an non-existent blob store should fail. */ 2023 g_bs = NULL; 2024 dev = init_dev(); 2025 2026 g_bserrno = 0; 2027 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2028 CU_ASSERT(g_bserrno != 0); 2029 } 2030 2031 /* Try to hit all of the corner cases associated with serializing 2032 * a blob to disk 2033 */ 2034 static void 2035 blob_serialize(void) 2036 { 2037 struct spdk_bs_dev *dev; 2038 struct spdk_bs_opts opts; 2039 struct spdk_blob_store *bs; 2040 spdk_blob_id blobid[2]; 2041 struct spdk_blob *blob[2]; 2042 uint64_t i; 2043 char *value; 2044 int rc; 2045 2046 dev = init_dev(); 2047 2048 /* Initialize a new blobstore with very small clusters */ 2049 spdk_bs_opts_init(&opts); 2050 opts.cluster_sz = dev->blocklen * 8; 2051 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2052 CU_ASSERT(g_bserrno == 0); 2053 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2054 bs = g_bs; 2055 2056 /* Create and open two blobs */ 2057 for (i = 0; i < 2; i++) { 2058 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2059 CU_ASSERT(g_bserrno == 0); 2060 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2061 blobid[i] = g_blobid; 2062 2063 /* Open a blob */ 2064 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2065 CU_ASSERT(g_bserrno == 0); 2066 CU_ASSERT(g_blob != NULL); 2067 blob[i] = g_blob; 2068 2069 /* Set a fairly large xattr on both blobs to eat up 2070 * metadata space 2071 */ 2072 value = calloc(dev->blocklen - 64, sizeof(char)); 2073 SPDK_CU_ASSERT_FATAL(value != NULL); 2074 memset(value, i, dev->blocklen / 2); 2075 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2076 CU_ASSERT(rc == 0); 2077 free(value); 2078 } 2079 2080 /* Resize the blobs, alternating 1 cluster at a time. 2081 * This thwarts run length encoding and will cause spill 2082 * over of the extents. 2083 */ 2084 for (i = 0; i < 6; i++) { 2085 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 2086 CU_ASSERT(rc == 0); 2087 } 2088 2089 for (i = 0; i < 2; i++) { 2090 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2091 CU_ASSERT(g_bserrno == 0); 2092 } 2093 2094 /* Close the blobs */ 2095 for (i = 0; i < 2; i++) { 2096 spdk_blob_close(blob[i], blob_op_complete, NULL); 2097 CU_ASSERT(g_bserrno == 0); 2098 } 2099 2100 /* Unload the blobstore */ 2101 spdk_bs_unload(bs, bs_op_complete, NULL); 2102 CU_ASSERT(g_bserrno == 0); 2103 g_bs = NULL; 2104 g_blob = NULL; 2105 g_blobid = 0; 2106 bs = NULL; 2107 2108 dev = init_dev(); 2109 /* Load an existing blob store */ 2110 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2111 CU_ASSERT(g_bserrno == 0); 2112 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2113 bs = g_bs; 2114 2115 for (i = 0; i < 2; i++) { 2116 blob[i] = NULL; 2117 2118 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2119 CU_ASSERT(g_bserrno == 0); 2120 CU_ASSERT(g_blob != NULL); 2121 blob[i] = g_blob; 2122 2123 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 2124 2125 spdk_blob_close(blob[i], blob_op_complete, NULL); 2126 CU_ASSERT(g_bserrno == 0); 2127 } 2128 2129 spdk_bs_unload(bs, bs_op_complete, NULL); 2130 CU_ASSERT(g_bserrno == 0); 2131 g_bs = NULL; 2132 } 2133 2134 static void 2135 blob_crc(void) 2136 { 2137 struct spdk_blob_store *bs; 2138 struct spdk_bs_dev *dev; 2139 struct spdk_blob *blob; 2140 spdk_blob_id blobid; 2141 uint32_t page_num; 2142 int index; 2143 struct spdk_blob_md_page *page; 2144 2145 dev = init_dev(); 2146 2147 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2148 CU_ASSERT(g_bserrno == 0); 2149 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2150 bs = g_bs; 2151 2152 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2153 CU_ASSERT(g_bserrno == 0); 2154 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2155 blobid = g_blobid; 2156 2157 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2158 CU_ASSERT(g_bserrno == 0); 2159 CU_ASSERT(g_blob != NULL); 2160 blob = g_blob; 2161 2162 spdk_blob_close(blob, blob_op_complete, NULL); 2163 CU_ASSERT(g_bserrno == 0); 2164 2165 page_num = _spdk_bs_blobid_to_page(blobid); 2166 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2167 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2168 page->crc = 0; 2169 2170 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2171 CU_ASSERT(g_bserrno == -EINVAL); 2172 CU_ASSERT(g_blob == NULL); 2173 g_bserrno = 0; 2174 2175 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2176 CU_ASSERT(g_bserrno == -EINVAL); 2177 2178 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2179 CU_ASSERT(g_bserrno == 0); 2180 g_bs = NULL; 2181 } 2182 2183 static void 2184 super_block_crc(void) 2185 { 2186 struct spdk_bs_dev *dev; 2187 struct spdk_bs_super_block *super_block; 2188 struct spdk_bs_opts opts; 2189 2190 dev = init_dev(); 2191 spdk_bs_opts_init(&opts); 2192 2193 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2194 CU_ASSERT(g_bserrno == 0); 2195 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2196 2197 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2198 CU_ASSERT(g_bserrno == 0); 2199 g_bs = NULL; 2200 2201 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2202 super_block->crc = 0; 2203 dev = init_dev(); 2204 2205 /* Load an existing blob store */ 2206 g_bserrno = 0; 2207 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2208 CU_ASSERT(g_bserrno == -EILSEQ); 2209 } 2210 2211 /* For blob dirty shutdown test case we do the following sub-test cases: 2212 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 2213 * dirty shutdown and reload the blob store and verify the xattrs. 2214 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2215 * reload the blob store and verify the clusters number. 2216 * 3 Create the second blob and then dirty shutdown, reload the blob store 2217 * and verify the second blob. 2218 * 4 Delete the second blob and then dirty shutdown, reload the blob store 2219 * and verify the second blob is invalid. 2220 * 5 Create the second blob again and also create the third blob, modify the 2221 * md of second blob which makes the md invalid, and then dirty shutdown, 2222 * reload the blob store verify the second blob, it should invalid and also 2223 * verify the third blob, it should correct. 2224 */ 2225 static void 2226 blob_dirty_shutdown(void) 2227 { 2228 int rc; 2229 int index; 2230 struct spdk_bs_dev *dev; 2231 spdk_blob_id blobid1, blobid2, blobid3; 2232 struct spdk_blob *blob; 2233 uint64_t length; 2234 uint64_t free_clusters; 2235 const void *value; 2236 size_t value_len; 2237 uint32_t page_num; 2238 struct spdk_blob_md_page *page; 2239 struct spdk_bs_opts opts; 2240 2241 dev = init_dev(); 2242 spdk_bs_opts_init(&opts); 2243 /* Initialize a new blob store */ 2244 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2245 CU_ASSERT(g_bserrno == 0); 2246 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2247 2248 /* Create first blob */ 2249 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2250 CU_ASSERT(g_bserrno == 0); 2251 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2252 blobid1 = g_blobid; 2253 2254 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2255 CU_ASSERT(g_bserrno == 0); 2256 CU_ASSERT(g_blob != NULL); 2257 blob = g_blob; 2258 2259 /* Set some xattrs */ 2260 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2261 CU_ASSERT(rc == 0); 2262 2263 length = 2345; 2264 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2265 CU_ASSERT(rc == 0); 2266 2267 /* Resize the blob */ 2268 rc = spdk_blob_resize(blob, 10); 2269 CU_ASSERT(rc == 0); 2270 2271 /* Set the blob as the super blob */ 2272 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 2273 CU_ASSERT(g_bserrno == 0); 2274 2275 free_clusters = spdk_bs_free_cluster_count(g_bs); 2276 2277 spdk_blob_close(blob, blob_op_complete, NULL); 2278 blob = NULL; 2279 g_blob = NULL; 2280 g_blobid = SPDK_BLOBID_INVALID; 2281 2282 /* Dirty shutdown */ 2283 _spdk_bs_free(g_bs); 2284 2285 /* reload blobstore */ 2286 dev = init_dev(); 2287 spdk_bs_opts_init(&opts); 2288 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2289 CU_ASSERT(g_bserrno == 0); 2290 2291 /* Get the super blob */ 2292 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 2293 CU_ASSERT(g_bserrno == 0); 2294 CU_ASSERT(blobid1 == g_blobid); 2295 2296 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2297 CU_ASSERT(g_bserrno == 0); 2298 CU_ASSERT(g_blob != NULL); 2299 blob = g_blob; 2300 2301 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2302 2303 /* Get the xattrs */ 2304 value = NULL; 2305 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2306 CU_ASSERT(rc == 0); 2307 SPDK_CU_ASSERT_FATAL(value != NULL); 2308 CU_ASSERT(*(uint64_t *)value == length); 2309 CU_ASSERT(value_len == 8); 2310 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2311 2312 /* Resize the blob */ 2313 rc = spdk_blob_resize(blob, 20); 2314 CU_ASSERT(rc == 0); 2315 2316 free_clusters = spdk_bs_free_cluster_count(g_bs); 2317 2318 spdk_blob_close(blob, blob_op_complete, NULL); 2319 CU_ASSERT(g_bserrno == 0); 2320 blob = NULL; 2321 g_blob = NULL; 2322 g_blobid = SPDK_BLOBID_INVALID; 2323 2324 /* Dirty shutdown */ 2325 _spdk_bs_free(g_bs); 2326 2327 /* reload the blobstore */ 2328 dev = init_dev(); 2329 spdk_bs_opts_init(&opts); 2330 /* Load an existing blob store */ 2331 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2332 CU_ASSERT(g_bserrno == 0); 2333 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2334 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2335 CU_ASSERT(g_bserrno == 0); 2336 CU_ASSERT(g_blob != NULL); 2337 blob = g_blob; 2338 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2339 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2340 2341 spdk_blob_close(blob, blob_op_complete, NULL); 2342 CU_ASSERT(g_bserrno == 0); 2343 blob = NULL; 2344 g_blob = NULL; 2345 g_blobid = SPDK_BLOBID_INVALID; 2346 2347 /* Create second blob */ 2348 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2349 CU_ASSERT(g_bserrno == 0); 2350 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2351 blobid2 = g_blobid; 2352 2353 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2354 CU_ASSERT(g_bserrno == 0); 2355 CU_ASSERT(g_blob != NULL); 2356 blob = g_blob; 2357 2358 /* Set some xattrs */ 2359 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2360 CU_ASSERT(rc == 0); 2361 2362 length = 5432; 2363 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2364 CU_ASSERT(rc == 0); 2365 2366 /* Resize the blob */ 2367 rc = spdk_blob_resize(blob, 10); 2368 CU_ASSERT(rc == 0); 2369 2370 free_clusters = spdk_bs_free_cluster_count(g_bs); 2371 2372 spdk_blob_close(blob, blob_op_complete, NULL); 2373 blob = NULL; 2374 g_blob = NULL; 2375 g_blobid = SPDK_BLOBID_INVALID; 2376 2377 /* Dirty shutdown */ 2378 _spdk_bs_free(g_bs); 2379 2380 /* reload the blobstore */ 2381 dev = init_dev(); 2382 spdk_bs_opts_init(&opts); 2383 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2384 CU_ASSERT(g_bserrno == 0); 2385 2386 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2387 CU_ASSERT(g_bserrno == 0); 2388 CU_ASSERT(g_blob != NULL); 2389 blob = g_blob; 2390 2391 /* Get the xattrs */ 2392 value = NULL; 2393 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2394 CU_ASSERT(rc == 0); 2395 SPDK_CU_ASSERT_FATAL(value != NULL); 2396 CU_ASSERT(*(uint64_t *)value == length); 2397 CU_ASSERT(value_len == 8); 2398 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2399 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2400 2401 spdk_blob_close(blob, blob_op_complete, NULL); 2402 CU_ASSERT(g_bserrno == 0); 2403 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2404 CU_ASSERT(g_bserrno == 0); 2405 2406 free_clusters = spdk_bs_free_cluster_count(g_bs); 2407 2408 /* Dirty shutdown */ 2409 _spdk_bs_free(g_bs); 2410 /* reload the blobstore */ 2411 dev = init_dev(); 2412 spdk_bs_opts_init(&opts); 2413 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2414 CU_ASSERT(g_bserrno == 0); 2415 2416 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2417 CU_ASSERT(g_bserrno != 0); 2418 CU_ASSERT(g_blob == NULL); 2419 2420 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2421 CU_ASSERT(g_bserrno == 0); 2422 CU_ASSERT(g_blob != NULL); 2423 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2424 spdk_blob_close(g_blob, blob_op_complete, NULL); 2425 CU_ASSERT(g_bserrno == 0); 2426 2427 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2428 CU_ASSERT(g_bserrno == 0); 2429 g_bs = NULL; 2430 2431 /* reload the blobstore */ 2432 dev = init_dev(); 2433 spdk_bs_opts_init(&opts); 2434 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2435 CU_ASSERT(g_bserrno == 0); 2436 2437 /* Create second blob */ 2438 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2439 CU_ASSERT(g_bserrno == 0); 2440 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2441 blobid2 = g_blobid; 2442 2443 /* Create third blob */ 2444 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2445 CU_ASSERT(g_bserrno == 0); 2446 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2447 blobid3 = g_blobid; 2448 2449 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2450 CU_ASSERT(g_bserrno == 0); 2451 CU_ASSERT(g_blob != NULL); 2452 blob = g_blob; 2453 2454 /* Set some xattrs for second blob */ 2455 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2456 CU_ASSERT(rc == 0); 2457 2458 length = 5432; 2459 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2460 CU_ASSERT(rc == 0); 2461 2462 spdk_blob_close(blob, blob_op_complete, NULL); 2463 blob = NULL; 2464 g_blob = NULL; 2465 g_blobid = SPDK_BLOBID_INVALID; 2466 2467 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2468 CU_ASSERT(g_bserrno == 0); 2469 CU_ASSERT(g_blob != NULL); 2470 blob = g_blob; 2471 2472 /* Set some xattrs for third blob */ 2473 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2474 CU_ASSERT(rc == 0); 2475 2476 length = 5432; 2477 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2478 CU_ASSERT(rc == 0); 2479 2480 spdk_blob_close(blob, blob_op_complete, NULL); 2481 blob = NULL; 2482 g_blob = NULL; 2483 g_blobid = SPDK_BLOBID_INVALID; 2484 2485 /* Mark second blob as invalid */ 2486 page_num = _spdk_bs_blobid_to_page(blobid2); 2487 2488 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2489 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2490 page->sequence_num = 1; 2491 page->crc = _spdk_blob_md_page_calc_crc(page); 2492 2493 free_clusters = spdk_bs_free_cluster_count(g_bs); 2494 2495 /* Dirty shutdown */ 2496 _spdk_bs_free(g_bs); 2497 /* reload the blobstore */ 2498 dev = init_dev(); 2499 spdk_bs_opts_init(&opts); 2500 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2501 CU_ASSERT(g_bserrno == 0); 2502 2503 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2504 CU_ASSERT(g_bserrno != 0); 2505 CU_ASSERT(g_blob == NULL); 2506 2507 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2508 CU_ASSERT(g_bserrno == 0); 2509 CU_ASSERT(g_blob != NULL); 2510 blob = g_blob; 2511 2512 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2513 2514 spdk_blob_close(blob, blob_op_complete, NULL); 2515 blob = NULL; 2516 g_blob = NULL; 2517 g_blobid = SPDK_BLOBID_INVALID; 2518 2519 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2520 CU_ASSERT(g_bserrno == 0); 2521 g_bs = NULL; 2522 } 2523 2524 static void 2525 blob_flags(void) 2526 { 2527 struct spdk_bs_dev *dev; 2528 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2529 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2530 struct spdk_bs_opts opts; 2531 int rc; 2532 2533 dev = init_dev(); 2534 spdk_bs_opts_init(&opts); 2535 2536 /* Initialize a new blob store */ 2537 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2538 CU_ASSERT(g_bserrno == 0); 2539 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2540 2541 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2542 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2543 CU_ASSERT(g_bserrno == 0); 2544 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2545 blobid_invalid = g_blobid; 2546 2547 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2548 CU_ASSERT(g_bserrno == 0); 2549 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2550 blobid_data_ro = g_blobid; 2551 2552 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2553 CU_ASSERT(g_bserrno == 0); 2554 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2555 blobid_md_ro = g_blobid; 2556 2557 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2558 CU_ASSERT(g_bserrno == 0); 2559 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2560 blob_invalid = g_blob; 2561 2562 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2563 CU_ASSERT(g_bserrno == 0); 2564 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2565 blob_data_ro = g_blob; 2566 2567 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2568 CU_ASSERT(g_bserrno == 0); 2569 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2570 blob_md_ro = g_blob; 2571 2572 /* Change the size of blob_data_ro to check if flags are serialized 2573 * when blob has non zero number of extents */ 2574 rc = spdk_blob_resize(blob_data_ro, 10); 2575 CU_ASSERT(rc == 0); 2576 2577 /* Set the xattr to check if flags are serialized 2578 * when blob has non zero number of xattrs */ 2579 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2580 CU_ASSERT(rc == 0); 2581 2582 blob_invalid->invalid_flags = (1ULL << 63); 2583 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2584 blob_data_ro->data_ro_flags = (1ULL << 62); 2585 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2586 blob_md_ro->md_ro_flags = (1ULL << 61); 2587 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2588 2589 g_bserrno = -1; 2590 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2591 CU_ASSERT(g_bserrno == 0); 2592 g_bserrno = -1; 2593 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2594 CU_ASSERT(g_bserrno == 0); 2595 g_bserrno = -1; 2596 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2597 CU_ASSERT(g_bserrno == 0); 2598 2599 g_bserrno = -1; 2600 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2601 CU_ASSERT(g_bserrno == 0); 2602 blob_invalid = NULL; 2603 g_bserrno = -1; 2604 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2605 CU_ASSERT(g_bserrno == 0); 2606 blob_data_ro = NULL; 2607 g_bserrno = -1; 2608 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2609 CU_ASSERT(g_bserrno == 0); 2610 blob_md_ro = NULL; 2611 2612 g_blob = NULL; 2613 g_blobid = SPDK_BLOBID_INVALID; 2614 2615 /* Unload the blob store */ 2616 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2617 CU_ASSERT(g_bserrno == 0); 2618 g_bs = NULL; 2619 2620 /* Load an existing blob store */ 2621 dev = init_dev(); 2622 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2623 CU_ASSERT(g_bserrno == 0); 2624 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2625 2626 g_blob = NULL; 2627 g_bserrno = 0; 2628 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2629 CU_ASSERT(g_bserrno != 0); 2630 CU_ASSERT(g_blob == NULL); 2631 2632 g_blob = NULL; 2633 g_bserrno = -1; 2634 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2635 CU_ASSERT(g_bserrno == 0); 2636 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2637 blob_data_ro = g_blob; 2638 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2639 CU_ASSERT(blob_data_ro->data_ro == true); 2640 CU_ASSERT(blob_data_ro->md_ro == true); 2641 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2642 2643 g_blob = NULL; 2644 g_bserrno = -1; 2645 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2646 CU_ASSERT(g_bserrno == 0); 2647 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2648 blob_md_ro = g_blob; 2649 CU_ASSERT(blob_md_ro->data_ro == false); 2650 CU_ASSERT(blob_md_ro->md_ro == true); 2651 2652 g_bserrno = -1; 2653 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2654 CU_ASSERT(g_bserrno == 0); 2655 2656 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2657 CU_ASSERT(g_bserrno == 0); 2658 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2659 CU_ASSERT(g_bserrno == 0); 2660 2661 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2662 CU_ASSERT(g_bserrno == 0); 2663 } 2664 2665 static void 2666 bs_version(void) 2667 { 2668 struct spdk_bs_super_block *super; 2669 struct spdk_bs_dev *dev; 2670 struct spdk_bs_opts opts; 2671 spdk_blob_id blobid; 2672 2673 dev = init_dev(); 2674 spdk_bs_opts_init(&opts); 2675 2676 /* Initialize a new blob store */ 2677 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2678 CU_ASSERT(g_bserrno == 0); 2679 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2680 2681 /* Unload the blob store */ 2682 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2683 CU_ASSERT(g_bserrno == 0); 2684 g_bs = NULL; 2685 2686 /* 2687 * Change the bs version on disk. This will allow us to 2688 * test that the version does not get modified automatically 2689 * when loading and unloading the blobstore. 2690 */ 2691 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2692 CU_ASSERT(super->version == SPDK_BS_VERSION); 2693 CU_ASSERT(super->clean == 1); 2694 super->version = 2; 2695 /* 2696 * Version 2 metadata does not have a used blobid mask, so clear 2697 * those fields in the super block and zero the corresponding 2698 * region on "disk". We will use this to ensure blob IDs are 2699 * correctly reconstructed. 2700 */ 2701 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2702 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2703 super->used_blobid_mask_start = 0; 2704 super->used_blobid_mask_len = 0; 2705 super->crc = _spdk_blob_md_page_calc_crc(super); 2706 2707 /* Load an existing blob store */ 2708 dev = init_dev(); 2709 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2710 CU_ASSERT(g_bserrno == 0); 2711 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2712 CU_ASSERT(super->clean == 0); 2713 2714 /* 2715 * Create a blob - just to make sure that when we unload it 2716 * results in writing the super block (since metadata pages 2717 * were allocated. 2718 */ 2719 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2720 CU_ASSERT(g_bserrno == 0); 2721 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2722 blobid = g_blobid; 2723 2724 /* Unload the blob store */ 2725 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2726 CU_ASSERT(g_bserrno == 0); 2727 g_bs = NULL; 2728 CU_ASSERT(super->version == 2); 2729 CU_ASSERT(super->used_blobid_mask_start == 0); 2730 CU_ASSERT(super->used_blobid_mask_len == 0); 2731 2732 dev = init_dev(); 2733 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2734 CU_ASSERT(g_bserrno == 0); 2735 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2736 2737 g_blob = NULL; 2738 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2739 CU_ASSERT(g_bserrno == 0); 2740 CU_ASSERT(g_blob != NULL); 2741 2742 spdk_blob_close(g_blob, blob_op_complete, NULL); 2743 CU_ASSERT(g_bserrno == 0); 2744 2745 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2746 CU_ASSERT(g_bserrno == 0); 2747 g_bs = NULL; 2748 CU_ASSERT(super->version == 2); 2749 CU_ASSERT(super->used_blobid_mask_start == 0); 2750 CU_ASSERT(super->used_blobid_mask_len == 0); 2751 } 2752 2753 static void 2754 blob_set_xattrs(void) 2755 { 2756 struct spdk_blob_store *bs; 2757 struct spdk_bs_dev *dev; 2758 struct spdk_blob *blob; 2759 struct spdk_blob_opts opts; 2760 spdk_blob_id blobid; 2761 const void *value; 2762 size_t value_len; 2763 int rc; 2764 2765 dev = init_dev(); 2766 2767 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2768 CU_ASSERT(g_bserrno == 0); 2769 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2770 bs = g_bs; 2771 2772 /* Create blob with extra attributes */ 2773 spdk_blob_opts_init(&opts); 2774 2775 opts.xattrs.names = g_xattr_names; 2776 opts.xattrs.get_value = _get_xattr_value; 2777 opts.xattrs.count = 3; 2778 opts.xattrs.ctx = &g_ctx; 2779 2780 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2781 CU_ASSERT(g_bserrno == 0); 2782 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2783 blobid = g_blobid; 2784 2785 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2786 CU_ASSERT(g_bserrno == 0); 2787 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2788 blob = g_blob; 2789 2790 /* Get the xattrs */ 2791 value = NULL; 2792 2793 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 2794 CU_ASSERT(rc == 0); 2795 SPDK_CU_ASSERT_FATAL(value != NULL); 2796 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 2797 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 2798 2799 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 2800 CU_ASSERT(rc == 0); 2801 SPDK_CU_ASSERT_FATAL(value != NULL); 2802 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 2803 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 2804 2805 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 2806 CU_ASSERT(rc == 0); 2807 SPDK_CU_ASSERT_FATAL(value != NULL); 2808 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 2809 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 2810 2811 /* Try to get non existing attribute */ 2812 2813 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2814 CU_ASSERT(rc == -ENOENT); 2815 2816 spdk_blob_close(blob, blob_op_complete, NULL); 2817 CU_ASSERT(g_bserrno == 0); 2818 blob = NULL; 2819 g_blob = NULL; 2820 g_blobid = SPDK_BLOBID_INVALID; 2821 2822 /* NULL callback */ 2823 spdk_blob_opts_init(&opts); 2824 opts.xattrs.names = g_xattr_names; 2825 opts.xattrs.get_value = NULL; 2826 opts.xattrs.count = 1; 2827 opts.xattrs.ctx = &g_ctx; 2828 2829 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2830 CU_ASSERT(g_bserrno == -EINVAL); 2831 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2832 2833 /* NULL values */ 2834 spdk_blob_opts_init(&opts); 2835 opts.xattrs.names = g_xattr_names; 2836 opts.xattrs.get_value = _get_xattr_value_null; 2837 opts.xattrs.count = 1; 2838 opts.xattrs.ctx = NULL; 2839 2840 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2841 CU_ASSERT(g_bserrno == -EINVAL); 2842 2843 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2844 CU_ASSERT(g_bserrno == 0); 2845 g_bs = NULL; 2846 2847 } 2848 2849 static void 2850 blob_thin_prov_alloc(void) 2851 { 2852 struct spdk_blob_store *bs; 2853 struct spdk_bs_dev *dev; 2854 struct spdk_blob *blob; 2855 struct spdk_blob_opts opts; 2856 spdk_blob_id blobid; 2857 uint64_t free_clusters; 2858 int rc; 2859 2860 dev = init_dev(); 2861 2862 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2863 CU_ASSERT(g_bserrno == 0); 2864 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2865 bs = g_bs; 2866 free_clusters = spdk_bs_free_cluster_count(bs); 2867 2868 /* Set blob as thin provisioned */ 2869 spdk_blob_opts_init(&opts); 2870 opts.thin_provision = true; 2871 2872 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2873 CU_ASSERT(g_bserrno == 0); 2874 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2875 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2876 blobid = g_blobid; 2877 2878 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2879 CU_ASSERT(g_bserrno == 0); 2880 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2881 blob = g_blob; 2882 2883 CU_ASSERT(blob->active.num_clusters == 0); 2884 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 2885 2886 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2887 rc = spdk_blob_resize(blob, 5); 2888 CU_ASSERT(rc == 0); 2889 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2890 CU_ASSERT(blob->active.num_clusters == 5); 2891 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2892 2893 /* Shrink the blob to 3 clusters - still unallocated */ 2894 rc = spdk_blob_resize(blob, 3); 2895 CU_ASSERT(rc == 0); 2896 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2897 CU_ASSERT(blob->active.num_clusters == 3); 2898 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2899 2900 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2901 CU_ASSERT(g_bserrno == 0); 2902 /* Sync must not change anything */ 2903 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2904 CU_ASSERT(blob->active.num_clusters == 3); 2905 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2906 2907 spdk_blob_close(blob, blob_op_complete, NULL); 2908 CU_ASSERT(g_bserrno == 0); 2909 2910 /* Unload the blob store */ 2911 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2912 CU_ASSERT(g_bserrno == 0); 2913 g_bs = NULL; 2914 g_blob = NULL; 2915 g_blobid = 0; 2916 2917 /* Load an existing blob store */ 2918 dev = init_dev(); 2919 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2920 CU_ASSERT(g_bserrno == 0); 2921 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2922 2923 bs = g_bs; 2924 2925 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2926 CU_ASSERT(g_bserrno == 0); 2927 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2928 blob = g_blob; 2929 2930 /* Check that clusters allocation and size is still the same */ 2931 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2932 CU_ASSERT(blob->active.num_clusters == 3); 2933 2934 spdk_blob_close(blob, blob_op_complete, NULL); 2935 CU_ASSERT(g_bserrno == 0); 2936 2937 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2938 CU_ASSERT(g_bserrno == 0); 2939 2940 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2941 CU_ASSERT(g_bserrno == 0); 2942 g_bs = NULL; 2943 } 2944 2945 static void 2946 blob_insert_cluster_msg(void) 2947 { 2948 struct spdk_blob_store *bs; 2949 struct spdk_bs_dev *dev; 2950 struct spdk_blob *blob; 2951 struct spdk_blob_opts opts; 2952 spdk_blob_id blobid; 2953 uint64_t free_clusters; 2954 2955 dev = init_dev(); 2956 2957 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2958 CU_ASSERT(g_bserrno == 0); 2959 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2960 bs = g_bs; 2961 free_clusters = spdk_bs_free_cluster_count(bs); 2962 2963 /* Set blob as thin provisioned */ 2964 spdk_blob_opts_init(&opts); 2965 opts.thin_provision = true; 2966 opts.num_clusters = 4; 2967 2968 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2969 CU_ASSERT(g_bserrno == 0); 2970 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2971 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2972 blobid = g_blobid; 2973 2974 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2975 CU_ASSERT(g_bserrno == 0); 2976 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2977 blob = g_blob; 2978 2979 CU_ASSERT(blob->active.num_clusters == 4); 2980 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 2981 CU_ASSERT(blob->active.clusters[1] == 0); 2982 2983 _spdk_bs_claim_cluster(bs, 0xF); 2984 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 2985 2986 CU_ASSERT(blob->active.clusters[1] != 0); 2987 2988 spdk_blob_close(blob, blob_op_complete, NULL); 2989 CU_ASSERT(g_bserrno == 0); 2990 2991 /* Unload the blob store */ 2992 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2993 CU_ASSERT(g_bserrno == 0); 2994 g_bs = NULL; 2995 g_blob = NULL; 2996 g_blobid = 0; 2997 2998 /* Load an existing blob store */ 2999 dev = init_dev(); 3000 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3001 CU_ASSERT(g_bserrno == 0); 3002 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3003 3004 bs = g_bs; 3005 3006 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3007 CU_ASSERT(g_bserrno == 0); 3008 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3009 blob = g_blob; 3010 3011 CU_ASSERT(blob->active.clusters[1] != 0); 3012 3013 spdk_blob_close(blob, blob_op_complete, NULL); 3014 CU_ASSERT(g_bserrno == 0); 3015 3016 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3017 CU_ASSERT(g_bserrno == 0); 3018 3019 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3020 CU_ASSERT(g_bserrno == 0); 3021 g_bs = NULL; 3022 } 3023 3024 static void 3025 blob_thin_prov_rw(void) 3026 { 3027 static const uint8_t zero[10 * 4096] = { 0 }; 3028 struct spdk_blob_store *bs; 3029 struct spdk_bs_dev *dev; 3030 struct spdk_blob *blob; 3031 struct spdk_io_channel *channel; 3032 struct spdk_blob_opts opts; 3033 spdk_blob_id blobid; 3034 uint64_t free_clusters; 3035 uint8_t payload_read[10 * 4096]; 3036 uint8_t payload_write[10 * 4096]; 3037 int rc; 3038 3039 dev = init_dev(); 3040 3041 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3042 CU_ASSERT(g_bserrno == 0); 3043 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3044 bs = g_bs; 3045 free_clusters = spdk_bs_free_cluster_count(bs); 3046 3047 channel = spdk_bs_alloc_io_channel(bs); 3048 CU_ASSERT(channel != NULL); 3049 3050 spdk_blob_opts_init(&opts); 3051 opts.thin_provision = true; 3052 3053 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3054 CU_ASSERT(g_bserrno == 0); 3055 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3056 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3057 blobid = g_blobid; 3058 3059 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3060 CU_ASSERT(g_bserrno == 0); 3061 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3062 blob = g_blob; 3063 3064 CU_ASSERT(blob->active.num_clusters == 0); 3065 3066 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3067 rc = spdk_blob_resize(blob, 5); 3068 CU_ASSERT(rc == 0); 3069 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3070 CU_ASSERT(blob->active.num_clusters == 5); 3071 3072 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3073 CU_ASSERT(g_bserrno == 0); 3074 /* Sync must not change anything */ 3075 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3076 CU_ASSERT(blob->active.num_clusters == 5); 3077 3078 /* Payload should be all zeros from unallocated clusters */ 3079 memset(payload_read, 0xFF, sizeof(payload_read)); 3080 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3081 CU_ASSERT(g_bserrno == 0); 3082 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3083 3084 memset(payload_write, 0xE5, sizeof(payload_write)); 3085 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3086 CU_ASSERT(g_bserrno == 0); 3087 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3088 3089 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3090 CU_ASSERT(g_bserrno == 0); 3091 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3092 3093 spdk_blob_close(blob, blob_op_complete, NULL); 3094 CU_ASSERT(g_bserrno == 0); 3095 3096 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3097 CU_ASSERT(g_bserrno == 0); 3098 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3099 3100 spdk_bs_free_io_channel(channel); 3101 3102 /* Unload the blob store */ 3103 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3104 CU_ASSERT(g_bserrno == 0); 3105 g_bs = NULL; 3106 g_blob = NULL; 3107 g_blobid = 0; 3108 } 3109 3110 static void 3111 blob_thin_prov_rw_iov(void) 3112 { 3113 static const uint8_t zero[10 * 4096] = { 0 }; 3114 struct spdk_blob_store *bs; 3115 struct spdk_bs_dev *dev; 3116 struct spdk_blob *blob; 3117 struct spdk_io_channel *channel; 3118 struct spdk_blob_opts opts; 3119 spdk_blob_id blobid; 3120 uint64_t free_clusters; 3121 uint8_t payload_read[10 * 4096]; 3122 uint8_t payload_write[10 * 4096]; 3123 struct iovec iov_read[3]; 3124 struct iovec iov_write[3]; 3125 3126 int rc; 3127 3128 dev = init_dev(); 3129 3130 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3131 CU_ASSERT(g_bserrno == 0); 3132 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3133 bs = g_bs; 3134 free_clusters = spdk_bs_free_cluster_count(bs); 3135 3136 channel = spdk_bs_alloc_io_channel(bs); 3137 CU_ASSERT(channel != NULL); 3138 3139 spdk_blob_opts_init(&opts); 3140 opts.thin_provision = true; 3141 3142 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3143 CU_ASSERT(g_bserrno == 0); 3144 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3145 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3146 blobid = g_blobid; 3147 3148 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3149 CU_ASSERT(g_bserrno == 0); 3150 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3151 blob = g_blob; 3152 3153 CU_ASSERT(blob->active.num_clusters == 0); 3154 3155 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3156 rc = spdk_blob_resize(blob, 5); 3157 CU_ASSERT(rc == 0); 3158 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3159 CU_ASSERT(blob->active.num_clusters == 5); 3160 3161 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3162 CU_ASSERT(g_bserrno == 0); 3163 /* Sync must not change anything */ 3164 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3165 CU_ASSERT(blob->active.num_clusters == 5); 3166 3167 /* Payload should be all zeros from unallocated clusters */ 3168 memset(payload_read, 0xAA, sizeof(payload_read)); 3169 iov_read[0].iov_base = payload_read; 3170 iov_read[0].iov_len = 3 * 4096; 3171 iov_read[1].iov_base = payload_read + 3 * 4096; 3172 iov_read[1].iov_len = 4 * 4096; 3173 iov_read[2].iov_base = payload_read + 7 * 4096; 3174 iov_read[2].iov_len = 3 * 4096; 3175 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3176 CU_ASSERT(g_bserrno == 0); 3177 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3178 3179 memset(payload_write, 0xE5, sizeof(payload_write)); 3180 iov_write[0].iov_base = payload_write; 3181 iov_write[0].iov_len = 1 * 4096; 3182 iov_write[1].iov_base = payload_write + 1 * 4096; 3183 iov_write[1].iov_len = 5 * 4096; 3184 iov_write[2].iov_base = payload_write + 6 * 4096; 3185 iov_write[2].iov_len = 4 * 4096; 3186 3187 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3188 CU_ASSERT(g_bserrno == 0); 3189 3190 memset(payload_read, 0xAA, sizeof(payload_read)); 3191 iov_read[0].iov_base = payload_read; 3192 iov_read[0].iov_len = 3 * 4096; 3193 iov_read[1].iov_base = payload_read + 3 * 4096; 3194 iov_read[1].iov_len = 4 * 4096; 3195 iov_read[2].iov_base = payload_read + 7 * 4096; 3196 iov_read[2].iov_len = 3 * 4096; 3197 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3198 CU_ASSERT(g_bserrno == 0); 3199 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3200 3201 spdk_blob_close(blob, blob_op_complete, NULL); 3202 CU_ASSERT(g_bserrno == 0); 3203 3204 spdk_bs_free_io_channel(channel); 3205 3206 /* Unload the blob store */ 3207 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3208 CU_ASSERT(g_bserrno == 0); 3209 g_bs = NULL; 3210 g_blob = NULL; 3211 g_blobid = 0; 3212 } 3213 3214 struct iter_ctx { 3215 int current_iter; 3216 spdk_blob_id blobid[4]; 3217 }; 3218 3219 static void 3220 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3221 { 3222 struct iter_ctx *iter_ctx = arg; 3223 spdk_blob_id blobid; 3224 3225 CU_ASSERT(bserrno == 0); 3226 blobid = spdk_blob_get_id(blob); 3227 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3228 } 3229 3230 static void 3231 bs_load_iter(void) 3232 { 3233 struct spdk_bs_dev *dev; 3234 struct iter_ctx iter_ctx = { 0 }; 3235 struct spdk_blob *blob; 3236 int i, rc; 3237 struct spdk_bs_opts opts; 3238 3239 dev = init_dev(); 3240 spdk_bs_opts_init(&opts); 3241 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3242 3243 /* Initialize a new blob store */ 3244 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3245 CU_ASSERT(g_bserrno == 0); 3246 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3247 3248 for (i = 0; i < 4; i++) { 3249 g_bserrno = -1; 3250 g_blobid = SPDK_BLOBID_INVALID; 3251 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3252 CU_ASSERT(g_bserrno == 0); 3253 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3254 iter_ctx.blobid[i] = g_blobid; 3255 3256 g_bserrno = -1; 3257 g_blob = NULL; 3258 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3259 CU_ASSERT(g_bserrno == 0); 3260 CU_ASSERT(g_blob != NULL); 3261 blob = g_blob; 3262 3263 /* Just save the blobid as an xattr for testing purposes. */ 3264 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3265 CU_ASSERT(rc == 0); 3266 3267 /* Resize the blob */ 3268 rc = spdk_blob_resize(blob, i); 3269 CU_ASSERT(rc == 0); 3270 3271 spdk_blob_close(blob, blob_op_complete, NULL); 3272 CU_ASSERT(g_bserrno == 0); 3273 } 3274 3275 g_bserrno = -1; 3276 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3277 CU_ASSERT(g_bserrno == 0); 3278 3279 dev = init_dev(); 3280 spdk_bs_opts_init(&opts); 3281 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3282 opts.iter_cb_fn = test_iter; 3283 opts.iter_cb_arg = &iter_ctx; 3284 3285 /* Test blob iteration during load after a clean shutdown. */ 3286 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3287 CU_ASSERT(g_bserrno == 0); 3288 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3289 3290 /* Dirty shutdown */ 3291 _spdk_bs_free(g_bs); 3292 3293 dev = init_dev(); 3294 spdk_bs_opts_init(&opts); 3295 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3296 opts.iter_cb_fn = test_iter; 3297 iter_ctx.current_iter = 0; 3298 opts.iter_cb_arg = &iter_ctx; 3299 3300 /* Test blob iteration during load after a dirty shutdown. */ 3301 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3302 CU_ASSERT(g_bserrno == 0); 3303 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3304 3305 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3306 CU_ASSERT(g_bserrno == 0); 3307 g_bs = NULL; 3308 3309 } 3310 3311 int main(int argc, char **argv) 3312 { 3313 CU_pSuite suite = NULL; 3314 unsigned int num_failures; 3315 3316 if (CU_initialize_registry() != CUE_SUCCESS) { 3317 return CU_get_error(); 3318 } 3319 3320 suite = CU_add_suite("blob", NULL, NULL); 3321 if (suite == NULL) { 3322 CU_cleanup_registry(); 3323 return CU_get_error(); 3324 } 3325 3326 if ( 3327 CU_add_test(suite, "blob_init", blob_init) == NULL || 3328 CU_add_test(suite, "blob_open", blob_open) == NULL || 3329 CU_add_test(suite, "blob_create", blob_create) == NULL || 3330 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 3331 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 3332 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 3333 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 3334 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 3335 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 3336 CU_add_test(suite, "blob_super", blob_super) == NULL || 3337 CU_add_test(suite, "blob_write", blob_write) == NULL || 3338 CU_add_test(suite, "blob_read", blob_read) == NULL || 3339 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 3340 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 3341 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 3342 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 3343 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 3344 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 3345 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 3346 CU_add_test(suite, "bs_load", bs_load) == NULL || 3347 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 3348 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 3349 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 3350 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 3351 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 3352 CU_add_test(suite, "bs_type", bs_type) == NULL || 3353 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 3354 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 3355 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 3356 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 3357 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 3358 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 3359 CU_add_test(suite, "bs_version", bs_version) == NULL || 3360 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 3361 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 3362 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 3363 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 3364 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 3365 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL 3366 ) { 3367 CU_cleanup_registry(); 3368 return CU_get_error(); 3369 } 3370 3371 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 3372 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 3373 CU_basic_set_mode(CU_BRM_VERBOSE); 3374 CU_basic_run_tests(); 3375 num_failures = CU_get_number_of_failures(); 3376 CU_cleanup_registry(); 3377 spdk_free_thread(); 3378 free(g_dev_buffer); 3379 return num_failures; 3380 } 3381