1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "spdk/blob.h" 38 39 #include "lib/test_env.c" 40 #include "../bs_dev_common.c" 41 #include "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 1545 /* Load an existing blob store */ 1546 dev = init_dev(); 1547 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1548 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1549 CU_ASSERT(g_bserrno == 0); 1550 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1551 1552 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1553 CU_ASSERT(super_block->clean == 0); 1554 1555 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1556 CU_ASSERT(g_bserrno == 0); 1557 CU_ASSERT(g_blob != NULL); 1558 blob = g_blob; 1559 1560 /* Get the xattrs */ 1561 value = NULL; 1562 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1563 CU_ASSERT(rc == 0); 1564 SPDK_CU_ASSERT_FATAL(value != NULL); 1565 CU_ASSERT(*(uint64_t *)value == length); 1566 CU_ASSERT(value_len == 8); 1567 1568 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1569 CU_ASSERT(rc == -ENOENT); 1570 1571 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1572 1573 spdk_blob_close(blob, blob_op_complete, NULL); 1574 CU_ASSERT(g_bserrno == 0); 1575 blob = NULL; 1576 g_blob = NULL; 1577 g_blobid = SPDK_BLOBID_INVALID; 1578 1579 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1580 CU_ASSERT(g_bserrno == 0); 1581 g_bs = NULL; 1582 } 1583 1584 static void 1585 bs_type(void) 1586 { 1587 struct spdk_bs_dev *dev; 1588 struct spdk_bs_opts opts; 1589 1590 dev = init_dev(); 1591 spdk_bs_opts_init(&opts); 1592 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1593 1594 /* Initialize a new blob store */ 1595 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1596 CU_ASSERT(g_bserrno == 0); 1597 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1598 1599 /* Unload the blob store */ 1600 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1601 CU_ASSERT(g_bserrno == 0); 1602 g_bs = NULL; 1603 g_blob = NULL; 1604 g_blobid = 0; 1605 1606 /* Load non existing blobstore type */ 1607 dev = init_dev(); 1608 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1609 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1610 CU_ASSERT(g_bserrno != 0); 1611 1612 /* Load with empty blobstore type */ 1613 dev = init_dev(); 1614 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1615 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1616 CU_ASSERT(g_bserrno == 0); 1617 1618 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1619 CU_ASSERT(g_bserrno == 0); 1620 g_bs = NULL; 1621 1622 /* Initialize a new blob store with empty bstype */ 1623 dev = init_dev(); 1624 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1625 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1626 CU_ASSERT(g_bserrno == 0); 1627 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1628 1629 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1630 CU_ASSERT(g_bserrno == 0); 1631 g_bs = NULL; 1632 1633 /* Load non existing blobstore type */ 1634 dev = init_dev(); 1635 strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH); 1636 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1637 CU_ASSERT(g_bserrno != 0); 1638 1639 /* Load with empty blobstore type */ 1640 dev = init_dev(); 1641 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1642 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1643 CU_ASSERT(g_bserrno == 0); 1644 1645 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1646 CU_ASSERT(g_bserrno == 0); 1647 g_bs = NULL; 1648 } 1649 1650 static void 1651 bs_super_block(void) 1652 { 1653 struct spdk_bs_dev *dev; 1654 struct spdk_bs_super_block *super_block; 1655 struct spdk_bs_opts opts; 1656 struct spdk_bs_super_block_ver1 super_block_v1; 1657 1658 dev = init_dev(); 1659 spdk_bs_opts_init(&opts); 1660 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 1661 1662 /* Initialize a new blob store */ 1663 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1664 CU_ASSERT(g_bserrno == 0); 1665 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1666 1667 /* Unload the blob store */ 1668 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1669 CU_ASSERT(g_bserrno == 0); 1670 g_bs = NULL; 1671 g_blob = NULL; 1672 g_blobid = 0; 1673 1674 /* Load an existing blob store with version newer than supported */ 1675 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1676 super_block->version++; 1677 1678 dev = init_dev(); 1679 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1680 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1681 CU_ASSERT(g_bserrno != 0); 1682 1683 /* Create a new blob store with super block version 1 */ 1684 dev = init_dev(); 1685 super_block_v1.version = 1; 1686 strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 1687 super_block_v1.length = 0x1000; 1688 super_block_v1.clean = 1; 1689 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 1690 super_block_v1.cluster_size = 0x100000; 1691 super_block_v1.used_page_mask_start = 0x01; 1692 super_block_v1.used_page_mask_len = 0x01; 1693 super_block_v1.used_cluster_mask_start = 0x02; 1694 super_block_v1.used_cluster_mask_len = 0x01; 1695 super_block_v1.md_start = 0x03; 1696 super_block_v1.md_len = 0x40; 1697 memset(super_block_v1.reserved, 0, 4036); 1698 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 1699 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 1700 1701 strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH); 1702 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1703 CU_ASSERT(g_bserrno == 0); 1704 1705 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1706 CU_ASSERT(g_bserrno == 0); 1707 g_bs = NULL; 1708 } 1709 1710 /* 1711 * Create a blobstore and then unload it. 1712 */ 1713 static void 1714 bs_unload(void) 1715 { 1716 struct spdk_bs_dev *dev; 1717 struct spdk_blob_store *bs; 1718 spdk_blob_id blobid; 1719 struct spdk_blob *blob; 1720 1721 dev = init_dev(); 1722 1723 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1724 CU_ASSERT(g_bserrno == 0); 1725 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1726 bs = g_bs; 1727 1728 /* Create a blob and open it. */ 1729 g_bserrno = -1; 1730 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1731 CU_ASSERT(g_bserrno == 0); 1732 CU_ASSERT(g_blobid > 0); 1733 blobid = g_blobid; 1734 1735 g_bserrno = -1; 1736 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1737 CU_ASSERT(g_bserrno == 0); 1738 CU_ASSERT(g_blob != NULL); 1739 blob = g_blob; 1740 1741 /* Try to unload blobstore, should fail with open blob */ 1742 g_bserrno = -1; 1743 spdk_bs_unload(bs, bs_op_complete, NULL); 1744 CU_ASSERT(g_bserrno == -EBUSY); 1745 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1746 1747 /* Close the blob, then successfully unload blobstore */ 1748 g_bserrno = -1; 1749 spdk_blob_close(blob, blob_op_complete, NULL); 1750 CU_ASSERT(g_bserrno == 0); 1751 1752 g_bserrno = -1; 1753 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1754 CU_ASSERT(g_bserrno == 0); 1755 g_bs = NULL; 1756 } 1757 1758 /* 1759 * Create a blobstore with a cluster size different than the default, and ensure it is 1760 * persisted. 1761 */ 1762 static void 1763 bs_cluster_sz(void) 1764 { 1765 struct spdk_bs_dev *dev; 1766 struct spdk_bs_opts opts; 1767 uint32_t cluster_sz; 1768 1769 /* Set cluster size to zero */ 1770 dev = init_dev(); 1771 spdk_bs_opts_init(&opts); 1772 opts.cluster_sz = 0; 1773 1774 /* Initialize a new blob store */ 1775 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1776 CU_ASSERT(g_bserrno == -EINVAL); 1777 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1778 1779 /* 1780 * Set cluster size to blobstore page size, 1781 * to work it is required to be at least twice the blobstore page size. 1782 */ 1783 dev = init_dev(); 1784 spdk_bs_opts_init(&opts); 1785 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 1786 1787 /* Initialize a new blob store */ 1788 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1789 CU_ASSERT(g_bserrno == -ENOMEM); 1790 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1791 1792 /* 1793 * Set cluster size to lower than page size, 1794 * to work it is required to be at least twice the blobstore page size. 1795 */ 1796 dev = init_dev(); 1797 spdk_bs_opts_init(&opts); 1798 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 1799 1800 /* Initialize a new blob store */ 1801 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1802 CU_ASSERT(g_bserrno == -ENOMEM); 1803 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 1804 1805 /* Set cluster size to twice the default */ 1806 dev = init_dev(); 1807 spdk_bs_opts_init(&opts); 1808 opts.cluster_sz *= 2; 1809 cluster_sz = opts.cluster_sz; 1810 1811 /* Initialize a new blob store */ 1812 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1813 CU_ASSERT(g_bserrno == 0); 1814 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1815 1816 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1817 1818 /* Unload the blob store */ 1819 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1820 CU_ASSERT(g_bserrno == 0); 1821 g_bs = NULL; 1822 g_blob = NULL; 1823 g_blobid = 0; 1824 1825 dev = init_dev(); 1826 /* Load an existing blob store */ 1827 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1828 CU_ASSERT(g_bserrno == 0); 1829 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1830 1831 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1832 1833 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1834 CU_ASSERT(g_bserrno == 0); 1835 g_bs = NULL; 1836 } 1837 1838 /* 1839 * Create a blobstore, reload it and ensure total usable cluster count 1840 * stays the same. 1841 */ 1842 static void 1843 bs_usable_clusters(void) 1844 { 1845 struct spdk_bs_dev *dev; 1846 struct spdk_bs_opts opts; 1847 uint32_t clusters; 1848 int i, rc; 1849 1850 /* Init blobstore */ 1851 dev = init_dev(); 1852 spdk_bs_opts_init(&opts); 1853 1854 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1855 CU_ASSERT(g_bserrno == 0); 1856 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1857 1858 clusters = spdk_bs_total_data_cluster_count(g_bs); 1859 1860 /* Unload the blob store */ 1861 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1862 CU_ASSERT(g_bserrno == 0); 1863 g_bs = NULL; 1864 1865 dev = init_dev(); 1866 /* Load an existing blob store */ 1867 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1868 CU_ASSERT(g_bserrno == 0); 1869 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1870 1871 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1872 1873 /* Create and resize blobs to make sure that useable cluster count won't change */ 1874 for (i = 0; i < 4; i++) { 1875 g_bserrno = -1; 1876 g_blobid = SPDK_BLOBID_INVALID; 1877 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1878 CU_ASSERT(g_bserrno == 0); 1879 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1880 1881 g_bserrno = -1; 1882 g_blob = NULL; 1883 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 1884 CU_ASSERT(g_bserrno == 0); 1885 CU_ASSERT(g_blob != NULL); 1886 1887 rc = spdk_blob_resize(g_blob, 10); 1888 CU_ASSERT(rc == 0); 1889 1890 g_bserrno = -1; 1891 spdk_blob_close(g_blob, blob_op_complete, NULL); 1892 CU_ASSERT(g_bserrno == 0); 1893 1894 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1895 } 1896 1897 /* Reload the blob store to make sure that nothing changed */ 1898 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1899 CU_ASSERT(g_bserrno == 0); 1900 g_bs = NULL; 1901 1902 dev = init_dev(); 1903 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1904 CU_ASSERT(g_bserrno == 0); 1905 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1906 1907 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 1908 1909 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1910 CU_ASSERT(g_bserrno == 0); 1911 g_bs = NULL; 1912 } 1913 1914 /* 1915 * Test resizing of the metadata blob. This requires creating enough blobs 1916 * so that one cluster is not enough to fit the metadata for those blobs. 1917 * To induce this condition to happen more quickly, we reduce the cluster 1918 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 1919 */ 1920 static void 1921 bs_resize_md(void) 1922 { 1923 const int CLUSTER_PAGE_COUNT = 4; 1924 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 1925 struct spdk_bs_dev *dev; 1926 struct spdk_bs_opts opts; 1927 uint32_t cluster_sz; 1928 spdk_blob_id blobids[NUM_BLOBS]; 1929 int i; 1930 1931 1932 dev = init_dev(); 1933 spdk_bs_opts_init(&opts); 1934 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 1935 cluster_sz = opts.cluster_sz; 1936 1937 /* Initialize a new blob store */ 1938 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1939 CU_ASSERT(g_bserrno == 0); 1940 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1941 1942 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1943 1944 for (i = 0; i < NUM_BLOBS; i++) { 1945 g_bserrno = -1; 1946 g_blobid = SPDK_BLOBID_INVALID; 1947 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1948 CU_ASSERT(g_bserrno == 0); 1949 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1950 blobids[i] = g_blobid; 1951 } 1952 1953 /* Unload the blob store */ 1954 g_bserrno = -1; 1955 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1956 CU_ASSERT(g_bserrno == 0); 1957 1958 /* Load an existing blob store */ 1959 g_bserrno = -1; 1960 g_bs = NULL; 1961 dev = init_dev(); 1962 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1963 CU_ASSERT(g_bserrno == 0); 1964 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1965 1966 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 1967 1968 for (i = 0; i < NUM_BLOBS; i++) { 1969 g_bserrno = -1; 1970 g_blob = NULL; 1971 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 1972 CU_ASSERT(g_bserrno == 0); 1973 CU_ASSERT(g_blob != NULL); 1974 g_bserrno = -1; 1975 spdk_blob_close(g_blob, blob_op_complete, NULL); 1976 CU_ASSERT(g_bserrno == 0); 1977 } 1978 1979 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1980 CU_ASSERT(g_bserrno == 0); 1981 g_bs = NULL; 1982 } 1983 1984 static void 1985 bs_destroy(void) 1986 { 1987 struct spdk_bs_dev *dev; 1988 struct spdk_bs_opts opts; 1989 1990 /* Initialize a new blob store */ 1991 dev = init_dev(); 1992 spdk_bs_opts_init(&opts); 1993 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1994 CU_ASSERT(g_bserrno == 0); 1995 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1996 1997 /* Destroy the blob store */ 1998 g_bserrno = -1; 1999 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2000 CU_ASSERT(g_bserrno == 0); 2001 2002 /* Loading an non-existent blob store should fail. */ 2003 g_bs = NULL; 2004 dev = init_dev(); 2005 2006 g_bserrno = 0; 2007 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2008 CU_ASSERT(g_bserrno != 0); 2009 } 2010 2011 /* Try to hit all of the corner cases associated with serializing 2012 * a blob to disk 2013 */ 2014 static void 2015 blob_serialize(void) 2016 { 2017 struct spdk_bs_dev *dev; 2018 struct spdk_bs_opts opts; 2019 struct spdk_blob_store *bs; 2020 spdk_blob_id blobid[2]; 2021 struct spdk_blob *blob[2]; 2022 uint64_t i; 2023 char *value; 2024 int rc; 2025 2026 dev = init_dev(); 2027 2028 /* Initialize a new blobstore with very small clusters */ 2029 spdk_bs_opts_init(&opts); 2030 opts.cluster_sz = dev->blocklen * 8; 2031 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2032 CU_ASSERT(g_bserrno == 0); 2033 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2034 bs = g_bs; 2035 2036 /* Create and open two blobs */ 2037 for (i = 0; i < 2; i++) { 2038 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2039 CU_ASSERT(g_bserrno == 0); 2040 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2041 blobid[i] = g_blobid; 2042 2043 /* Open a blob */ 2044 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2045 CU_ASSERT(g_bserrno == 0); 2046 CU_ASSERT(g_blob != NULL); 2047 blob[i] = g_blob; 2048 2049 /* Set a fairly large xattr on both blobs to eat up 2050 * metadata space 2051 */ 2052 value = calloc(dev->blocklen - 64, sizeof(char)); 2053 SPDK_CU_ASSERT_FATAL(value != NULL); 2054 memset(value, i, dev->blocklen / 2); 2055 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2056 CU_ASSERT(rc == 0); 2057 free(value); 2058 } 2059 2060 /* Resize the blobs, alternating 1 cluster at a time. 2061 * This thwarts run length encoding and will cause spill 2062 * over of the extents. 2063 */ 2064 for (i = 0; i < 6; i++) { 2065 rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1); 2066 CU_ASSERT(rc == 0); 2067 } 2068 2069 for (i = 0; i < 2; i++) { 2070 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2071 CU_ASSERT(g_bserrno == 0); 2072 } 2073 2074 /* Close the blobs */ 2075 for (i = 0; i < 2; i++) { 2076 spdk_blob_close(blob[i], blob_op_complete, NULL); 2077 CU_ASSERT(g_bserrno == 0); 2078 } 2079 2080 /* Unload the blobstore */ 2081 spdk_bs_unload(bs, bs_op_complete, NULL); 2082 CU_ASSERT(g_bserrno == 0); 2083 g_bs = NULL; 2084 g_blob = NULL; 2085 g_blobid = 0; 2086 bs = NULL; 2087 2088 dev = init_dev(); 2089 /* Load an existing blob store */ 2090 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2091 CU_ASSERT(g_bserrno == 0); 2092 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2093 bs = g_bs; 2094 2095 for (i = 0; i < 2; i++) { 2096 blob[i] = NULL; 2097 2098 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2099 CU_ASSERT(g_bserrno == 0); 2100 CU_ASSERT(g_blob != NULL); 2101 blob[i] = g_blob; 2102 2103 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 2104 2105 spdk_blob_close(blob[i], blob_op_complete, NULL); 2106 CU_ASSERT(g_bserrno == 0); 2107 } 2108 2109 spdk_bs_unload(bs, bs_op_complete, NULL); 2110 CU_ASSERT(g_bserrno == 0); 2111 g_bs = NULL; 2112 } 2113 2114 static void 2115 blob_crc(void) 2116 { 2117 struct spdk_blob_store *bs; 2118 struct spdk_bs_dev *dev; 2119 struct spdk_blob *blob; 2120 spdk_blob_id blobid; 2121 uint32_t page_num; 2122 int index; 2123 struct spdk_blob_md_page *page; 2124 2125 dev = init_dev(); 2126 2127 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2128 CU_ASSERT(g_bserrno == 0); 2129 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2130 bs = g_bs; 2131 2132 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2133 CU_ASSERT(g_bserrno == 0); 2134 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2135 blobid = g_blobid; 2136 2137 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2138 CU_ASSERT(g_bserrno == 0); 2139 CU_ASSERT(g_blob != NULL); 2140 blob = g_blob; 2141 2142 spdk_blob_close(blob, blob_op_complete, NULL); 2143 CU_ASSERT(g_bserrno == 0); 2144 2145 page_num = _spdk_bs_blobid_to_page(blobid); 2146 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2147 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2148 page->crc = 0; 2149 2150 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2151 CU_ASSERT(g_bserrno == -EINVAL); 2152 CU_ASSERT(g_blob == NULL); 2153 g_bserrno = 0; 2154 2155 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2156 CU_ASSERT(g_bserrno == -EINVAL); 2157 2158 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2159 CU_ASSERT(g_bserrno == 0); 2160 g_bs = NULL; 2161 } 2162 2163 static void 2164 super_block_crc(void) 2165 { 2166 struct spdk_bs_dev *dev; 2167 struct spdk_bs_super_block *super_block; 2168 struct spdk_bs_opts opts; 2169 2170 dev = init_dev(); 2171 spdk_bs_opts_init(&opts); 2172 2173 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2174 CU_ASSERT(g_bserrno == 0); 2175 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2176 2177 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2178 CU_ASSERT(g_bserrno == 0); 2179 g_bs = NULL; 2180 2181 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2182 super_block->crc = 0; 2183 dev = init_dev(); 2184 2185 /* Load an existing blob store */ 2186 g_bserrno = 0; 2187 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2188 CU_ASSERT(g_bserrno == -EILSEQ); 2189 } 2190 2191 /* For blob dirty shutdown test case we do the following sub-test cases: 2192 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 2193 * dirty shutdown and reload the blob store and verify the xattrs. 2194 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2195 * reload the blob store and verify the clusters number. 2196 * 3 Create the second blob and then dirty shutdown, reload the blob store 2197 * and verify the second blob. 2198 * 4 Delete the second blob and then dirty shutdown, reload the blob store 2199 * and verify the second blob is invalid. 2200 * 5 Create the second blob again and also create the third blob, modify the 2201 * md of second blob which makes the md invalid, and then dirty shutdown, 2202 * reload the blob store verify the second blob, it should invalid and also 2203 * verify the third blob, it should correct. 2204 */ 2205 static void 2206 blob_dirty_shutdown(void) 2207 { 2208 int rc; 2209 int index; 2210 struct spdk_bs_dev *dev; 2211 spdk_blob_id blobid1, blobid2, blobid3; 2212 struct spdk_blob *blob; 2213 uint64_t length; 2214 uint64_t free_clusters; 2215 const void *value; 2216 size_t value_len; 2217 uint32_t page_num; 2218 struct spdk_blob_md_page *page; 2219 struct spdk_bs_opts opts; 2220 2221 dev = init_dev(); 2222 spdk_bs_opts_init(&opts); 2223 /* Initialize a new blob store */ 2224 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2225 CU_ASSERT(g_bserrno == 0); 2226 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2227 2228 /* Create first blob */ 2229 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2230 CU_ASSERT(g_bserrno == 0); 2231 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2232 blobid1 = g_blobid; 2233 2234 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2235 CU_ASSERT(g_bserrno == 0); 2236 CU_ASSERT(g_blob != NULL); 2237 blob = g_blob; 2238 2239 /* Set some xattrs */ 2240 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2241 CU_ASSERT(rc == 0); 2242 2243 length = 2345; 2244 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2245 CU_ASSERT(rc == 0); 2246 2247 /* Resize the blob */ 2248 rc = spdk_blob_resize(blob, 10); 2249 CU_ASSERT(rc == 0); 2250 2251 /* Set the blob as the super blob */ 2252 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 2253 CU_ASSERT(g_bserrno == 0); 2254 2255 free_clusters = spdk_bs_free_cluster_count(g_bs); 2256 2257 spdk_blob_close(blob, blob_op_complete, NULL); 2258 blob = NULL; 2259 g_blob = NULL; 2260 g_blobid = SPDK_BLOBID_INVALID; 2261 2262 /* Dirty shutdown */ 2263 _spdk_bs_free(g_bs); 2264 2265 /* reload blobstore */ 2266 dev = init_dev(); 2267 spdk_bs_opts_init(&opts); 2268 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2269 CU_ASSERT(g_bserrno == 0); 2270 2271 /* Get the super blob */ 2272 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 2273 CU_ASSERT(g_bserrno == 0); 2274 CU_ASSERT(blobid1 == g_blobid); 2275 2276 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2277 CU_ASSERT(g_bserrno == 0); 2278 CU_ASSERT(g_blob != NULL); 2279 blob = g_blob; 2280 2281 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2282 2283 /* Get the xattrs */ 2284 value = NULL; 2285 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2286 CU_ASSERT(rc == 0); 2287 SPDK_CU_ASSERT_FATAL(value != NULL); 2288 CU_ASSERT(*(uint64_t *)value == length); 2289 CU_ASSERT(value_len == 8); 2290 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2291 2292 /* Resize the blob */ 2293 rc = spdk_blob_resize(blob, 20); 2294 CU_ASSERT(rc == 0); 2295 2296 free_clusters = spdk_bs_free_cluster_count(g_bs); 2297 2298 spdk_blob_close(blob, blob_op_complete, NULL); 2299 CU_ASSERT(g_bserrno == 0); 2300 blob = NULL; 2301 g_blob = NULL; 2302 g_blobid = SPDK_BLOBID_INVALID; 2303 2304 /* Dirty shutdown */ 2305 _spdk_bs_free(g_bs); 2306 2307 /* reload the blobstore */ 2308 dev = init_dev(); 2309 spdk_bs_opts_init(&opts); 2310 /* Load an existing blob store */ 2311 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2312 CU_ASSERT(g_bserrno == 0); 2313 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2314 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2315 CU_ASSERT(g_bserrno == 0); 2316 CU_ASSERT(g_blob != NULL); 2317 blob = g_blob; 2318 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2319 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2320 2321 spdk_blob_close(blob, blob_op_complete, NULL); 2322 CU_ASSERT(g_bserrno == 0); 2323 blob = NULL; 2324 g_blob = NULL; 2325 g_blobid = SPDK_BLOBID_INVALID; 2326 2327 /* Create second blob */ 2328 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2329 CU_ASSERT(g_bserrno == 0); 2330 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2331 blobid2 = g_blobid; 2332 2333 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2334 CU_ASSERT(g_bserrno == 0); 2335 CU_ASSERT(g_blob != NULL); 2336 blob = g_blob; 2337 2338 /* Set some xattrs */ 2339 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2340 CU_ASSERT(rc == 0); 2341 2342 length = 5432; 2343 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2344 CU_ASSERT(rc == 0); 2345 2346 /* Resize the blob */ 2347 rc = spdk_blob_resize(blob, 10); 2348 CU_ASSERT(rc == 0); 2349 2350 free_clusters = spdk_bs_free_cluster_count(g_bs); 2351 2352 spdk_blob_close(blob, blob_op_complete, NULL); 2353 blob = NULL; 2354 g_blob = NULL; 2355 g_blobid = SPDK_BLOBID_INVALID; 2356 2357 /* Dirty shutdown */ 2358 _spdk_bs_free(g_bs); 2359 2360 /* reload the blobstore */ 2361 dev = init_dev(); 2362 spdk_bs_opts_init(&opts); 2363 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2364 CU_ASSERT(g_bserrno == 0); 2365 2366 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2367 CU_ASSERT(g_bserrno == 0); 2368 CU_ASSERT(g_blob != NULL); 2369 blob = g_blob; 2370 2371 /* Get the xattrs */ 2372 value = NULL; 2373 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2374 CU_ASSERT(rc == 0); 2375 SPDK_CU_ASSERT_FATAL(value != NULL); 2376 CU_ASSERT(*(uint64_t *)value == length); 2377 CU_ASSERT(value_len == 8); 2378 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2379 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2380 2381 spdk_blob_close(blob, blob_op_complete, NULL); 2382 CU_ASSERT(g_bserrno == 0); 2383 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2384 CU_ASSERT(g_bserrno == 0); 2385 2386 free_clusters = spdk_bs_free_cluster_count(g_bs); 2387 2388 /* Dirty shutdown */ 2389 _spdk_bs_free(g_bs); 2390 /* reload the blobstore */ 2391 dev = init_dev(); 2392 spdk_bs_opts_init(&opts); 2393 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2394 CU_ASSERT(g_bserrno == 0); 2395 2396 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2397 CU_ASSERT(g_bserrno != 0); 2398 CU_ASSERT(g_blob == NULL); 2399 2400 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2401 CU_ASSERT(g_bserrno == 0); 2402 CU_ASSERT(g_blob != NULL); 2403 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2404 spdk_blob_close(g_blob, blob_op_complete, NULL); 2405 CU_ASSERT(g_bserrno == 0); 2406 2407 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2408 CU_ASSERT(g_bserrno == 0); 2409 g_bs = NULL; 2410 2411 /* reload the blobstore */ 2412 dev = init_dev(); 2413 spdk_bs_opts_init(&opts); 2414 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2415 CU_ASSERT(g_bserrno == 0); 2416 2417 /* Create second blob */ 2418 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2419 CU_ASSERT(g_bserrno == 0); 2420 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2421 blobid2 = g_blobid; 2422 2423 /* Create third blob */ 2424 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2425 CU_ASSERT(g_bserrno == 0); 2426 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2427 blobid3 = g_blobid; 2428 2429 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2430 CU_ASSERT(g_bserrno == 0); 2431 CU_ASSERT(g_blob != NULL); 2432 blob = g_blob; 2433 2434 /* Set some xattrs for second blob */ 2435 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2436 CU_ASSERT(rc == 0); 2437 2438 length = 5432; 2439 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2440 CU_ASSERT(rc == 0); 2441 2442 spdk_blob_close(blob, blob_op_complete, NULL); 2443 blob = NULL; 2444 g_blob = NULL; 2445 g_blobid = SPDK_BLOBID_INVALID; 2446 2447 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2448 CU_ASSERT(g_bserrno == 0); 2449 CU_ASSERT(g_blob != NULL); 2450 blob = g_blob; 2451 2452 /* Set some xattrs for third blob */ 2453 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2454 CU_ASSERT(rc == 0); 2455 2456 length = 5432; 2457 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2458 CU_ASSERT(rc == 0); 2459 2460 spdk_blob_close(blob, blob_op_complete, NULL); 2461 blob = NULL; 2462 g_blob = NULL; 2463 g_blobid = SPDK_BLOBID_INVALID; 2464 2465 /* Mark second blob as invalid */ 2466 page_num = _spdk_bs_blobid_to_page(blobid2); 2467 2468 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2469 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2470 page->sequence_num = 1; 2471 page->crc = _spdk_blob_md_page_calc_crc(page); 2472 2473 free_clusters = spdk_bs_free_cluster_count(g_bs); 2474 2475 /* Dirty shutdown */ 2476 _spdk_bs_free(g_bs); 2477 /* reload the blobstore */ 2478 dev = init_dev(); 2479 spdk_bs_opts_init(&opts); 2480 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2481 CU_ASSERT(g_bserrno == 0); 2482 2483 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2484 CU_ASSERT(g_bserrno != 0); 2485 CU_ASSERT(g_blob == NULL); 2486 2487 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2488 CU_ASSERT(g_bserrno == 0); 2489 CU_ASSERT(g_blob != NULL); 2490 blob = g_blob; 2491 2492 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2493 2494 spdk_blob_close(blob, blob_op_complete, NULL); 2495 blob = NULL; 2496 g_blob = NULL; 2497 g_blobid = SPDK_BLOBID_INVALID; 2498 2499 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2500 CU_ASSERT(g_bserrno == 0); 2501 g_bs = NULL; 2502 } 2503 2504 static void 2505 blob_flags(void) 2506 { 2507 struct spdk_bs_dev *dev; 2508 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2509 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2510 struct spdk_bs_opts opts; 2511 int rc; 2512 2513 dev = init_dev(); 2514 spdk_bs_opts_init(&opts); 2515 2516 /* Initialize a new blob store */ 2517 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2518 CU_ASSERT(g_bserrno == 0); 2519 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2520 2521 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2522 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2523 CU_ASSERT(g_bserrno == 0); 2524 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2525 blobid_invalid = g_blobid; 2526 2527 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2528 CU_ASSERT(g_bserrno == 0); 2529 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2530 blobid_data_ro = g_blobid; 2531 2532 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2533 CU_ASSERT(g_bserrno == 0); 2534 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2535 blobid_md_ro = g_blobid; 2536 2537 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2538 CU_ASSERT(g_bserrno == 0); 2539 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2540 blob_invalid = g_blob; 2541 2542 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2543 CU_ASSERT(g_bserrno == 0); 2544 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2545 blob_data_ro = g_blob; 2546 2547 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2548 CU_ASSERT(g_bserrno == 0); 2549 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2550 blob_md_ro = g_blob; 2551 2552 /* Change the size of blob_data_ro to check if flags are serialized 2553 * when blob has non zero number of extents */ 2554 rc = spdk_blob_resize(blob_data_ro, 10); 2555 CU_ASSERT(rc == 0); 2556 2557 /* Set the xattr to check if flags are serialized 2558 * when blob has non zero number of xattrs */ 2559 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2560 CU_ASSERT(rc == 0); 2561 2562 blob_invalid->invalid_flags = (1ULL << 63); 2563 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2564 blob_data_ro->data_ro_flags = (1ULL << 62); 2565 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2566 blob_md_ro->md_ro_flags = (1ULL << 61); 2567 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2568 2569 g_bserrno = -1; 2570 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2571 CU_ASSERT(g_bserrno == 0); 2572 g_bserrno = -1; 2573 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2574 CU_ASSERT(g_bserrno == 0); 2575 g_bserrno = -1; 2576 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2577 CU_ASSERT(g_bserrno == 0); 2578 2579 g_bserrno = -1; 2580 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2581 CU_ASSERT(g_bserrno == 0); 2582 blob_invalid = NULL; 2583 g_bserrno = -1; 2584 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2585 CU_ASSERT(g_bserrno == 0); 2586 blob_data_ro = NULL; 2587 g_bserrno = -1; 2588 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2589 CU_ASSERT(g_bserrno == 0); 2590 blob_md_ro = NULL; 2591 2592 g_blob = NULL; 2593 g_blobid = SPDK_BLOBID_INVALID; 2594 2595 /* Unload the blob store */ 2596 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2597 CU_ASSERT(g_bserrno == 0); 2598 g_bs = NULL; 2599 2600 /* Load an existing blob store */ 2601 dev = init_dev(); 2602 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2603 CU_ASSERT(g_bserrno == 0); 2604 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2605 2606 g_blob = NULL; 2607 g_bserrno = 0; 2608 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2609 CU_ASSERT(g_bserrno != 0); 2610 CU_ASSERT(g_blob == NULL); 2611 2612 g_blob = NULL; 2613 g_bserrno = -1; 2614 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2615 CU_ASSERT(g_bserrno == 0); 2616 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2617 blob_data_ro = g_blob; 2618 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2619 CU_ASSERT(blob_data_ro->data_ro == true); 2620 CU_ASSERT(blob_data_ro->md_ro == true); 2621 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2622 2623 g_blob = NULL; 2624 g_bserrno = -1; 2625 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2626 CU_ASSERT(g_bserrno == 0); 2627 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2628 blob_md_ro = g_blob; 2629 CU_ASSERT(blob_md_ro->data_ro == false); 2630 CU_ASSERT(blob_md_ro->md_ro == true); 2631 2632 g_bserrno = -1; 2633 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2634 CU_ASSERT(g_bserrno == 0); 2635 2636 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2637 CU_ASSERT(g_bserrno == 0); 2638 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2639 CU_ASSERT(g_bserrno == 0); 2640 2641 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2642 CU_ASSERT(g_bserrno == 0); 2643 } 2644 2645 static void 2646 bs_version(void) 2647 { 2648 struct spdk_bs_super_block *super; 2649 struct spdk_bs_dev *dev; 2650 struct spdk_bs_opts opts; 2651 spdk_blob_id blobid; 2652 2653 dev = init_dev(); 2654 spdk_bs_opts_init(&opts); 2655 2656 /* Initialize a new blob store */ 2657 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2658 CU_ASSERT(g_bserrno == 0); 2659 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2660 2661 /* Unload the blob store */ 2662 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2663 CU_ASSERT(g_bserrno == 0); 2664 g_bs = NULL; 2665 2666 /* 2667 * Change the bs version on disk. This will allow us to 2668 * test that the version does not get modified automatically 2669 * when loading and unloading the blobstore. 2670 */ 2671 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 2672 CU_ASSERT(super->version == SPDK_BS_VERSION); 2673 CU_ASSERT(super->clean == 1); 2674 super->version = 2; 2675 /* 2676 * Version 2 metadata does not have a used blobid mask, so clear 2677 * those fields in the super block and zero the corresponding 2678 * region on "disk". We will use this to ensure blob IDs are 2679 * correctly reconstructed. 2680 */ 2681 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 2682 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 2683 super->used_blobid_mask_start = 0; 2684 super->used_blobid_mask_len = 0; 2685 super->crc = _spdk_blob_md_page_calc_crc(super); 2686 2687 /* Load an existing blob store */ 2688 dev = init_dev(); 2689 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2690 CU_ASSERT(g_bserrno == 0); 2691 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2692 CU_ASSERT(super->clean == 0); 2693 2694 /* 2695 * Create a blob - just to make sure that when we unload it 2696 * results in writing the super block (since metadata pages 2697 * were allocated. 2698 */ 2699 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2700 CU_ASSERT(g_bserrno == 0); 2701 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2702 blobid = g_blobid; 2703 2704 /* Unload the blob store */ 2705 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2706 CU_ASSERT(g_bserrno == 0); 2707 g_bs = NULL; 2708 CU_ASSERT(super->version == 2); 2709 CU_ASSERT(super->used_blobid_mask_start == 0); 2710 CU_ASSERT(super->used_blobid_mask_len == 0); 2711 2712 dev = init_dev(); 2713 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2714 CU_ASSERT(g_bserrno == 0); 2715 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2716 2717 g_blob = NULL; 2718 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2719 CU_ASSERT(g_bserrno == 0); 2720 CU_ASSERT(g_blob != NULL); 2721 2722 spdk_blob_close(g_blob, blob_op_complete, NULL); 2723 CU_ASSERT(g_bserrno == 0); 2724 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 2733 static void 2734 blob_set_xattrs(void) 2735 { 2736 struct spdk_blob_store *bs; 2737 struct spdk_bs_dev *dev; 2738 struct spdk_blob *blob; 2739 struct spdk_blob_opts opts; 2740 spdk_blob_id blobid; 2741 const void *value; 2742 size_t value_len; 2743 int rc; 2744 2745 dev = init_dev(); 2746 2747 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2748 CU_ASSERT(g_bserrno == 0); 2749 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2750 bs = g_bs; 2751 2752 /* Create blob with extra attributes */ 2753 spdk_blob_opts_init(&opts); 2754 2755 opts.xattrs.names = g_xattr_names; 2756 opts.xattrs.get_value = _get_xattr_value; 2757 opts.xattrs.count = 3; 2758 opts.xattrs.ctx = &g_ctx; 2759 2760 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2761 CU_ASSERT(g_bserrno == 0); 2762 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2763 blobid = g_blobid; 2764 2765 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2766 CU_ASSERT(g_bserrno == 0); 2767 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2768 blob = g_blob; 2769 2770 /* Get the xattrs */ 2771 value = NULL; 2772 2773 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 2774 CU_ASSERT(rc == 0); 2775 SPDK_CU_ASSERT_FATAL(value != NULL); 2776 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 2777 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 2778 2779 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 2780 CU_ASSERT(rc == 0); 2781 SPDK_CU_ASSERT_FATAL(value != NULL); 2782 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 2783 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 2784 2785 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 2786 CU_ASSERT(rc == 0); 2787 SPDK_CU_ASSERT_FATAL(value != NULL); 2788 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 2789 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 2790 2791 /* Try to get non existing attribute */ 2792 2793 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 2794 CU_ASSERT(rc == -ENOENT); 2795 2796 spdk_blob_close(blob, blob_op_complete, NULL); 2797 CU_ASSERT(g_bserrno == 0); 2798 blob = NULL; 2799 g_blob = NULL; 2800 g_blobid = SPDK_BLOBID_INVALID; 2801 2802 /* NULL callback */ 2803 spdk_blob_opts_init(&opts); 2804 opts.xattrs.names = g_xattr_names; 2805 opts.xattrs.get_value = NULL; 2806 opts.xattrs.count = 1; 2807 opts.xattrs.ctx = &g_ctx; 2808 2809 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2810 CU_ASSERT(g_bserrno == -EINVAL); 2811 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2812 2813 /* NULL values */ 2814 spdk_blob_opts_init(&opts); 2815 opts.xattrs.names = g_xattr_names; 2816 opts.xattrs.get_value = _get_xattr_value_null; 2817 opts.xattrs.count = 1; 2818 opts.xattrs.ctx = NULL; 2819 2820 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2821 CU_ASSERT(g_bserrno == -EINVAL); 2822 2823 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2824 CU_ASSERT(g_bserrno == 0); 2825 g_bs = NULL; 2826 2827 } 2828 2829 static void 2830 blob_thin_prov_alloc(void) 2831 { 2832 struct spdk_blob_store *bs; 2833 struct spdk_bs_dev *dev; 2834 struct spdk_blob *blob; 2835 struct spdk_blob_opts opts; 2836 spdk_blob_id blobid; 2837 uint64_t free_clusters; 2838 int rc; 2839 2840 dev = init_dev(); 2841 2842 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2843 CU_ASSERT(g_bserrno == 0); 2844 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2845 bs = g_bs; 2846 free_clusters = spdk_bs_free_cluster_count(bs); 2847 2848 /* Set blob as thin provisioned */ 2849 spdk_blob_opts_init(&opts); 2850 opts.thin_provision = true; 2851 2852 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2853 CU_ASSERT(g_bserrno == 0); 2854 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2855 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2856 blobid = g_blobid; 2857 2858 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2859 CU_ASSERT(g_bserrno == 0); 2860 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2861 blob = g_blob; 2862 2863 CU_ASSERT(blob->active.num_clusters == 0); 2864 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 2865 2866 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 2867 rc = spdk_blob_resize(blob, 5); 2868 CU_ASSERT(rc == 0); 2869 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2870 CU_ASSERT(blob->active.num_clusters == 5); 2871 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 2872 2873 /* Shrink the blob to 3 clusters - still unallocated */ 2874 rc = spdk_blob_resize(blob, 3); 2875 CU_ASSERT(rc == 0); 2876 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2877 CU_ASSERT(blob->active.num_clusters == 3); 2878 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2879 2880 spdk_blob_sync_md(blob, blob_op_complete, NULL); 2881 CU_ASSERT(g_bserrno == 0); 2882 /* Sync must not change anything */ 2883 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2884 CU_ASSERT(blob->active.num_clusters == 3); 2885 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 2886 2887 spdk_blob_close(blob, blob_op_complete, NULL); 2888 CU_ASSERT(g_bserrno == 0); 2889 2890 /* Unload the blob store */ 2891 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2892 CU_ASSERT(g_bserrno == 0); 2893 g_bs = NULL; 2894 g_blob = NULL; 2895 g_blobid = 0; 2896 2897 /* Load an existing blob store */ 2898 dev = init_dev(); 2899 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2900 CU_ASSERT(g_bserrno == 0); 2901 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2902 2903 bs = g_bs; 2904 2905 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2906 CU_ASSERT(g_bserrno == 0); 2907 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2908 blob = g_blob; 2909 2910 /* Check that clusters allocation and size is still the same */ 2911 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2912 CU_ASSERT(blob->active.num_clusters == 3); 2913 2914 spdk_blob_close(blob, blob_op_complete, NULL); 2915 CU_ASSERT(g_bserrno == 0); 2916 2917 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2918 CU_ASSERT(g_bserrno == 0); 2919 2920 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2921 CU_ASSERT(g_bserrno == 0); 2922 g_bs = NULL; 2923 } 2924 2925 static void 2926 blob_insert_cluster_msg(void) 2927 { 2928 struct spdk_blob_store *bs; 2929 struct spdk_bs_dev *dev; 2930 struct spdk_blob *blob; 2931 struct spdk_blob_opts opts; 2932 spdk_blob_id blobid; 2933 uint64_t free_clusters; 2934 2935 dev = init_dev(); 2936 2937 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2938 CU_ASSERT(g_bserrno == 0); 2939 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2940 bs = g_bs; 2941 free_clusters = spdk_bs_free_cluster_count(bs); 2942 2943 /* Set blob as thin provisioned */ 2944 spdk_blob_opts_init(&opts); 2945 opts.thin_provision = true; 2946 opts.num_clusters = 4; 2947 2948 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 2949 CU_ASSERT(g_bserrno == 0); 2950 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2951 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 2952 blobid = g_blobid; 2953 2954 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2955 CU_ASSERT(g_bserrno == 0); 2956 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2957 blob = g_blob; 2958 2959 CU_ASSERT(blob->active.num_clusters == 4); 2960 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 2961 CU_ASSERT(blob->active.clusters[1] == 0); 2962 2963 _spdk_bs_claim_cluster(bs, 0xF); 2964 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 2965 2966 CU_ASSERT(blob->active.clusters[1] != 0); 2967 2968 spdk_blob_close(blob, blob_op_complete, NULL); 2969 CU_ASSERT(g_bserrno == 0); 2970 2971 /* Unload the blob store */ 2972 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2973 CU_ASSERT(g_bserrno == 0); 2974 g_bs = NULL; 2975 g_blob = NULL; 2976 g_blobid = 0; 2977 2978 /* Load an existing blob store */ 2979 dev = init_dev(); 2980 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 2981 CU_ASSERT(g_bserrno == 0); 2982 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2983 2984 bs = g_bs; 2985 2986 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 2987 CU_ASSERT(g_bserrno == 0); 2988 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2989 blob = g_blob; 2990 2991 CU_ASSERT(blob->active.clusters[1] != 0); 2992 2993 spdk_blob_close(blob, blob_op_complete, NULL); 2994 CU_ASSERT(g_bserrno == 0); 2995 2996 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2997 CU_ASSERT(g_bserrno == 0); 2998 2999 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3000 CU_ASSERT(g_bserrno == 0); 3001 g_bs = NULL; 3002 } 3003 3004 static void 3005 blob_thin_prov_rw(void) 3006 { 3007 static const uint8_t zero[10 * 4096] = { 0 }; 3008 struct spdk_blob_store *bs; 3009 struct spdk_bs_dev *dev; 3010 struct spdk_blob *blob; 3011 struct spdk_io_channel *channel; 3012 struct spdk_blob_opts opts; 3013 spdk_blob_id blobid; 3014 uint64_t free_clusters; 3015 uint8_t payload_read[10 * 4096]; 3016 uint8_t payload_write[10 * 4096]; 3017 int rc; 3018 3019 dev = init_dev(); 3020 3021 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3022 CU_ASSERT(g_bserrno == 0); 3023 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3024 bs = g_bs; 3025 free_clusters = spdk_bs_free_cluster_count(bs); 3026 3027 channel = spdk_bs_alloc_io_channel(bs); 3028 CU_ASSERT(channel != NULL); 3029 3030 spdk_blob_opts_init(&opts); 3031 opts.thin_provision = true; 3032 3033 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3034 CU_ASSERT(g_bserrno == 0); 3035 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3036 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3037 blobid = g_blobid; 3038 3039 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3040 CU_ASSERT(g_bserrno == 0); 3041 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3042 blob = g_blob; 3043 3044 CU_ASSERT(blob->active.num_clusters == 0); 3045 3046 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3047 rc = spdk_blob_resize(blob, 5); 3048 CU_ASSERT(rc == 0); 3049 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3050 CU_ASSERT(blob->active.num_clusters == 5); 3051 3052 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3053 CU_ASSERT(g_bserrno == 0); 3054 /* Sync must not change anything */ 3055 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3056 CU_ASSERT(blob->active.num_clusters == 5); 3057 3058 /* Payload should be all zeros from unallocated clusters */ 3059 memset(payload_read, 0xFF, sizeof(payload_read)); 3060 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3061 CU_ASSERT(g_bserrno == 0); 3062 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3063 3064 memset(payload_write, 0xE5, sizeof(payload_write)); 3065 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3066 CU_ASSERT(g_bserrno == 0); 3067 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3068 3069 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3070 CU_ASSERT(g_bserrno == 0); 3071 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3072 3073 spdk_blob_close(blob, blob_op_complete, NULL); 3074 CU_ASSERT(g_bserrno == 0); 3075 3076 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3077 CU_ASSERT(g_bserrno == 0); 3078 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3079 3080 spdk_bs_free_io_channel(channel); 3081 3082 /* Unload the blob store */ 3083 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3084 CU_ASSERT(g_bserrno == 0); 3085 g_bs = NULL; 3086 g_blob = NULL; 3087 g_blobid = 0; 3088 } 3089 3090 static void 3091 blob_thin_prov_rw_iov(void) 3092 { 3093 static const uint8_t zero[10 * 4096] = { 0 }; 3094 struct spdk_blob_store *bs; 3095 struct spdk_bs_dev *dev; 3096 struct spdk_blob *blob; 3097 struct spdk_io_channel *channel; 3098 struct spdk_blob_opts opts; 3099 spdk_blob_id blobid; 3100 uint64_t free_clusters; 3101 uint8_t payload_read[10 * 4096]; 3102 uint8_t payload_write[10 * 4096]; 3103 struct iovec iov_read[3]; 3104 struct iovec iov_write[3]; 3105 3106 int rc; 3107 3108 dev = init_dev(); 3109 3110 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3111 CU_ASSERT(g_bserrno == 0); 3112 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3113 bs = g_bs; 3114 free_clusters = spdk_bs_free_cluster_count(bs); 3115 3116 channel = spdk_bs_alloc_io_channel(bs); 3117 CU_ASSERT(channel != NULL); 3118 3119 spdk_blob_opts_init(&opts); 3120 opts.thin_provision = true; 3121 3122 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3123 CU_ASSERT(g_bserrno == 0); 3124 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3125 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3126 blobid = g_blobid; 3127 3128 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3129 CU_ASSERT(g_bserrno == 0); 3130 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3131 blob = g_blob; 3132 3133 CU_ASSERT(blob->active.num_clusters == 0); 3134 3135 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3136 rc = spdk_blob_resize(blob, 5); 3137 CU_ASSERT(rc == 0); 3138 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3139 CU_ASSERT(blob->active.num_clusters == 5); 3140 3141 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3142 CU_ASSERT(g_bserrno == 0); 3143 /* Sync must not change anything */ 3144 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3145 CU_ASSERT(blob->active.num_clusters == 5); 3146 3147 /* Payload should be all zeros from unallocated clusters */ 3148 memset(payload_read, 0xAA, sizeof(payload_read)); 3149 iov_read[0].iov_base = payload_read; 3150 iov_read[0].iov_len = 3 * 4096; 3151 iov_read[1].iov_base = payload_read + 3 * 4096; 3152 iov_read[1].iov_len = 4 * 4096; 3153 iov_read[2].iov_base = payload_read + 7 * 4096; 3154 iov_read[2].iov_len = 3 * 4096; 3155 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3156 CU_ASSERT(g_bserrno == 0); 3157 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3158 3159 memset(payload_write, 0xE5, sizeof(payload_write)); 3160 iov_write[0].iov_base = payload_write; 3161 iov_write[0].iov_len = 1 * 4096; 3162 iov_write[1].iov_base = payload_write + 1 * 4096; 3163 iov_write[1].iov_len = 5 * 4096; 3164 iov_write[2].iov_base = payload_write + 6 * 4096; 3165 iov_write[2].iov_len = 4 * 4096; 3166 3167 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3168 CU_ASSERT(g_bserrno == 0); 3169 3170 memset(payload_read, 0xAA, sizeof(payload_read)); 3171 iov_read[0].iov_base = payload_read; 3172 iov_read[0].iov_len = 3 * 4096; 3173 iov_read[1].iov_base = payload_read + 3 * 4096; 3174 iov_read[1].iov_len = 4 * 4096; 3175 iov_read[2].iov_base = payload_read + 7 * 4096; 3176 iov_read[2].iov_len = 3 * 4096; 3177 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3178 CU_ASSERT(g_bserrno == 0); 3179 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3180 3181 spdk_blob_close(blob, blob_op_complete, NULL); 3182 CU_ASSERT(g_bserrno == 0); 3183 3184 spdk_bs_free_io_channel(channel); 3185 3186 /* Unload the blob store */ 3187 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3188 CU_ASSERT(g_bserrno == 0); 3189 g_bs = NULL; 3190 g_blob = NULL; 3191 g_blobid = 0; 3192 } 3193 3194 struct iter_ctx { 3195 int current_iter; 3196 spdk_blob_id blobid[4]; 3197 }; 3198 3199 static void 3200 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3201 { 3202 struct iter_ctx *iter_ctx = arg; 3203 spdk_blob_id blobid; 3204 3205 CU_ASSERT(bserrno == 0); 3206 blobid = spdk_blob_get_id(blob); 3207 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3208 } 3209 3210 static void 3211 bs_load_iter(void) 3212 { 3213 struct spdk_bs_dev *dev; 3214 struct iter_ctx iter_ctx = { 0 }; 3215 struct spdk_blob *blob; 3216 int i, rc; 3217 struct spdk_bs_opts opts; 3218 3219 dev = init_dev(); 3220 spdk_bs_opts_init(&opts); 3221 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3222 3223 /* Initialize a new blob store */ 3224 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3225 CU_ASSERT(g_bserrno == 0); 3226 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3227 3228 for (i = 0; i < 4; i++) { 3229 g_bserrno = -1; 3230 g_blobid = SPDK_BLOBID_INVALID; 3231 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3232 CU_ASSERT(g_bserrno == 0); 3233 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3234 iter_ctx.blobid[i] = g_blobid; 3235 3236 g_bserrno = -1; 3237 g_blob = NULL; 3238 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3239 CU_ASSERT(g_bserrno == 0); 3240 CU_ASSERT(g_blob != NULL); 3241 blob = g_blob; 3242 3243 /* Just save the blobid as an xattr for testing purposes. */ 3244 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3245 CU_ASSERT(rc == 0); 3246 3247 /* Resize the blob */ 3248 rc = spdk_blob_resize(blob, i); 3249 CU_ASSERT(rc == 0); 3250 3251 spdk_blob_close(blob, blob_op_complete, NULL); 3252 CU_ASSERT(g_bserrno == 0); 3253 } 3254 3255 g_bserrno = -1; 3256 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3257 CU_ASSERT(g_bserrno == 0); 3258 3259 dev = init_dev(); 3260 spdk_bs_opts_init(&opts); 3261 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3262 opts.iter_cb_fn = test_iter; 3263 opts.iter_cb_arg = &iter_ctx; 3264 3265 /* Test blob iteration during load after a clean shutdown. */ 3266 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3267 CU_ASSERT(g_bserrno == 0); 3268 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3269 3270 /* Dirty shutdown */ 3271 _spdk_bs_free(g_bs); 3272 3273 dev = init_dev(); 3274 spdk_bs_opts_init(&opts); 3275 strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH); 3276 opts.iter_cb_fn = test_iter; 3277 iter_ctx.current_iter = 0; 3278 opts.iter_cb_arg = &iter_ctx; 3279 3280 /* Test blob iteration during load after a dirty shutdown. */ 3281 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3282 CU_ASSERT(g_bserrno == 0); 3283 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3284 3285 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3286 CU_ASSERT(g_bserrno == 0); 3287 g_bs = NULL; 3288 3289 } 3290 3291 int main(int argc, char **argv) 3292 { 3293 CU_pSuite suite = NULL; 3294 unsigned int num_failures; 3295 3296 if (CU_initialize_registry() != CUE_SUCCESS) { 3297 return CU_get_error(); 3298 } 3299 3300 suite = CU_add_suite("blob", NULL, NULL); 3301 if (suite == NULL) { 3302 CU_cleanup_registry(); 3303 return CU_get_error(); 3304 } 3305 3306 if ( 3307 CU_add_test(suite, "blob_init", blob_init) == NULL || 3308 CU_add_test(suite, "blob_open", blob_open) == NULL || 3309 CU_add_test(suite, "blob_create", blob_create) == NULL || 3310 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 3311 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 3312 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 3313 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 3314 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 3315 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 3316 CU_add_test(suite, "blob_super", blob_super) == NULL || 3317 CU_add_test(suite, "blob_write", blob_write) == NULL || 3318 CU_add_test(suite, "blob_read", blob_read) == NULL || 3319 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 3320 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 3321 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 3322 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 3323 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 3324 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 3325 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 3326 CU_add_test(suite, "bs_load", bs_load) == NULL || 3327 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 3328 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 3329 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 3330 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 3331 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 3332 CU_add_test(suite, "bs_type", bs_type) == NULL || 3333 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 3334 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 3335 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 3336 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 3337 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 3338 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 3339 CU_add_test(suite, "bs_version", bs_version) == NULL || 3340 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 3341 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 3342 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 3343 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 3344 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 3345 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL 3346 ) { 3347 CU_cleanup_registry(); 3348 return CU_get_error(); 3349 } 3350 3351 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 3352 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 3353 CU_basic_set_mode(CU_BRM_VERBOSE); 3354 CU_basic_run_tests(); 3355 num_failures = CU_get_number_of_failures(); 3356 CU_cleanup_registry(); 3357 spdk_free_thread(); 3358 free(g_dev_buffer); 3359 return num_failures; 3360 } 3361