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