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 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 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 /* Do not shut down cleanly. This makes sure that when we load again 528 * and try to recover a valid used_cluster map, that blobstore will 529 * ignore clusters with index 0 since these are unallocated clusters. 530 */ 531 532 /* Load an existing blob store and check if invalid_flags is set */ 533 dev = init_dev(); 534 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 535 spdk_bs_load(dev, &bs_opts, bs_op_with_handle_complete, NULL); 536 CU_ASSERT(g_bserrno == 0); 537 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 538 539 bs = g_bs; 540 541 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 542 CU_ASSERT(g_bserrno == 0); 543 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 544 blob = g_blob; 545 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 546 547 spdk_blob_close(blob, blob_op_complete, NULL); 548 CU_ASSERT(g_bserrno == 0); 549 550 spdk_bs_unload(g_bs, bs_op_complete, NULL); 551 CU_ASSERT(g_bserrno == 0); 552 g_bs = NULL; 553 } 554 555 static void 556 blob_snapshot(void) 557 { 558 struct spdk_blob_store *bs; 559 struct spdk_bs_dev *dev; 560 struct spdk_blob *blob; 561 struct spdk_blob *snapshot, *snapshot2; 562 struct spdk_blob_bs_dev *blob_bs_dev; 563 struct spdk_blob_opts opts; 564 struct spdk_blob_xattr_opts xattrs; 565 spdk_blob_id blobid; 566 spdk_blob_id snapshotid; 567 const void *value; 568 size_t value_len; 569 int rc; 570 571 dev = init_dev(); 572 573 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 574 CU_ASSERT(g_bserrno == 0); 575 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 576 bs = g_bs; 577 578 /* Create blob with 10 clusters */ 579 spdk_blob_opts_init(&opts); 580 opts.num_clusters = 10; 581 582 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 583 CU_ASSERT(g_bserrno == 0); 584 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 585 blobid = g_blobid; 586 587 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 588 CU_ASSERT(g_bserrno == 0); 589 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 590 blob = g_blob; 591 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 592 593 /* Create snapshot from blob */ 594 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 595 CU_ASSERT(g_bserrno == 0); 596 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 597 snapshotid = g_blobid; 598 599 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 600 CU_ASSERT(g_bserrno == 0); 601 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 602 snapshot = g_blob; 603 CU_ASSERT(snapshot->data_ro == true) 604 CU_ASSERT(snapshot->md_ro == true) 605 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10) 606 607 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 608 CU_ASSERT(blob->invalid_flags & SPDK_BLOB_THIN_PROV); 609 CU_ASSERT(spdk_mem_all_zero(blob->active.clusters, 610 blob->active.num_clusters * sizeof(blob->active.clusters[0]))); 611 612 /* Try to create snapshot from clone with xattrs */ 613 xattrs.names = g_xattr_names; 614 xattrs.get_value = _get_xattr_value; 615 xattrs.count = 3; 616 xattrs.ctx = &g_ctx; 617 spdk_bs_create_snapshot(bs, blobid, &xattrs, blob_op_with_id_complete, NULL); 618 CU_ASSERT(g_bserrno == 0); 619 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 620 blobid = g_blobid; 621 622 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 623 CU_ASSERT(g_bserrno == 0); 624 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 625 snapshot2 = g_blob; 626 CU_ASSERT(snapshot2->data_ro == true) 627 CU_ASSERT(snapshot2->md_ro == true) 628 CU_ASSERT(spdk_blob_get_num_clusters(snapshot2) == 10) 629 630 /* Confirm that blob is backed by snapshot2 and snapshot2 is backed by snapshot */ 631 CU_ASSERT(snapshot->back_bs_dev == NULL); 632 SPDK_CU_ASSERT_FATAL(blob->back_bs_dev != NULL); 633 SPDK_CU_ASSERT_FATAL(snapshot2->back_bs_dev != NULL); 634 635 blob_bs_dev = (struct spdk_blob_bs_dev *)blob->back_bs_dev; 636 CU_ASSERT(blob_bs_dev->blob == snapshot2); 637 638 blob_bs_dev = (struct spdk_blob_bs_dev *)snapshot2->back_bs_dev; 639 CU_ASSERT(blob_bs_dev->blob == snapshot); 640 641 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[0], &value, &value_len); 642 CU_ASSERT(rc == 0); 643 SPDK_CU_ASSERT_FATAL(value != NULL); 644 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 645 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 646 647 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[1], &value, &value_len); 648 CU_ASSERT(rc == 0); 649 SPDK_CU_ASSERT_FATAL(value != NULL); 650 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 651 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 652 653 rc = spdk_blob_get_xattr_value(snapshot2, g_xattr_names[2], &value, &value_len); 654 CU_ASSERT(rc == 0); 655 SPDK_CU_ASSERT_FATAL(value != NULL); 656 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 657 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 658 659 /* Try to create snapshot from snapshot */ 660 spdk_bs_create_snapshot(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 661 CU_ASSERT(g_bserrno == -EINVAL); 662 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 663 664 spdk_blob_close(blob, blob_op_complete, NULL); 665 CU_ASSERT(g_bserrno == 0); 666 667 spdk_blob_close(snapshot, blob_op_complete, NULL); 668 CU_ASSERT(g_bserrno == 0); 669 670 spdk_blob_close(snapshot2, blob_op_complete, NULL); 671 CU_ASSERT(g_bserrno == 0); 672 673 spdk_bs_unload(g_bs, bs_op_complete, NULL); 674 CU_ASSERT(g_bserrno == 0); 675 g_bs = NULL; 676 } 677 678 static void 679 blob_clone(void) 680 { 681 struct spdk_blob_store *bs; 682 struct spdk_bs_dev *dev; 683 struct spdk_blob_opts opts; 684 struct spdk_blob *blob, *snapshot, *clone; 685 spdk_blob_id blobid, cloneid, snapshotid; 686 struct spdk_blob_xattr_opts xattrs; 687 const void *value; 688 size_t value_len; 689 int rc; 690 691 dev = init_dev(); 692 693 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 694 CU_ASSERT(g_bserrno == 0); 695 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 696 bs = g_bs; 697 698 /* Create blob with 10 clusters */ 699 700 spdk_blob_opts_init(&opts); 701 opts.num_clusters = 10; 702 703 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 704 CU_ASSERT(g_bserrno == 0); 705 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 706 blobid = g_blobid; 707 708 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 709 CU_ASSERT(g_bserrno == 0); 710 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 711 blob = g_blob; 712 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 713 714 /* Create snapshot */ 715 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 716 CU_ASSERT(g_bserrno == 0); 717 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 718 snapshotid = g_blobid; 719 720 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 721 CU_ASSERT(g_bserrno == 0); 722 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 723 snapshot = g_blob; 724 CU_ASSERT(snapshot->data_ro == true) 725 CU_ASSERT(snapshot->md_ro == true) 726 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 727 728 spdk_blob_close(snapshot, blob_op_complete, NULL); 729 CU_ASSERT(g_bserrno == 0); 730 731 /* Create clone from snapshot with xattrs */ 732 xattrs.names = g_xattr_names; 733 xattrs.get_value = _get_xattr_value; 734 xattrs.count = 3; 735 xattrs.ctx = &g_ctx; 736 737 spdk_bs_create_clone(bs, snapshotid, &xattrs, blob_op_with_id_complete, NULL); 738 CU_ASSERT(g_bserrno == 0); 739 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 740 cloneid = g_blobid; 741 742 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 743 CU_ASSERT(g_bserrno == 0); 744 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 745 clone = g_blob; 746 CU_ASSERT(clone->data_ro == false) 747 CU_ASSERT(clone->md_ro == false) 748 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 749 750 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[0], &value, &value_len); 751 CU_ASSERT(rc == 0); 752 SPDK_CU_ASSERT_FATAL(value != NULL); 753 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 754 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 755 756 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[1], &value, &value_len); 757 CU_ASSERT(rc == 0); 758 SPDK_CU_ASSERT_FATAL(value != NULL); 759 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 760 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 761 762 rc = spdk_blob_get_xattr_value(clone, g_xattr_names[2], &value, &value_len); 763 CU_ASSERT(rc == 0); 764 SPDK_CU_ASSERT_FATAL(value != NULL); 765 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 766 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 767 768 769 spdk_blob_close(clone, blob_op_complete, NULL); 770 CU_ASSERT(g_bserrno == 0); 771 772 /* Try to create clone from not read only blob */ 773 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 774 CU_ASSERT(g_bserrno == -EINVAL); 775 CU_ASSERT(g_blobid == SPDK_BLOBID_INVALID); 776 777 /* Mark blob as read only */ 778 spdk_blob_set_read_only(blob); 779 spdk_blob_sync_md(blob, blob_op_complete, NULL); 780 CU_ASSERT(g_bserrno == 0); 781 782 /* Create clone from read only blob */ 783 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 784 CU_ASSERT(g_bserrno == 0); 785 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 786 cloneid = g_blobid; 787 788 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 789 CU_ASSERT(g_bserrno == 0); 790 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 791 clone = g_blob; 792 CU_ASSERT(clone->data_ro == false) 793 CU_ASSERT(clone->md_ro == false) 794 CU_ASSERT(spdk_blob_get_num_clusters(clone) == 10); 795 796 spdk_blob_close(clone, blob_op_complete, NULL); 797 CU_ASSERT(g_bserrno == 0); 798 799 spdk_blob_close(blob, blob_op_complete, NULL); 800 CU_ASSERT(g_bserrno == 0); 801 802 spdk_bs_unload(g_bs, bs_op_complete, NULL); 803 CU_ASSERT(g_bserrno == 0); 804 g_bs = NULL; 805 806 } 807 808 static void 809 blob_inflate(void) 810 { 811 struct spdk_blob_store *bs; 812 struct spdk_bs_dev *dev; 813 struct spdk_blob_opts opts; 814 struct spdk_blob *blob, *snapshot; 815 spdk_blob_id blobid, snapshotid; 816 struct spdk_io_channel *channel; 817 uint64_t free_clusters; 818 819 dev = init_dev(); 820 821 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 822 CU_ASSERT(g_bserrno == 0); 823 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 824 bs = g_bs; 825 826 channel = spdk_bs_alloc_io_channel(bs); 827 SPDK_CU_ASSERT_FATAL(channel != NULL); 828 829 /* Create blob with 10 clusters */ 830 831 spdk_blob_opts_init(&opts); 832 opts.num_clusters = 10; 833 834 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 835 CU_ASSERT(g_bserrno == 0); 836 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 837 blobid = g_blobid; 838 839 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 840 CU_ASSERT(g_bserrno == 0); 841 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 842 blob = g_blob; 843 844 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 845 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 846 847 /* Create snapshot */ 848 849 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 850 CU_ASSERT(g_bserrno == 0); 851 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 852 snapshotid = g_blobid; 853 854 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == true); 855 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 856 857 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 858 CU_ASSERT(g_bserrno == 0); 859 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 860 snapshot = g_blob; 861 CU_ASSERT(snapshot->data_ro == true) 862 CU_ASSERT(snapshot->md_ro == true) 863 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 10); 864 865 spdk_blob_close(snapshot, blob_op_complete, NULL); 866 CU_ASSERT(g_bserrno == 0); 867 868 free_clusters = spdk_bs_free_cluster_count(bs); 869 870 /* Inflate blob */ 871 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 872 CU_ASSERT(g_bserrno == 0); 873 874 /* All 10 clusters should be allocated from blob store */ 875 CU_ASSERT(spdk_bs_free_cluster_count(bs) == free_clusters - 10); 876 877 /* Now, it should be possible to delete snapshot */ 878 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 879 CU_ASSERT(g_bserrno == 0); 880 881 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10) 882 CU_ASSERT(spdk_blob_is_thin_provisioned(blob) == false); 883 884 spdk_blob_close(blob, blob_op_complete, NULL); 885 CU_ASSERT(g_bserrno == 0); 886 887 spdk_bs_unload(g_bs, bs_op_complete, NULL); 888 CU_ASSERT(g_bserrno == 0); 889 g_bs = NULL; 890 891 spdk_bs_free_io_channel(channel); 892 } 893 894 static void 895 blob_delete(void) 896 { 897 struct spdk_blob_store *bs; 898 struct spdk_bs_dev *dev; 899 spdk_blob_id blobid; 900 901 dev = init_dev(); 902 903 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 904 CU_ASSERT(g_bserrno == 0); 905 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 906 bs = g_bs; 907 908 /* Create a blob and then delete it. */ 909 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 910 CU_ASSERT(g_bserrno == 0); 911 CU_ASSERT(g_blobid > 0); 912 blobid = g_blobid; 913 914 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 915 CU_ASSERT(g_bserrno == 0); 916 917 /* Try to open the blob */ 918 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 919 CU_ASSERT(g_bserrno == -ENOENT); 920 921 spdk_bs_unload(g_bs, bs_op_complete, NULL); 922 CU_ASSERT(g_bserrno == 0); 923 g_bs = NULL; 924 } 925 926 static void 927 blob_resize(void) 928 { 929 struct spdk_blob_store *bs; 930 struct spdk_bs_dev *dev; 931 struct spdk_blob *blob; 932 spdk_blob_id blobid; 933 uint64_t free_clusters; 934 935 dev = init_dev(); 936 937 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 938 CU_ASSERT(g_bserrno == 0); 939 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 940 bs = g_bs; 941 free_clusters = spdk_bs_free_cluster_count(bs); 942 943 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 944 CU_ASSERT(g_bserrno == 0); 945 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 946 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 947 blobid = g_blobid; 948 949 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 950 CU_ASSERT(g_bserrno == 0); 951 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 952 blob = g_blob; 953 954 /* Confirm that resize fails if blob is marked read-only. */ 955 blob->md_ro = true; 956 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 957 CU_ASSERT(g_bserrno == -EPERM); 958 blob->md_ro = false; 959 960 /* The blob started at 0 clusters. Resize it to be 5. */ 961 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 962 CU_ASSERT(g_bserrno == 0); 963 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 964 965 /* Shrink the blob to 3 clusters. This will not actually release 966 * the old clusters until the blob is synced. 967 */ 968 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 969 CU_ASSERT(g_bserrno == 0); 970 /* Verify there are still 5 clusters in use */ 971 CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs)); 972 973 spdk_blob_sync_md(blob, blob_op_complete, NULL); 974 CU_ASSERT(g_bserrno == 0); 975 /* Now there are only 3 clusters in use */ 976 CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs)); 977 978 /* Resize the blob to be 10 clusters. Growth takes effect immediately. */ 979 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 980 CU_ASSERT(g_bserrno == 0); 981 CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs)); 982 983 /* Try to resize the blob to size larger than blobstore. */ 984 spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL); 985 CU_ASSERT(g_bserrno == -ENOSPC); 986 987 spdk_blob_close(blob, blob_op_complete, NULL); 988 CU_ASSERT(g_bserrno == 0); 989 990 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 991 CU_ASSERT(g_bserrno == 0); 992 993 spdk_bs_unload(g_bs, bs_op_complete, NULL); 994 CU_ASSERT(g_bserrno == 0); 995 g_bs = NULL; 996 } 997 998 static void 999 blob_read_only(void) 1000 { 1001 struct spdk_blob_store *bs; 1002 struct spdk_bs_dev *dev; 1003 struct spdk_blob *blob; 1004 struct spdk_bs_opts opts; 1005 spdk_blob_id blobid; 1006 int rc; 1007 1008 dev = init_dev(); 1009 spdk_bs_opts_init(&opts); 1010 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1011 1012 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1013 CU_ASSERT(g_bserrno == 0); 1014 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1015 bs = g_bs; 1016 1017 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1018 CU_ASSERT(g_bserrno == 0); 1019 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1020 blobid = g_blobid; 1021 1022 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1023 CU_ASSERT(g_bserrno == 0); 1024 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1025 blob = g_blob; 1026 1027 rc = spdk_blob_set_read_only(blob); 1028 CU_ASSERT(rc == 0); 1029 1030 CU_ASSERT(blob->data_ro == false); 1031 CU_ASSERT(blob->md_ro == false); 1032 1033 spdk_blob_sync_md(blob, bs_op_complete, NULL); 1034 1035 CU_ASSERT(blob->data_ro == true); 1036 CU_ASSERT(blob->md_ro == true); 1037 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1038 1039 spdk_blob_close(blob, blob_op_complete, NULL); 1040 CU_ASSERT(g_bserrno == 0); 1041 1042 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1043 CU_ASSERT(g_bserrno == 0); 1044 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1045 blob = g_blob; 1046 1047 CU_ASSERT(blob->data_ro == true); 1048 CU_ASSERT(blob->md_ro == true); 1049 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1050 1051 spdk_blob_close(blob, blob_op_complete, NULL); 1052 CU_ASSERT(g_bserrno == 0); 1053 1054 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1055 CU_ASSERT(g_bserrno == 0); 1056 g_bs = NULL; 1057 g_blob = NULL; 1058 g_blobid = 0; 1059 1060 /* Load an existing blob store */ 1061 dev = init_dev(); 1062 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1063 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1064 CU_ASSERT(g_bserrno == 0); 1065 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1066 1067 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1068 CU_ASSERT(g_bserrno == 0); 1069 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1070 blob = g_blob; 1071 1072 CU_ASSERT(blob->data_ro == true); 1073 CU_ASSERT(blob->md_ro == true); 1074 CU_ASSERT(blob->data_ro_flags & SPDK_BLOB_READ_ONLY); 1075 1076 spdk_blob_close(blob, blob_op_complete, NULL); 1077 CU_ASSERT(g_bserrno == 0); 1078 1079 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1080 CU_ASSERT(g_bserrno == 0); 1081 1082 } 1083 1084 static void 1085 channel_ops(void) 1086 { 1087 struct spdk_blob_store *bs; 1088 struct spdk_bs_dev *dev; 1089 struct spdk_io_channel *channel; 1090 1091 dev = init_dev(); 1092 1093 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1094 CU_ASSERT(g_bserrno == 0); 1095 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1096 bs = g_bs; 1097 1098 channel = spdk_bs_alloc_io_channel(bs); 1099 CU_ASSERT(channel != NULL); 1100 1101 spdk_bs_free_io_channel(channel); 1102 1103 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1104 CU_ASSERT(g_bserrno == 0); 1105 g_bs = NULL; 1106 } 1107 1108 static void 1109 blob_write(void) 1110 { 1111 struct spdk_blob_store *bs; 1112 struct spdk_bs_dev *dev; 1113 struct spdk_blob *blob; 1114 struct spdk_io_channel *channel; 1115 spdk_blob_id blobid; 1116 uint64_t pages_per_cluster; 1117 uint8_t payload[10 * 4096]; 1118 1119 dev = init_dev(); 1120 1121 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1122 CU_ASSERT(g_bserrno == 0); 1123 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1124 bs = g_bs; 1125 1126 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1127 1128 channel = spdk_bs_alloc_io_channel(bs); 1129 CU_ASSERT(channel != NULL); 1130 1131 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1132 CU_ASSERT(g_bserrno == 0); 1133 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1134 blobid = g_blobid; 1135 1136 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1137 CU_ASSERT(g_bserrno == 0); 1138 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1139 blob = g_blob; 1140 1141 /* Write to a blob with 0 size */ 1142 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1143 CU_ASSERT(g_bserrno == -EINVAL); 1144 1145 /* Resize the blob */ 1146 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1147 CU_ASSERT(g_bserrno == 0); 1148 1149 /* Confirm that write fails if blob is marked read-only. */ 1150 blob->data_ro = true; 1151 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1152 CU_ASSERT(g_bserrno == -EPERM); 1153 blob->data_ro = false; 1154 1155 /* Write to the blob */ 1156 spdk_blob_io_write(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1157 CU_ASSERT(g_bserrno == 0); 1158 1159 /* Write starting beyond the end */ 1160 spdk_blob_io_write(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1161 NULL); 1162 CU_ASSERT(g_bserrno == -EINVAL); 1163 1164 /* Write starting at a valid location but going off the end */ 1165 spdk_blob_io_write(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1166 blob_op_complete, NULL); 1167 CU_ASSERT(g_bserrno == -EINVAL); 1168 1169 spdk_blob_close(blob, blob_op_complete, NULL); 1170 CU_ASSERT(g_bserrno == 0); 1171 1172 spdk_bs_free_io_channel(channel); 1173 1174 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1175 CU_ASSERT(g_bserrno == 0); 1176 g_bs = NULL; 1177 } 1178 1179 static void 1180 blob_read(void) 1181 { 1182 struct spdk_blob_store *bs; 1183 struct spdk_bs_dev *dev; 1184 struct spdk_blob *blob; 1185 struct spdk_io_channel *channel; 1186 spdk_blob_id blobid; 1187 uint64_t pages_per_cluster; 1188 uint8_t payload[10 * 4096]; 1189 1190 dev = init_dev(); 1191 1192 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1193 CU_ASSERT(g_bserrno == 0); 1194 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1195 bs = g_bs; 1196 1197 pages_per_cluster = spdk_bs_get_cluster_size(bs) / spdk_bs_get_page_size(bs); 1198 1199 channel = spdk_bs_alloc_io_channel(bs); 1200 CU_ASSERT(channel != NULL); 1201 1202 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1203 CU_ASSERT(g_bserrno == 0); 1204 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1205 blobid = g_blobid; 1206 1207 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1208 CU_ASSERT(g_bserrno == 0); 1209 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1210 blob = g_blob; 1211 1212 /* Read from a blob with 0 size */ 1213 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1214 CU_ASSERT(g_bserrno == -EINVAL); 1215 1216 /* Resize the blob */ 1217 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 1218 CU_ASSERT(g_bserrno == 0); 1219 1220 /* Confirm that read passes if blob is marked read-only. */ 1221 blob->data_ro = true; 1222 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1223 CU_ASSERT(g_bserrno == 0); 1224 blob->data_ro = false; 1225 1226 /* Read from the blob */ 1227 spdk_blob_io_read(blob, channel, payload, 0, 1, blob_op_complete, NULL); 1228 CU_ASSERT(g_bserrno == 0); 1229 1230 /* Read starting beyond the end */ 1231 spdk_blob_io_read(blob, channel, payload, 5 * pages_per_cluster, 1, blob_op_complete, 1232 NULL); 1233 CU_ASSERT(g_bserrno == -EINVAL); 1234 1235 /* Read starting at a valid location but going off the end */ 1236 spdk_blob_io_read(blob, channel, payload, 4 * pages_per_cluster, pages_per_cluster + 1, 1237 blob_op_complete, NULL); 1238 CU_ASSERT(g_bserrno == -EINVAL); 1239 1240 spdk_blob_close(blob, blob_op_complete, NULL); 1241 CU_ASSERT(g_bserrno == 0); 1242 1243 spdk_bs_free_io_channel(channel); 1244 1245 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1246 CU_ASSERT(g_bserrno == 0); 1247 g_bs = NULL; 1248 } 1249 1250 static void 1251 blob_rw_verify(void) 1252 { 1253 struct spdk_blob_store *bs; 1254 struct spdk_bs_dev *dev; 1255 struct spdk_blob *blob; 1256 struct spdk_io_channel *channel; 1257 spdk_blob_id blobid; 1258 uint8_t payload_read[10 * 4096]; 1259 uint8_t payload_write[10 * 4096]; 1260 1261 dev = init_dev(); 1262 1263 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1264 CU_ASSERT(g_bserrno == 0); 1265 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1266 bs = g_bs; 1267 1268 channel = spdk_bs_alloc_io_channel(bs); 1269 CU_ASSERT(channel != NULL); 1270 1271 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1272 CU_ASSERT(g_bserrno == 0); 1273 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1274 blobid = g_blobid; 1275 1276 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1277 CU_ASSERT(g_bserrno == 0); 1278 CU_ASSERT(g_blob != NULL); 1279 blob = g_blob; 1280 1281 spdk_blob_resize(blob, 32, blob_op_complete, NULL); 1282 CU_ASSERT(g_bserrno == 0); 1283 1284 memset(payload_write, 0xE5, sizeof(payload_write)); 1285 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 1286 CU_ASSERT(g_bserrno == 0); 1287 1288 memset(payload_read, 0x00, sizeof(payload_read)); 1289 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 1290 CU_ASSERT(g_bserrno == 0); 1291 CU_ASSERT(memcmp(payload_write, payload_read, 4 * 4096) == 0); 1292 1293 spdk_blob_close(blob, blob_op_complete, NULL); 1294 CU_ASSERT(g_bserrno == 0); 1295 1296 spdk_bs_free_io_channel(channel); 1297 1298 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1299 CU_ASSERT(g_bserrno == 0); 1300 g_bs = NULL; 1301 } 1302 1303 static void 1304 blob_rw_verify_iov(void) 1305 { 1306 struct spdk_blob_store *bs; 1307 struct spdk_bs_dev *dev; 1308 struct spdk_blob *blob; 1309 struct spdk_io_channel *channel; 1310 spdk_blob_id blobid; 1311 uint8_t payload_read[10 * 4096]; 1312 uint8_t payload_write[10 * 4096]; 1313 struct iovec iov_read[3]; 1314 struct iovec iov_write[3]; 1315 void *buf; 1316 1317 dev = init_dev(); 1318 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1319 1320 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1321 CU_ASSERT(g_bserrno == 0); 1322 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1323 bs = g_bs; 1324 1325 channel = spdk_bs_alloc_io_channel(bs); 1326 CU_ASSERT(channel != NULL); 1327 1328 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1329 CU_ASSERT(g_bserrno == 0); 1330 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1331 blobid = g_blobid; 1332 1333 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1334 CU_ASSERT(g_bserrno == 0); 1335 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1336 blob = g_blob; 1337 1338 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1339 CU_ASSERT(g_bserrno == 0); 1340 1341 /* 1342 * Manually adjust the offset of the blob's second cluster. This allows 1343 * us to make sure that the readv/write code correctly accounts for I/O 1344 * that cross cluster boundaries. Start by asserting that the allocated 1345 * clusters are where we expect before modifying the second cluster. 1346 */ 1347 CU_ASSERT(blob->active.clusters[0] == 1 * 256); 1348 CU_ASSERT(blob->active.clusters[1] == 2 * 256); 1349 blob->active.clusters[1] = 3 * 256; 1350 1351 memset(payload_write, 0xE5, sizeof(payload_write)); 1352 iov_write[0].iov_base = payload_write; 1353 iov_write[0].iov_len = 1 * 4096; 1354 iov_write[1].iov_base = payload_write + 1 * 4096; 1355 iov_write[1].iov_len = 5 * 4096; 1356 iov_write[2].iov_base = payload_write + 6 * 4096; 1357 iov_write[2].iov_len = 4 * 4096; 1358 /* 1359 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1360 * will get written to the first cluster, the last 4 to the second cluster. 1361 */ 1362 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1363 CU_ASSERT(g_bserrno == 0); 1364 1365 memset(payload_read, 0xAA, sizeof(payload_read)); 1366 iov_read[0].iov_base = payload_read; 1367 iov_read[0].iov_len = 3 * 4096; 1368 iov_read[1].iov_base = payload_read + 3 * 4096; 1369 iov_read[1].iov_len = 4 * 4096; 1370 iov_read[2].iov_base = payload_read + 7 * 4096; 1371 iov_read[2].iov_len = 3 * 4096; 1372 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 1373 CU_ASSERT(g_bserrno == 0); 1374 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 1375 1376 buf = calloc(1, 256 * 4096); 1377 SPDK_CU_ASSERT_FATAL(buf != NULL); 1378 /* Check that cluster 2 on "disk" was not modified. */ 1379 CU_ASSERT(memcmp(buf, &g_dev_buffer[512 * 4096], 256 * 4096) == 0); 1380 free(buf); 1381 1382 spdk_blob_close(blob, blob_op_complete, NULL); 1383 CU_ASSERT(g_bserrno == 0); 1384 1385 spdk_bs_free_io_channel(channel); 1386 1387 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1388 CU_ASSERT(g_bserrno == 0); 1389 g_bs = NULL; 1390 } 1391 1392 static uint32_t 1393 bs_channel_get_req_count(struct spdk_io_channel *_channel) 1394 { 1395 struct spdk_bs_channel *channel = spdk_io_channel_get_ctx(_channel); 1396 struct spdk_bs_request_set *set; 1397 uint32_t count = 0; 1398 1399 TAILQ_FOREACH(set, &channel->reqs, link) { 1400 count++; 1401 } 1402 1403 return count; 1404 } 1405 1406 static void 1407 blob_rw_verify_iov_nomem(void) 1408 { 1409 struct spdk_blob_store *bs; 1410 struct spdk_bs_dev *dev; 1411 struct spdk_blob *blob; 1412 struct spdk_io_channel *channel; 1413 spdk_blob_id blobid; 1414 uint8_t payload_write[10 * 4096]; 1415 struct iovec iov_write[3]; 1416 uint32_t req_count; 1417 1418 dev = init_dev(); 1419 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1420 1421 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1422 CU_ASSERT(g_bserrno == 0); 1423 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1424 bs = g_bs; 1425 1426 channel = spdk_bs_alloc_io_channel(bs); 1427 CU_ASSERT(channel != NULL); 1428 1429 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1430 CU_ASSERT(g_bserrno == 0); 1431 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1432 blobid = g_blobid; 1433 1434 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1435 CU_ASSERT(g_bserrno == 0); 1436 CU_ASSERT(g_blob != NULL); 1437 blob = g_blob; 1438 1439 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1440 CU_ASSERT(g_bserrno == 0); 1441 1442 /* 1443 * Choose a page offset just before the cluster boundary. The first 6 pages of payload 1444 * will get written to the first cluster, the last 4 to the second cluster. 1445 */ 1446 iov_write[0].iov_base = payload_write; 1447 iov_write[0].iov_len = 1 * 4096; 1448 iov_write[1].iov_base = payload_write + 1 * 4096; 1449 iov_write[1].iov_len = 5 * 4096; 1450 iov_write[2].iov_base = payload_write + 6 * 4096; 1451 iov_write[2].iov_len = 4 * 4096; 1452 MOCK_SET(calloc, void *, NULL); 1453 req_count = bs_channel_get_req_count(channel); 1454 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 1455 CU_ASSERT(g_bserrno = -ENOMEM); 1456 CU_ASSERT(req_count == bs_channel_get_req_count(channel)); 1457 MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU); 1458 1459 spdk_blob_close(blob, blob_op_complete, NULL); 1460 CU_ASSERT(g_bserrno == 0); 1461 1462 spdk_bs_free_io_channel(channel); 1463 1464 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1465 CU_ASSERT(g_bserrno == 0); 1466 g_bs = NULL; 1467 } 1468 1469 static void 1470 blob_rw_iov_read_only(void) 1471 { 1472 struct spdk_blob_store *bs; 1473 struct spdk_bs_dev *dev; 1474 struct spdk_blob *blob; 1475 struct spdk_io_channel *channel; 1476 spdk_blob_id blobid; 1477 uint8_t payload_read[4096]; 1478 uint8_t payload_write[4096]; 1479 struct iovec iov_read; 1480 struct iovec iov_write; 1481 1482 dev = init_dev(); 1483 memset(g_dev_buffer, 0, DEV_BUFFER_SIZE); 1484 1485 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1486 CU_ASSERT(g_bserrno == 0); 1487 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1488 bs = g_bs; 1489 1490 channel = spdk_bs_alloc_io_channel(bs); 1491 CU_ASSERT(channel != NULL); 1492 1493 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1494 CU_ASSERT(g_bserrno == 0); 1495 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1496 blobid = g_blobid; 1497 1498 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1499 CU_ASSERT(g_bserrno == 0); 1500 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1501 blob = g_blob; 1502 1503 spdk_blob_resize(blob, 2, blob_op_complete, NULL); 1504 CU_ASSERT(g_bserrno == 0); 1505 1506 /* Verify that writev failed if read_only flag is set. */ 1507 blob->data_ro = true; 1508 iov_write.iov_base = payload_write; 1509 iov_write.iov_len = sizeof(payload_write); 1510 spdk_blob_io_writev(blob, channel, &iov_write, 1, 0, 1, blob_op_complete, NULL); 1511 CU_ASSERT(g_bserrno == -EPERM); 1512 1513 /* Verify that reads pass if data_ro flag is set. */ 1514 iov_read.iov_base = payload_read; 1515 iov_read.iov_len = sizeof(payload_read); 1516 spdk_blob_io_readv(blob, channel, &iov_read, 1, 0, 1, blob_op_complete, NULL); 1517 CU_ASSERT(g_bserrno == 0); 1518 1519 spdk_blob_close(blob, blob_op_complete, NULL); 1520 CU_ASSERT(g_bserrno == 0); 1521 1522 spdk_bs_free_io_channel(channel); 1523 1524 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1525 CU_ASSERT(g_bserrno == 0); 1526 g_bs = NULL; 1527 } 1528 1529 static void 1530 blob_unmap(void) 1531 { 1532 struct spdk_blob_store *bs; 1533 struct spdk_bs_dev *dev; 1534 struct spdk_blob *blob; 1535 struct spdk_io_channel *channel; 1536 spdk_blob_id blobid; 1537 struct spdk_blob_opts opts; 1538 uint8_t payload[4096]; 1539 int i; 1540 1541 dev = init_dev(); 1542 1543 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1544 CU_ASSERT(g_bserrno == 0); 1545 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1546 bs = g_bs; 1547 1548 channel = spdk_bs_alloc_io_channel(bs); 1549 CU_ASSERT(channel != NULL); 1550 1551 spdk_blob_opts_init(&opts); 1552 opts.num_clusters = 10; 1553 1554 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 1555 CU_ASSERT(g_bserrno == 0); 1556 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1557 blobid = g_blobid; 1558 1559 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1560 CU_ASSERT(g_bserrno == 0); 1561 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1562 blob = g_blob; 1563 1564 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1565 CU_ASSERT(g_bserrno == 0); 1566 1567 memset(payload, 0, sizeof(payload)); 1568 payload[0] = 0xFF; 1569 1570 /* 1571 * Set first byte of every cluster to 0xFF. 1572 * First cluster on device is reserved so let's start from cluster number 1 1573 */ 1574 for (i = 1; i < 11; i++) { 1575 g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] = 0xFF; 1576 } 1577 1578 /* Confirm writes */ 1579 for (i = 0; i < 10; i++) { 1580 payload[0] = 0; 1581 spdk_blob_io_read(blob, channel, &payload, i * SPDK_BLOB_OPTS_CLUSTER_SZ / 4096, 1, 1582 blob_op_complete, NULL); 1583 CU_ASSERT(g_bserrno == 0); 1584 CU_ASSERT(payload[0] == 0xFF); 1585 } 1586 1587 /* Mark some clusters as unallocated */ 1588 blob->active.clusters[1] = 0; 1589 blob->active.clusters[2] = 0; 1590 blob->active.clusters[3] = 0; 1591 blob->active.clusters[6] = 0; 1592 blob->active.clusters[8] = 0; 1593 1594 /* Unmap clusters by resizing to 0 */ 1595 spdk_blob_resize(blob, 0, blob_op_complete, NULL); 1596 CU_ASSERT(g_bserrno == 0); 1597 1598 spdk_blob_sync_md(blob, blob_op_complete, NULL); 1599 CU_ASSERT(g_bserrno == 0); 1600 1601 /* Confirm that only 'allocated' clusters were unmaped */ 1602 for (i = 1; i < 11; i++) { 1603 switch (i) { 1604 case 2: 1605 case 3: 1606 case 4: 1607 case 7: 1608 case 9: 1609 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0xFF); 1610 break; 1611 default: 1612 CU_ASSERT(g_dev_buffer[i * SPDK_BLOB_OPTS_CLUSTER_SZ] == 0); 1613 break; 1614 } 1615 } 1616 1617 spdk_blob_close(blob, blob_op_complete, NULL); 1618 CU_ASSERT(g_bserrno == 0); 1619 1620 spdk_bs_free_io_channel(channel); 1621 1622 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1623 CU_ASSERT(g_bserrno == 0); 1624 g_bs = NULL; 1625 } 1626 1627 1628 static void 1629 blob_iter(void) 1630 { 1631 struct spdk_blob_store *bs; 1632 struct spdk_bs_dev *dev; 1633 struct spdk_blob *blob; 1634 spdk_blob_id blobid; 1635 1636 dev = init_dev(); 1637 1638 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1639 CU_ASSERT(g_bserrno == 0); 1640 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1641 bs = g_bs; 1642 1643 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1644 CU_ASSERT(g_blob == NULL); 1645 CU_ASSERT(g_bserrno == -ENOENT); 1646 1647 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1648 CU_ASSERT(g_bserrno == 0); 1649 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1650 blobid = g_blobid; 1651 1652 spdk_bs_iter_first(bs, blob_op_with_handle_complete, NULL); 1653 CU_ASSERT(g_blob != NULL); 1654 CU_ASSERT(g_bserrno == 0); 1655 blob = g_blob; 1656 CU_ASSERT(spdk_blob_get_id(blob) == blobid); 1657 1658 spdk_bs_iter_next(bs, blob, blob_op_with_handle_complete, NULL); 1659 CU_ASSERT(g_blob == NULL); 1660 CU_ASSERT(g_bserrno == -ENOENT); 1661 1662 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1663 CU_ASSERT(g_bserrno == 0); 1664 g_bs = NULL; 1665 } 1666 1667 static void 1668 blob_xattr(void) 1669 { 1670 struct spdk_blob_store *bs; 1671 struct spdk_bs_dev *dev; 1672 struct spdk_blob *blob; 1673 spdk_blob_id blobid; 1674 uint64_t length; 1675 int rc; 1676 const char *name1, *name2; 1677 const void *value; 1678 size_t value_len; 1679 struct spdk_xattr_names *names; 1680 1681 dev = init_dev(); 1682 1683 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1684 CU_ASSERT(g_bserrno == 0); 1685 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1686 bs = g_bs; 1687 1688 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 1689 CU_ASSERT(g_bserrno == 0); 1690 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1691 blobid = g_blobid; 1692 1693 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1694 CU_ASSERT(g_bserrno == 0); 1695 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1696 blob = g_blob; 1697 1698 /* Test that set_xattr fails if md_ro flag is set. */ 1699 blob->md_ro = true; 1700 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1701 CU_ASSERT(rc == -EPERM); 1702 1703 blob->md_ro = false; 1704 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1705 CU_ASSERT(rc == 0); 1706 1707 length = 2345; 1708 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1709 CU_ASSERT(rc == 0); 1710 1711 /* Overwrite "length" xattr. */ 1712 length = 3456; 1713 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1714 CU_ASSERT(rc == 0); 1715 1716 /* get_xattr should still work even if md_ro flag is set. */ 1717 value = NULL; 1718 blob->md_ro = true; 1719 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1720 CU_ASSERT(rc == 0); 1721 SPDK_CU_ASSERT_FATAL(value != NULL); 1722 CU_ASSERT(*(uint64_t *)value == length); 1723 CU_ASSERT(value_len == 8); 1724 blob->md_ro = false; 1725 1726 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1727 CU_ASSERT(rc == -ENOENT); 1728 1729 names = NULL; 1730 rc = spdk_blob_get_xattr_names(blob, &names); 1731 CU_ASSERT(rc == 0); 1732 SPDK_CU_ASSERT_FATAL(names != NULL); 1733 CU_ASSERT(spdk_xattr_names_get_count(names) == 2); 1734 name1 = spdk_xattr_names_get_name(names, 0); 1735 SPDK_CU_ASSERT_FATAL(name1 != NULL); 1736 CU_ASSERT(!strcmp(name1, "name") || !strcmp(name1, "length")); 1737 name2 = spdk_xattr_names_get_name(names, 1); 1738 SPDK_CU_ASSERT_FATAL(name2 != NULL); 1739 CU_ASSERT(!strcmp(name2, "name") || !strcmp(name2, "length")); 1740 CU_ASSERT(strcmp(name1, name2)); 1741 spdk_xattr_names_free(names); 1742 1743 /* Confirm that remove_xattr fails if md_ro is set to true. */ 1744 blob->md_ro = true; 1745 rc = spdk_blob_remove_xattr(blob, "name"); 1746 CU_ASSERT(rc == -EPERM); 1747 1748 blob->md_ro = false; 1749 rc = spdk_blob_remove_xattr(blob, "name"); 1750 CU_ASSERT(rc == 0); 1751 1752 rc = spdk_blob_remove_xattr(blob, "foobar"); 1753 CU_ASSERT(rc == -ENOENT); 1754 1755 /* Set internal xattr */ 1756 length = 7898; 1757 rc = _spdk_blob_set_xattr(blob, "internal", &length, sizeof(length), true); 1758 CU_ASSERT(rc == 0); 1759 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1760 CU_ASSERT(rc == 0); 1761 CU_ASSERT(*(uint64_t *)value == length); 1762 /* try to get public xattr with same name */ 1763 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1764 CU_ASSERT(rc != 0); 1765 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, false); 1766 CU_ASSERT(rc != 0); 1767 /* Check if SPDK_BLOB_INTERNAL_XATTR is set */ 1768 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 1769 SPDK_BLOB_INTERNAL_XATTR) 1770 1771 spdk_blob_close(blob, blob_op_complete, NULL); 1772 1773 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1774 1775 /* Check if xattrs are persisted */ 1776 dev = init_dev(); 1777 1778 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1779 CU_ASSERT(g_bserrno == 0); 1780 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1781 1782 bs = g_bs; 1783 1784 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 1785 CU_ASSERT(g_bserrno == 0); 1786 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 1787 blob = g_blob; 1788 1789 rc = _spdk_blob_get_xattr_value(blob, "internal", &value, &value_len, true); 1790 CU_ASSERT(rc == 0); 1791 CU_ASSERT(*(uint64_t *)value == length); 1792 1793 /* try to get internal xattr trough public call */ 1794 rc = spdk_blob_get_xattr_value(blob, "internal", &value, &value_len); 1795 CU_ASSERT(rc != 0); 1796 1797 rc = _spdk_blob_remove_xattr(blob, "internal", true); 1798 CU_ASSERT(rc == 0); 1799 1800 CU_ASSERT((blob->invalid_flags & SPDK_BLOB_INTERNAL_XATTR) == 0); 1801 1802 CU_ASSERT(g_bserrno == 0); 1803 g_bs = NULL; 1804 } 1805 1806 static void 1807 bs_load(void) 1808 { 1809 struct spdk_bs_dev *dev; 1810 spdk_blob_id blobid; 1811 struct spdk_blob *blob; 1812 struct spdk_bs_super_block *super_block; 1813 uint64_t length; 1814 int rc; 1815 const void *value; 1816 size_t value_len; 1817 struct spdk_bs_opts opts; 1818 1819 dev = init_dev(); 1820 spdk_bs_opts_init(&opts); 1821 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1822 1823 /* Initialize a new blob store */ 1824 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1825 CU_ASSERT(g_bserrno == 0); 1826 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1827 1828 /* Try to open a blobid that does not exist */ 1829 spdk_bs_open_blob(g_bs, 0, blob_op_with_handle_complete, NULL); 1830 CU_ASSERT(g_bserrno == -ENOENT); 1831 CU_ASSERT(g_blob == NULL); 1832 1833 /* Create a blob */ 1834 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 1835 CU_ASSERT(g_bserrno == 0); 1836 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 1837 blobid = g_blobid; 1838 1839 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1840 CU_ASSERT(g_bserrno == 0); 1841 CU_ASSERT(g_blob != NULL); 1842 blob = g_blob; 1843 1844 /* Try again to open valid blob but without the upper bit set */ 1845 spdk_bs_open_blob(g_bs, blobid & 0xFFFFFFFF, blob_op_with_handle_complete, NULL); 1846 CU_ASSERT(g_bserrno == -ENOENT); 1847 CU_ASSERT(g_blob == NULL); 1848 1849 /* Set some xattrs */ 1850 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 1851 CU_ASSERT(rc == 0); 1852 1853 length = 2345; 1854 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 1855 CU_ASSERT(rc == 0); 1856 1857 /* Resize the blob */ 1858 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 1859 CU_ASSERT(g_bserrno == 0); 1860 1861 spdk_blob_close(blob, blob_op_complete, NULL); 1862 CU_ASSERT(g_bserrno == 0); 1863 blob = NULL; 1864 g_blob = NULL; 1865 g_blobid = SPDK_BLOBID_INVALID; 1866 1867 /* Unload the blob store */ 1868 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1869 CU_ASSERT(g_bserrno == 0); 1870 g_bs = NULL; 1871 g_blob = NULL; 1872 g_blobid = 0; 1873 1874 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1875 CU_ASSERT(super_block->clean == 1); 1876 1877 /* Load should fail for device with an unsupported blocklen */ 1878 dev = init_dev(); 1879 dev->blocklen = SPDK_BS_PAGE_SIZE * 2; 1880 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 1881 CU_ASSERT(g_bserrno == -EINVAL); 1882 1883 /* Load should when max_md_ops is set to zero */ 1884 dev = init_dev(); 1885 spdk_bs_opts_init(&opts); 1886 opts.max_md_ops = 0; 1887 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1888 CU_ASSERT(g_bserrno == -EINVAL); 1889 1890 /* Load should when max_channel_ops is set to zero */ 1891 dev = init_dev(); 1892 spdk_bs_opts_init(&opts); 1893 opts.max_channel_ops = 0; 1894 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1895 CU_ASSERT(g_bserrno == -EINVAL); 1896 1897 /* Load an existing blob store */ 1898 dev = init_dev(); 1899 spdk_bs_opts_init(&opts); 1900 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1901 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1902 CU_ASSERT(g_bserrno == 0); 1903 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1904 1905 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 1906 CU_ASSERT(super_block->clean == 0); 1907 1908 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 1909 CU_ASSERT(g_bserrno == 0); 1910 CU_ASSERT(g_blob != NULL); 1911 blob = g_blob; 1912 1913 /* Get the xattrs */ 1914 value = NULL; 1915 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 1916 CU_ASSERT(rc == 0); 1917 SPDK_CU_ASSERT_FATAL(value != NULL); 1918 CU_ASSERT(*(uint64_t *)value == length); 1919 CU_ASSERT(value_len == 8); 1920 1921 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 1922 CU_ASSERT(rc == -ENOENT); 1923 1924 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 1925 1926 spdk_blob_close(blob, blob_op_complete, NULL); 1927 CU_ASSERT(g_bserrno == 0); 1928 blob = NULL; 1929 g_blob = NULL; 1930 g_blobid = SPDK_BLOBID_INVALID; 1931 1932 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1933 CU_ASSERT(g_bserrno == 0); 1934 g_bs = NULL; 1935 } 1936 1937 static void 1938 bs_type(void) 1939 { 1940 struct spdk_bs_dev *dev; 1941 struct spdk_bs_opts opts; 1942 1943 dev = init_dev(); 1944 spdk_bs_opts_init(&opts); 1945 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 1946 1947 /* Initialize a new blob store */ 1948 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 1949 CU_ASSERT(g_bserrno == 0); 1950 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1951 1952 /* Unload the blob store */ 1953 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1954 CU_ASSERT(g_bserrno == 0); 1955 g_bs = NULL; 1956 g_blob = NULL; 1957 g_blobid = 0; 1958 1959 /* Load non existing blobstore type */ 1960 dev = init_dev(); 1961 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1962 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1963 CU_ASSERT(g_bserrno != 0); 1964 1965 /* Load with empty blobstore type */ 1966 dev = init_dev(); 1967 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 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 /* Initialize a new blob store with empty bstype */ 1976 dev = init_dev(); 1977 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1978 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 1979 CU_ASSERT(g_bserrno == 0); 1980 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 1981 1982 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1983 CU_ASSERT(g_bserrno == 0); 1984 g_bs = NULL; 1985 1986 /* Load non existing blobstore type */ 1987 dev = init_dev(); 1988 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "NONEXISTING"); 1989 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1990 CU_ASSERT(g_bserrno != 0); 1991 1992 /* Load with empty blobstore type */ 1993 dev = init_dev(); 1994 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 1995 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 1996 CU_ASSERT(g_bserrno == 0); 1997 1998 spdk_bs_unload(g_bs, bs_op_complete, NULL); 1999 CU_ASSERT(g_bserrno == 0); 2000 g_bs = NULL; 2001 } 2002 2003 static void 2004 bs_super_block(void) 2005 { 2006 struct spdk_bs_dev *dev; 2007 struct spdk_bs_super_block *super_block; 2008 struct spdk_bs_opts opts; 2009 struct spdk_bs_super_block_ver1 super_block_v1; 2010 2011 dev = init_dev(); 2012 spdk_bs_opts_init(&opts); 2013 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 2014 2015 /* Initialize a new blob store */ 2016 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2017 CU_ASSERT(g_bserrno == 0); 2018 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2019 2020 /* Unload the blob store */ 2021 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2022 CU_ASSERT(g_bserrno == 0); 2023 g_bs = NULL; 2024 g_blob = NULL; 2025 g_blobid = 0; 2026 2027 /* Load an existing blob store with version newer than supported */ 2028 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2029 super_block->version++; 2030 2031 dev = init_dev(); 2032 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2033 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2034 CU_ASSERT(g_bserrno != 0); 2035 2036 /* Create a new blob store with super block version 1 */ 2037 dev = init_dev(); 2038 super_block_v1.version = 1; 2039 memcpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature)); 2040 super_block_v1.length = 0x1000; 2041 super_block_v1.clean = 1; 2042 super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF; 2043 super_block_v1.cluster_size = 0x100000; 2044 super_block_v1.used_page_mask_start = 0x01; 2045 super_block_v1.used_page_mask_len = 0x01; 2046 super_block_v1.used_cluster_mask_start = 0x02; 2047 super_block_v1.used_cluster_mask_len = 0x01; 2048 super_block_v1.md_start = 0x03; 2049 super_block_v1.md_len = 0x40; 2050 memset(super_block_v1.reserved, 0, 4036); 2051 super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1); 2052 memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1)); 2053 2054 memset(opts.bstype.bstype, 0, sizeof(opts.bstype.bstype)); 2055 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2056 CU_ASSERT(g_bserrno == 0); 2057 2058 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2059 CU_ASSERT(g_bserrno == 0); 2060 g_bs = NULL; 2061 } 2062 2063 /* 2064 * Create a blobstore and then unload it. 2065 */ 2066 static void 2067 bs_unload(void) 2068 { 2069 struct spdk_bs_dev *dev; 2070 struct spdk_blob_store *bs; 2071 spdk_blob_id blobid; 2072 struct spdk_blob *blob; 2073 2074 dev = init_dev(); 2075 2076 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2077 CU_ASSERT(g_bserrno == 0); 2078 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2079 bs = g_bs; 2080 2081 /* Create a blob and open it. */ 2082 g_bserrno = -1; 2083 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2084 CU_ASSERT(g_bserrno == 0); 2085 CU_ASSERT(g_blobid > 0); 2086 blobid = g_blobid; 2087 2088 g_bserrno = -1; 2089 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2090 CU_ASSERT(g_bserrno == 0); 2091 CU_ASSERT(g_blob != NULL); 2092 blob = g_blob; 2093 2094 /* Try to unload blobstore, should fail with open blob */ 2095 g_bserrno = -1; 2096 spdk_bs_unload(bs, bs_op_complete, NULL); 2097 CU_ASSERT(g_bserrno == -EBUSY); 2098 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2099 2100 /* Close the blob, then successfully unload blobstore */ 2101 g_bserrno = -1; 2102 spdk_blob_close(blob, blob_op_complete, NULL); 2103 CU_ASSERT(g_bserrno == 0); 2104 2105 g_bserrno = -1; 2106 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2107 CU_ASSERT(g_bserrno == 0); 2108 g_bs = NULL; 2109 } 2110 2111 /* 2112 * Create a blobstore with a cluster size different than the default, and ensure it is 2113 * persisted. 2114 */ 2115 static void 2116 bs_cluster_sz(void) 2117 { 2118 struct spdk_bs_dev *dev; 2119 struct spdk_bs_opts opts; 2120 uint32_t cluster_sz; 2121 2122 /* Set cluster size to zero */ 2123 dev = init_dev(); 2124 spdk_bs_opts_init(&opts); 2125 opts.cluster_sz = 0; 2126 2127 /* Initialize a new blob store */ 2128 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2129 CU_ASSERT(g_bserrno == -EINVAL); 2130 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2131 2132 /* 2133 * Set cluster size to blobstore page size, 2134 * to work it is required to be at least twice the blobstore page size. 2135 */ 2136 dev = init_dev(); 2137 spdk_bs_opts_init(&opts); 2138 opts.cluster_sz = SPDK_BS_PAGE_SIZE; 2139 2140 /* Initialize a new blob store */ 2141 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2142 CU_ASSERT(g_bserrno == -ENOMEM); 2143 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2144 2145 /* 2146 * Set cluster size to lower than page size, 2147 * to work it is required to be at least twice the blobstore page size. 2148 */ 2149 dev = init_dev(); 2150 spdk_bs_opts_init(&opts); 2151 opts.cluster_sz = SPDK_BS_PAGE_SIZE - 1; 2152 2153 /* Initialize a new blob store */ 2154 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2155 CU_ASSERT(g_bserrno == -ENOMEM); 2156 SPDK_CU_ASSERT_FATAL(g_bs == NULL); 2157 2158 /* Set cluster size to twice the default */ 2159 dev = init_dev(); 2160 spdk_bs_opts_init(&opts); 2161 opts.cluster_sz *= 2; 2162 cluster_sz = opts.cluster_sz; 2163 2164 /* Initialize a new blob store */ 2165 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2166 CU_ASSERT(g_bserrno == 0); 2167 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2168 2169 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2170 2171 /* Unload the blob store */ 2172 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2173 CU_ASSERT(g_bserrno == 0); 2174 g_bs = NULL; 2175 g_blob = NULL; 2176 g_blobid = 0; 2177 2178 dev = init_dev(); 2179 /* Load an existing blob store */ 2180 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2181 CU_ASSERT(g_bserrno == 0); 2182 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2183 2184 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2185 2186 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2187 CU_ASSERT(g_bserrno == 0); 2188 g_bs = NULL; 2189 } 2190 2191 /* 2192 * Create a blobstore, reload it and ensure total usable cluster count 2193 * stays the same. 2194 */ 2195 static void 2196 bs_usable_clusters(void) 2197 { 2198 struct spdk_bs_dev *dev; 2199 struct spdk_bs_opts opts; 2200 uint32_t clusters; 2201 int i; 2202 2203 /* Init blobstore */ 2204 dev = init_dev(); 2205 spdk_bs_opts_init(&opts); 2206 2207 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2208 CU_ASSERT(g_bserrno == 0); 2209 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2210 2211 clusters = spdk_bs_total_data_cluster_count(g_bs); 2212 2213 /* Unload the blob store */ 2214 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2215 CU_ASSERT(g_bserrno == 0); 2216 g_bs = NULL; 2217 2218 dev = init_dev(); 2219 /* Load an existing blob store */ 2220 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2221 CU_ASSERT(g_bserrno == 0); 2222 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2223 2224 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2225 2226 /* Create and resize blobs to make sure that useable cluster count won't change */ 2227 for (i = 0; i < 4; i++) { 2228 g_bserrno = -1; 2229 g_blobid = SPDK_BLOBID_INVALID; 2230 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2231 CU_ASSERT(g_bserrno == 0); 2232 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2233 2234 g_bserrno = -1; 2235 g_blob = NULL; 2236 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 2237 CU_ASSERT(g_bserrno == 0); 2238 CU_ASSERT(g_blob != NULL); 2239 2240 spdk_blob_resize(g_blob, 10, blob_op_complete, NULL); 2241 CU_ASSERT(g_bserrno == 0); 2242 2243 g_bserrno = -1; 2244 spdk_blob_close(g_blob, blob_op_complete, NULL); 2245 CU_ASSERT(g_bserrno == 0); 2246 2247 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2248 } 2249 2250 /* Reload the blob store to make sure that nothing changed */ 2251 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2252 CU_ASSERT(g_bserrno == 0); 2253 g_bs = NULL; 2254 2255 dev = init_dev(); 2256 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2257 CU_ASSERT(g_bserrno == 0); 2258 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2259 2260 CU_ASSERT(spdk_bs_total_data_cluster_count(g_bs) == clusters); 2261 2262 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2263 CU_ASSERT(g_bserrno == 0); 2264 g_bs = NULL; 2265 } 2266 2267 /* 2268 * Test resizing of the metadata blob. This requires creating enough blobs 2269 * so that one cluster is not enough to fit the metadata for those blobs. 2270 * To induce this condition to happen more quickly, we reduce the cluster 2271 * size to 16KB, which means only 4 4KB blob metadata pages can fit. 2272 */ 2273 static void 2274 bs_resize_md(void) 2275 { 2276 const int CLUSTER_PAGE_COUNT = 4; 2277 const int NUM_BLOBS = CLUSTER_PAGE_COUNT * 4; 2278 struct spdk_bs_dev *dev; 2279 struct spdk_bs_opts opts; 2280 uint32_t cluster_sz; 2281 spdk_blob_id blobids[NUM_BLOBS]; 2282 int i; 2283 2284 2285 dev = init_dev(); 2286 spdk_bs_opts_init(&opts); 2287 opts.cluster_sz = CLUSTER_PAGE_COUNT * 4096; 2288 cluster_sz = opts.cluster_sz; 2289 2290 /* Initialize a new blob store */ 2291 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2292 CU_ASSERT(g_bserrno == 0); 2293 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2294 2295 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2296 2297 for (i = 0; i < NUM_BLOBS; i++) { 2298 g_bserrno = -1; 2299 g_blobid = SPDK_BLOBID_INVALID; 2300 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2301 CU_ASSERT(g_bserrno == 0); 2302 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2303 blobids[i] = g_blobid; 2304 } 2305 2306 /* Unload the blob store */ 2307 g_bserrno = -1; 2308 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2309 CU_ASSERT(g_bserrno == 0); 2310 2311 /* Load an existing blob store */ 2312 g_bserrno = -1; 2313 g_bs = NULL; 2314 dev = init_dev(); 2315 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2316 CU_ASSERT(g_bserrno == 0); 2317 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2318 2319 CU_ASSERT(spdk_bs_get_cluster_size(g_bs) == cluster_sz); 2320 2321 for (i = 0; i < NUM_BLOBS; i++) { 2322 g_bserrno = -1; 2323 g_blob = NULL; 2324 spdk_bs_open_blob(g_bs, blobids[i], blob_op_with_handle_complete, NULL); 2325 CU_ASSERT(g_bserrno == 0); 2326 CU_ASSERT(g_blob != NULL); 2327 g_bserrno = -1; 2328 spdk_blob_close(g_blob, blob_op_complete, NULL); 2329 CU_ASSERT(g_bserrno == 0); 2330 } 2331 2332 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2333 CU_ASSERT(g_bserrno == 0); 2334 g_bs = NULL; 2335 } 2336 2337 static void 2338 bs_destroy(void) 2339 { 2340 struct spdk_bs_dev *dev; 2341 struct spdk_bs_opts opts; 2342 2343 /* Initialize a new blob store */ 2344 dev = init_dev(); 2345 spdk_bs_opts_init(&opts); 2346 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2347 CU_ASSERT(g_bserrno == 0); 2348 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2349 2350 /* Destroy the blob store */ 2351 g_bserrno = -1; 2352 spdk_bs_destroy(g_bs, bs_op_complete, NULL); 2353 CU_ASSERT(g_bserrno == 0); 2354 2355 /* Loading an non-existent blob store should fail. */ 2356 g_bs = NULL; 2357 dev = init_dev(); 2358 2359 g_bserrno = 0; 2360 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2361 CU_ASSERT(g_bserrno != 0); 2362 } 2363 2364 /* Try to hit all of the corner cases associated with serializing 2365 * a blob to disk 2366 */ 2367 static void 2368 blob_serialize(void) 2369 { 2370 struct spdk_bs_dev *dev; 2371 struct spdk_bs_opts opts; 2372 struct spdk_blob_store *bs; 2373 spdk_blob_id blobid[2]; 2374 struct spdk_blob *blob[2]; 2375 uint64_t i; 2376 char *value; 2377 int rc; 2378 2379 dev = init_dev(); 2380 2381 /* Initialize a new blobstore with very small clusters */ 2382 spdk_bs_opts_init(&opts); 2383 opts.cluster_sz = dev->blocklen * 8; 2384 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2385 CU_ASSERT(g_bserrno == 0); 2386 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2387 bs = g_bs; 2388 2389 /* Create and open two blobs */ 2390 for (i = 0; i < 2; i++) { 2391 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2392 CU_ASSERT(g_bserrno == 0); 2393 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2394 blobid[i] = g_blobid; 2395 2396 /* Open a blob */ 2397 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2398 CU_ASSERT(g_bserrno == 0); 2399 CU_ASSERT(g_blob != NULL); 2400 blob[i] = g_blob; 2401 2402 /* Set a fairly large xattr on both blobs to eat up 2403 * metadata space 2404 */ 2405 value = calloc(dev->blocklen - 64, sizeof(char)); 2406 SPDK_CU_ASSERT_FATAL(value != NULL); 2407 memset(value, i, dev->blocklen / 2); 2408 rc = spdk_blob_set_xattr(blob[i], "name", value, dev->blocklen - 64); 2409 CU_ASSERT(rc == 0); 2410 free(value); 2411 } 2412 2413 /* Resize the blobs, alternating 1 cluster at a time. 2414 * This thwarts run length encoding and will cause spill 2415 * over of the extents. 2416 */ 2417 for (i = 0; i < 6; i++) { 2418 spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL); 2419 CU_ASSERT(g_bserrno == 0); 2420 } 2421 2422 for (i = 0; i < 2; i++) { 2423 spdk_blob_sync_md(blob[i], blob_op_complete, NULL); 2424 CU_ASSERT(g_bserrno == 0); 2425 } 2426 2427 /* Close the blobs */ 2428 for (i = 0; i < 2; i++) { 2429 spdk_blob_close(blob[i], blob_op_complete, NULL); 2430 CU_ASSERT(g_bserrno == 0); 2431 } 2432 2433 /* Unload the blobstore */ 2434 spdk_bs_unload(bs, bs_op_complete, NULL); 2435 CU_ASSERT(g_bserrno == 0); 2436 g_bs = NULL; 2437 g_blob = NULL; 2438 g_blobid = 0; 2439 bs = NULL; 2440 2441 dev = init_dev(); 2442 /* Load an existing blob store */ 2443 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2444 CU_ASSERT(g_bserrno == 0); 2445 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2446 bs = g_bs; 2447 2448 for (i = 0; i < 2; i++) { 2449 blob[i] = NULL; 2450 2451 spdk_bs_open_blob(bs, blobid[i], blob_op_with_handle_complete, NULL); 2452 CU_ASSERT(g_bserrno == 0); 2453 CU_ASSERT(g_blob != NULL); 2454 blob[i] = g_blob; 2455 2456 CU_ASSERT(spdk_blob_get_num_clusters(blob[i]) == 3); 2457 2458 spdk_blob_close(blob[i], blob_op_complete, NULL); 2459 CU_ASSERT(g_bserrno == 0); 2460 } 2461 2462 spdk_bs_unload(bs, bs_op_complete, NULL); 2463 CU_ASSERT(g_bserrno == 0); 2464 g_bs = NULL; 2465 } 2466 2467 static void 2468 blob_crc(void) 2469 { 2470 struct spdk_blob_store *bs; 2471 struct spdk_bs_dev *dev; 2472 struct spdk_blob *blob; 2473 spdk_blob_id blobid; 2474 uint32_t page_num; 2475 int index; 2476 struct spdk_blob_md_page *page; 2477 2478 dev = init_dev(); 2479 2480 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2481 CU_ASSERT(g_bserrno == 0); 2482 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2483 bs = g_bs; 2484 2485 spdk_bs_create_blob(bs, blob_op_with_id_complete, NULL); 2486 CU_ASSERT(g_bserrno == 0); 2487 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2488 blobid = g_blobid; 2489 2490 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2491 CU_ASSERT(g_bserrno == 0); 2492 CU_ASSERT(g_blob != NULL); 2493 blob = g_blob; 2494 2495 spdk_blob_close(blob, blob_op_complete, NULL); 2496 CU_ASSERT(g_bserrno == 0); 2497 2498 page_num = _spdk_bs_blobid_to_page(blobid); 2499 index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num); 2500 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2501 page->crc = 0; 2502 2503 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 2504 CU_ASSERT(g_bserrno == -EINVAL); 2505 CU_ASSERT(g_blob == NULL); 2506 g_bserrno = 0; 2507 2508 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 2509 CU_ASSERT(g_bserrno == -EINVAL); 2510 2511 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2512 CU_ASSERT(g_bserrno == 0); 2513 g_bs = NULL; 2514 } 2515 2516 static void 2517 super_block_crc(void) 2518 { 2519 struct spdk_bs_dev *dev; 2520 struct spdk_bs_super_block *super_block; 2521 struct spdk_bs_opts opts; 2522 2523 dev = init_dev(); 2524 spdk_bs_opts_init(&opts); 2525 2526 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2527 CU_ASSERT(g_bserrno == 0); 2528 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2529 2530 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2531 CU_ASSERT(g_bserrno == 0); 2532 g_bs = NULL; 2533 2534 super_block = (struct spdk_bs_super_block *)g_dev_buffer; 2535 super_block->crc = 0; 2536 dev = init_dev(); 2537 2538 /* Load an existing blob store */ 2539 g_bserrno = 0; 2540 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2541 CU_ASSERT(g_bserrno == -EILSEQ); 2542 } 2543 2544 /* For blob dirty shutdown test case we do the following sub-test cases: 2545 * 1 Initialize new blob store and create 1 super blob with some xattrs, then we 2546 * dirty shutdown and reload the blob store and verify the xattrs. 2547 * 2 Resize the blob from 10 clusters to 20 clusters and then dirty shutdown, 2548 * reload the blob store and verify the clusters number. 2549 * 3 Create the second blob and then dirty shutdown, reload the blob store 2550 * and verify the second blob. 2551 * 4 Delete the second blob and then dirty shutdown, reload the blob store 2552 * and verify the second blob is invalid. 2553 * 5 Create the second blob again and also create the third blob, modify the 2554 * md of second blob which makes the md invalid, and then dirty shutdown, 2555 * reload the blob store verify the second blob, it should invalid and also 2556 * verify the third blob, it should correct. 2557 */ 2558 static void 2559 blob_dirty_shutdown(void) 2560 { 2561 int rc; 2562 int index; 2563 struct spdk_bs_dev *dev; 2564 spdk_blob_id blobid1, blobid2, blobid3; 2565 struct spdk_blob *blob; 2566 uint64_t length; 2567 uint64_t free_clusters; 2568 const void *value; 2569 size_t value_len; 2570 uint32_t page_num; 2571 struct spdk_blob_md_page *page; 2572 struct spdk_bs_opts opts; 2573 2574 dev = init_dev(); 2575 spdk_bs_opts_init(&opts); 2576 /* Initialize a new blob store */ 2577 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 2578 CU_ASSERT(g_bserrno == 0); 2579 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2580 2581 /* Create first blob */ 2582 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2583 CU_ASSERT(g_bserrno == 0); 2584 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2585 blobid1 = g_blobid; 2586 2587 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2588 CU_ASSERT(g_bserrno == 0); 2589 CU_ASSERT(g_blob != NULL); 2590 blob = g_blob; 2591 2592 /* Set some xattrs */ 2593 rc = spdk_blob_set_xattr(blob, "name", "log.txt", strlen("log.txt") + 1); 2594 CU_ASSERT(rc == 0); 2595 2596 length = 2345; 2597 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2598 CU_ASSERT(rc == 0); 2599 2600 /* Resize the blob */ 2601 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2602 CU_ASSERT(g_bserrno == 0); 2603 2604 /* Set the blob as the super blob */ 2605 spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL); 2606 CU_ASSERT(g_bserrno == 0); 2607 2608 free_clusters = spdk_bs_free_cluster_count(g_bs); 2609 2610 spdk_blob_close(blob, blob_op_complete, NULL); 2611 blob = NULL; 2612 g_blob = NULL; 2613 g_blobid = SPDK_BLOBID_INVALID; 2614 2615 /* Dirty shutdown */ 2616 _spdk_bs_free(g_bs); 2617 2618 /* reload blobstore */ 2619 dev = init_dev(); 2620 spdk_bs_opts_init(&opts); 2621 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2622 CU_ASSERT(g_bserrno == 0); 2623 2624 /* Get the super blob */ 2625 spdk_bs_get_super(g_bs, blob_op_with_id_complete, NULL); 2626 CU_ASSERT(g_bserrno == 0); 2627 CU_ASSERT(blobid1 == g_blobid); 2628 2629 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2630 CU_ASSERT(g_bserrno == 0); 2631 CU_ASSERT(g_blob != NULL); 2632 blob = g_blob; 2633 2634 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2635 2636 /* Get the xattrs */ 2637 value = NULL; 2638 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2639 CU_ASSERT(rc == 0); 2640 SPDK_CU_ASSERT_FATAL(value != NULL); 2641 CU_ASSERT(*(uint64_t *)value == length); 2642 CU_ASSERT(value_len == 8); 2643 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2644 2645 /* Resize the blob */ 2646 spdk_blob_resize(blob, 20, blob_op_complete, NULL); 2647 CU_ASSERT(g_bserrno == 0); 2648 2649 free_clusters = spdk_bs_free_cluster_count(g_bs); 2650 2651 spdk_blob_close(blob, blob_op_complete, NULL); 2652 CU_ASSERT(g_bserrno == 0); 2653 blob = NULL; 2654 g_blob = NULL; 2655 g_blobid = SPDK_BLOBID_INVALID; 2656 2657 /* Dirty shutdown */ 2658 _spdk_bs_free(g_bs); 2659 2660 /* reload the blobstore */ 2661 dev = init_dev(); 2662 spdk_bs_opts_init(&opts); 2663 /* Load an existing blob store */ 2664 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2665 CU_ASSERT(g_bserrno == 0); 2666 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2667 spdk_bs_open_blob(g_bs, blobid1, blob_op_with_handle_complete, NULL); 2668 CU_ASSERT(g_bserrno == 0); 2669 CU_ASSERT(g_blob != NULL); 2670 blob = g_blob; 2671 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 20); 2672 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2673 2674 spdk_blob_close(blob, blob_op_complete, NULL); 2675 CU_ASSERT(g_bserrno == 0); 2676 blob = NULL; 2677 g_blob = NULL; 2678 g_blobid = SPDK_BLOBID_INVALID; 2679 2680 /* Create second blob */ 2681 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2682 CU_ASSERT(g_bserrno == 0); 2683 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2684 blobid2 = g_blobid; 2685 2686 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2687 CU_ASSERT(g_bserrno == 0); 2688 CU_ASSERT(g_blob != NULL); 2689 blob = g_blob; 2690 2691 /* Set some xattrs */ 2692 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2693 CU_ASSERT(rc == 0); 2694 2695 length = 5432; 2696 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2697 CU_ASSERT(rc == 0); 2698 2699 /* Resize the blob */ 2700 spdk_blob_resize(blob, 10, blob_op_complete, NULL); 2701 CU_ASSERT(g_bserrno == 0); 2702 2703 free_clusters = spdk_bs_free_cluster_count(g_bs); 2704 2705 spdk_blob_close(blob, blob_op_complete, NULL); 2706 blob = NULL; 2707 g_blob = NULL; 2708 g_blobid = SPDK_BLOBID_INVALID; 2709 2710 /* Dirty shutdown */ 2711 _spdk_bs_free(g_bs); 2712 2713 /* reload the blobstore */ 2714 dev = init_dev(); 2715 spdk_bs_opts_init(&opts); 2716 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2717 CU_ASSERT(g_bserrno == 0); 2718 2719 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2720 CU_ASSERT(g_bserrno == 0); 2721 CU_ASSERT(g_blob != NULL); 2722 blob = g_blob; 2723 2724 /* Get the xattrs */ 2725 value = NULL; 2726 rc = spdk_blob_get_xattr_value(blob, "length", &value, &value_len); 2727 CU_ASSERT(rc == 0); 2728 SPDK_CU_ASSERT_FATAL(value != NULL); 2729 CU_ASSERT(*(uint64_t *)value == length); 2730 CU_ASSERT(value_len == 8); 2731 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10); 2732 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2733 2734 spdk_blob_close(blob, blob_op_complete, NULL); 2735 CU_ASSERT(g_bserrno == 0); 2736 spdk_bs_delete_blob(g_bs, blobid2, blob_op_complete, NULL); 2737 CU_ASSERT(g_bserrno == 0); 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, blobid1, blob_op_with_handle_complete, NULL); 2754 CU_ASSERT(g_bserrno == 0); 2755 CU_ASSERT(g_blob != NULL); 2756 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2757 spdk_blob_close(g_blob, blob_op_complete, NULL); 2758 CU_ASSERT(g_bserrno == 0); 2759 2760 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2761 CU_ASSERT(g_bserrno == 0); 2762 g_bs = NULL; 2763 2764 /* reload the blobstore */ 2765 dev = init_dev(); 2766 spdk_bs_opts_init(&opts); 2767 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2768 CU_ASSERT(g_bserrno == 0); 2769 2770 /* Create second blob */ 2771 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2772 CU_ASSERT(g_bserrno == 0); 2773 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2774 blobid2 = g_blobid; 2775 2776 /* Create third blob */ 2777 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2778 CU_ASSERT(g_bserrno == 0); 2779 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2780 blobid3 = g_blobid; 2781 2782 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2783 CU_ASSERT(g_bserrno == 0); 2784 CU_ASSERT(g_blob != NULL); 2785 blob = g_blob; 2786 2787 /* Set some xattrs for second blob */ 2788 rc = spdk_blob_set_xattr(blob, "name", "log1.txt", strlen("log1.txt") + 1); 2789 CU_ASSERT(rc == 0); 2790 2791 length = 5432; 2792 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2793 CU_ASSERT(rc == 0); 2794 2795 spdk_blob_close(blob, blob_op_complete, NULL); 2796 blob = NULL; 2797 g_blob = NULL; 2798 g_blobid = SPDK_BLOBID_INVALID; 2799 2800 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2801 CU_ASSERT(g_bserrno == 0); 2802 CU_ASSERT(g_blob != NULL); 2803 blob = g_blob; 2804 2805 /* Set some xattrs for third blob */ 2806 rc = spdk_blob_set_xattr(blob, "name", "log2.txt", strlen("log2.txt") + 1); 2807 CU_ASSERT(rc == 0); 2808 2809 length = 5432; 2810 rc = spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); 2811 CU_ASSERT(rc == 0); 2812 2813 spdk_blob_close(blob, blob_op_complete, NULL); 2814 blob = NULL; 2815 g_blob = NULL; 2816 g_blobid = SPDK_BLOBID_INVALID; 2817 2818 /* Mark second blob as invalid */ 2819 page_num = _spdk_bs_blobid_to_page(blobid2); 2820 2821 index = DEV_BUFFER_BLOCKLEN * (g_bs->md_start + page_num); 2822 page = (struct spdk_blob_md_page *)&g_dev_buffer[index]; 2823 page->sequence_num = 1; 2824 page->crc = _spdk_blob_md_page_calc_crc(page); 2825 2826 free_clusters = spdk_bs_free_cluster_count(g_bs); 2827 2828 /* Dirty shutdown */ 2829 _spdk_bs_free(g_bs); 2830 /* reload the blobstore */ 2831 dev = init_dev(); 2832 spdk_bs_opts_init(&opts); 2833 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 2834 CU_ASSERT(g_bserrno == 0); 2835 2836 spdk_bs_open_blob(g_bs, blobid2, blob_op_with_handle_complete, NULL); 2837 CU_ASSERT(g_bserrno != 0); 2838 CU_ASSERT(g_blob == NULL); 2839 2840 spdk_bs_open_blob(g_bs, blobid3, blob_op_with_handle_complete, NULL); 2841 CU_ASSERT(g_bserrno == 0); 2842 CU_ASSERT(g_blob != NULL); 2843 blob = g_blob; 2844 2845 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(g_bs)); 2846 2847 spdk_blob_close(blob, blob_op_complete, NULL); 2848 blob = NULL; 2849 g_blob = NULL; 2850 g_blobid = SPDK_BLOBID_INVALID; 2851 2852 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2853 CU_ASSERT(g_bserrno == 0); 2854 g_bs = NULL; 2855 } 2856 2857 static void 2858 blob_flags(void) 2859 { 2860 struct spdk_bs_dev *dev; 2861 spdk_blob_id blobid_invalid, blobid_data_ro, blobid_md_ro; 2862 struct spdk_blob *blob_invalid, *blob_data_ro, *blob_md_ro; 2863 struct spdk_bs_opts opts; 2864 int rc; 2865 2866 dev = init_dev(); 2867 spdk_bs_opts_init(&opts); 2868 2869 /* Initialize a new blob store */ 2870 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 2871 CU_ASSERT(g_bserrno == 0); 2872 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 2873 2874 /* Create three blobs - one each for testing invalid, data_ro and md_ro flags. */ 2875 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2876 CU_ASSERT(g_bserrno == 0); 2877 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2878 blobid_invalid = g_blobid; 2879 2880 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2881 CU_ASSERT(g_bserrno == 0); 2882 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2883 blobid_data_ro = g_blobid; 2884 2885 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 2886 CU_ASSERT(g_bserrno == 0); 2887 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 2888 blobid_md_ro = g_blobid; 2889 2890 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2891 CU_ASSERT(g_bserrno == 0); 2892 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2893 blob_invalid = g_blob; 2894 2895 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2896 CU_ASSERT(g_bserrno == 0); 2897 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2898 blob_data_ro = g_blob; 2899 2900 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2901 CU_ASSERT(g_bserrno == 0); 2902 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2903 blob_md_ro = g_blob; 2904 2905 /* Change the size of blob_data_ro to check if flags are serialized 2906 * when blob has non zero number of extents */ 2907 spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL); 2908 CU_ASSERT(g_bserrno == 0); 2909 2910 /* Set the xattr to check if flags are serialized 2911 * when blob has non zero number of xattrs */ 2912 rc = spdk_blob_set_xattr(blob_md_ro, "name", "log.txt", strlen("log.txt") + 1); 2913 CU_ASSERT(rc == 0); 2914 2915 blob_invalid->invalid_flags = (1ULL << 63); 2916 blob_invalid->state = SPDK_BLOB_STATE_DIRTY; 2917 blob_data_ro->data_ro_flags = (1ULL << 62); 2918 blob_data_ro->state = SPDK_BLOB_STATE_DIRTY; 2919 blob_md_ro->md_ro_flags = (1ULL << 61); 2920 blob_md_ro->state = SPDK_BLOB_STATE_DIRTY; 2921 2922 g_bserrno = -1; 2923 spdk_blob_sync_md(blob_invalid, blob_op_complete, NULL); 2924 CU_ASSERT(g_bserrno == 0); 2925 g_bserrno = -1; 2926 spdk_blob_sync_md(blob_data_ro, blob_op_complete, NULL); 2927 CU_ASSERT(g_bserrno == 0); 2928 g_bserrno = -1; 2929 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2930 CU_ASSERT(g_bserrno == 0); 2931 2932 g_bserrno = -1; 2933 spdk_blob_close(blob_invalid, blob_op_complete, NULL); 2934 CU_ASSERT(g_bserrno == 0); 2935 blob_invalid = NULL; 2936 g_bserrno = -1; 2937 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2938 CU_ASSERT(g_bserrno == 0); 2939 blob_data_ro = NULL; 2940 g_bserrno = -1; 2941 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2942 CU_ASSERT(g_bserrno == 0); 2943 blob_md_ro = NULL; 2944 2945 g_blob = NULL; 2946 g_blobid = SPDK_BLOBID_INVALID; 2947 2948 /* Unload the blob store */ 2949 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2950 CU_ASSERT(g_bserrno == 0); 2951 g_bs = NULL; 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 2959 g_blob = NULL; 2960 g_bserrno = 0; 2961 spdk_bs_open_blob(g_bs, blobid_invalid, blob_op_with_handle_complete, NULL); 2962 CU_ASSERT(g_bserrno != 0); 2963 CU_ASSERT(g_blob == NULL); 2964 2965 g_blob = NULL; 2966 g_bserrno = -1; 2967 spdk_bs_open_blob(g_bs, blobid_data_ro, blob_op_with_handle_complete, NULL); 2968 CU_ASSERT(g_bserrno == 0); 2969 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2970 blob_data_ro = g_blob; 2971 /* If an unknown data_ro flag was found, the blob should be marked both data and md read-only. */ 2972 CU_ASSERT(blob_data_ro->data_ro == true); 2973 CU_ASSERT(blob_data_ro->md_ro == true); 2974 CU_ASSERT(spdk_blob_get_num_clusters(blob_data_ro) == 10); 2975 2976 g_blob = NULL; 2977 g_bserrno = -1; 2978 spdk_bs_open_blob(g_bs, blobid_md_ro, blob_op_with_handle_complete, NULL); 2979 CU_ASSERT(g_bserrno == 0); 2980 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 2981 blob_md_ro = g_blob; 2982 CU_ASSERT(blob_md_ro->data_ro == false); 2983 CU_ASSERT(blob_md_ro->md_ro == true); 2984 2985 g_bserrno = -1; 2986 spdk_blob_sync_md(blob_md_ro, blob_op_complete, NULL); 2987 CU_ASSERT(g_bserrno == 0); 2988 2989 spdk_blob_close(blob_data_ro, blob_op_complete, NULL); 2990 CU_ASSERT(g_bserrno == 0); 2991 spdk_blob_close(blob_md_ro, blob_op_complete, NULL); 2992 CU_ASSERT(g_bserrno == 0); 2993 2994 spdk_bs_unload(g_bs, bs_op_complete, NULL); 2995 CU_ASSERT(g_bserrno == 0); 2996 } 2997 2998 static void 2999 bs_version(void) 3000 { 3001 struct spdk_bs_super_block *super; 3002 struct spdk_bs_dev *dev; 3003 struct spdk_bs_opts opts; 3004 spdk_blob_id blobid; 3005 3006 dev = init_dev(); 3007 spdk_bs_opts_init(&opts); 3008 3009 /* Initialize a new blob store */ 3010 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3011 CU_ASSERT(g_bserrno == 0); 3012 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3013 3014 /* Unload the blob store */ 3015 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3016 CU_ASSERT(g_bserrno == 0); 3017 g_bs = NULL; 3018 3019 /* 3020 * Change the bs version on disk. This will allow us to 3021 * test that the version does not get modified automatically 3022 * when loading and unloading the blobstore. 3023 */ 3024 super = (struct spdk_bs_super_block *)&g_dev_buffer[0]; 3025 CU_ASSERT(super->version == SPDK_BS_VERSION); 3026 CU_ASSERT(super->clean == 1); 3027 super->version = 2; 3028 /* 3029 * Version 2 metadata does not have a used blobid mask, so clear 3030 * those fields in the super block and zero the corresponding 3031 * region on "disk". We will use this to ensure blob IDs are 3032 * correctly reconstructed. 3033 */ 3034 memset(&g_dev_buffer[super->used_blobid_mask_start * SPDK_BS_PAGE_SIZE], 0, 3035 super->used_blobid_mask_len * SPDK_BS_PAGE_SIZE); 3036 super->used_blobid_mask_start = 0; 3037 super->used_blobid_mask_len = 0; 3038 super->crc = _spdk_blob_md_page_calc_crc(super); 3039 3040 /* Load an existing blob store */ 3041 dev = init_dev(); 3042 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3043 CU_ASSERT(g_bserrno == 0); 3044 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3045 CU_ASSERT(super->clean == 0); 3046 3047 /* 3048 * Create a blob - just to make sure that when we unload it 3049 * results in writing the super block (since metadata pages 3050 * were allocated. 3051 */ 3052 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3053 CU_ASSERT(g_bserrno == 0); 3054 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3055 blobid = g_blobid; 3056 3057 /* Unload the blob store */ 3058 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3059 CU_ASSERT(g_bserrno == 0); 3060 g_bs = NULL; 3061 CU_ASSERT(super->version == 2); 3062 CU_ASSERT(super->used_blobid_mask_start == 0); 3063 CU_ASSERT(super->used_blobid_mask_len == 0); 3064 3065 dev = init_dev(); 3066 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3067 CU_ASSERT(g_bserrno == 0); 3068 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3069 3070 g_blob = NULL; 3071 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3072 CU_ASSERT(g_bserrno == 0); 3073 CU_ASSERT(g_blob != NULL); 3074 3075 spdk_blob_close(g_blob, blob_op_complete, NULL); 3076 CU_ASSERT(g_bserrno == 0); 3077 3078 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3079 CU_ASSERT(g_bserrno == 0); 3080 g_bs = NULL; 3081 CU_ASSERT(super->version == 2); 3082 CU_ASSERT(super->used_blobid_mask_start == 0); 3083 CU_ASSERT(super->used_blobid_mask_len == 0); 3084 } 3085 3086 static void 3087 blob_set_xattrs(void) 3088 { 3089 struct spdk_blob_store *bs; 3090 struct spdk_bs_dev *dev; 3091 struct spdk_blob *blob; 3092 struct spdk_blob_opts opts; 3093 spdk_blob_id blobid; 3094 const void *value; 3095 size_t value_len; 3096 int rc; 3097 3098 dev = init_dev(); 3099 3100 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3101 CU_ASSERT(g_bserrno == 0); 3102 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3103 bs = g_bs; 3104 3105 /* Create blob with extra attributes */ 3106 spdk_blob_opts_init(&opts); 3107 3108 opts.xattrs.names = g_xattr_names; 3109 opts.xattrs.get_value = _get_xattr_value; 3110 opts.xattrs.count = 3; 3111 opts.xattrs.ctx = &g_ctx; 3112 3113 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3114 CU_ASSERT(g_bserrno == 0); 3115 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3116 blobid = g_blobid; 3117 3118 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3119 CU_ASSERT(g_bserrno == 0); 3120 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3121 blob = g_blob; 3122 3123 /* Get the xattrs */ 3124 value = NULL; 3125 3126 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[0], &value, &value_len); 3127 CU_ASSERT(rc == 0); 3128 SPDK_CU_ASSERT_FATAL(value != NULL); 3129 CU_ASSERT(value_len == strlen(g_xattr_values[0])); 3130 CU_ASSERT_NSTRING_EQUAL_FATAL(value, g_xattr_values[0], value_len); 3131 3132 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[1], &value, &value_len); 3133 CU_ASSERT(rc == 0); 3134 SPDK_CU_ASSERT_FATAL(value != NULL); 3135 CU_ASSERT(value_len == strlen(g_xattr_values[1])); 3136 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[1], value_len); 3137 3138 rc = spdk_blob_get_xattr_value(blob, g_xattr_names[2], &value, &value_len); 3139 CU_ASSERT(rc == 0); 3140 SPDK_CU_ASSERT_FATAL(value != NULL); 3141 CU_ASSERT(value_len == strlen(g_xattr_values[2])); 3142 CU_ASSERT_NSTRING_EQUAL((char *)value, g_xattr_values[2], value_len); 3143 3144 /* Try to get non existing attribute */ 3145 3146 rc = spdk_blob_get_xattr_value(blob, "foobar", &value, &value_len); 3147 CU_ASSERT(rc == -ENOENT); 3148 3149 spdk_blob_close(blob, blob_op_complete, NULL); 3150 CU_ASSERT(g_bserrno == 0); 3151 blob = NULL; 3152 g_blob = NULL; 3153 g_blobid = SPDK_BLOBID_INVALID; 3154 3155 /* NULL callback */ 3156 spdk_blob_opts_init(&opts); 3157 opts.xattrs.names = g_xattr_names; 3158 opts.xattrs.get_value = NULL; 3159 opts.xattrs.count = 1; 3160 opts.xattrs.ctx = &g_ctx; 3161 3162 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3163 CU_ASSERT(g_bserrno == -EINVAL); 3164 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3165 3166 /* NULL values */ 3167 spdk_blob_opts_init(&opts); 3168 opts.xattrs.names = g_xattr_names; 3169 opts.xattrs.get_value = _get_xattr_value_null; 3170 opts.xattrs.count = 1; 3171 opts.xattrs.ctx = NULL; 3172 3173 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3174 CU_ASSERT(g_bserrno == -EINVAL); 3175 3176 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3177 CU_ASSERT(g_bserrno == 0); 3178 g_bs = NULL; 3179 3180 } 3181 3182 static void 3183 blob_thin_prov_alloc(void) 3184 { 3185 struct spdk_blob_store *bs; 3186 struct spdk_bs_dev *dev; 3187 struct spdk_blob *blob; 3188 struct spdk_blob_opts opts; 3189 spdk_blob_id blobid; 3190 uint64_t free_clusters; 3191 3192 dev = init_dev(); 3193 3194 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3195 CU_ASSERT(g_bserrno == 0); 3196 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3197 bs = g_bs; 3198 free_clusters = spdk_bs_free_cluster_count(bs); 3199 3200 /* Set blob as thin provisioned */ 3201 spdk_blob_opts_init(&opts); 3202 opts.thin_provision = true; 3203 3204 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3205 CU_ASSERT(g_bserrno == 0); 3206 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3207 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3208 blobid = g_blobid; 3209 3210 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3211 CU_ASSERT(g_bserrno == 0); 3212 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3213 blob = g_blob; 3214 3215 CU_ASSERT(blob->active.num_clusters == 0); 3216 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0); 3217 3218 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3219 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3220 CU_ASSERT(g_bserrno == 0); 3221 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3222 CU_ASSERT(blob->active.num_clusters == 5); 3223 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3224 3225 /* Shrink the blob to 3 clusters - still unallocated */ 3226 spdk_blob_resize(blob, 3, blob_op_complete, NULL); 3227 CU_ASSERT(g_bserrno == 0); 3228 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3229 CU_ASSERT(blob->active.num_clusters == 3); 3230 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3231 3232 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3233 CU_ASSERT(g_bserrno == 0); 3234 /* Sync must not change anything */ 3235 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3236 CU_ASSERT(blob->active.num_clusters == 3); 3237 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3); 3238 3239 spdk_blob_close(blob, blob_op_complete, NULL); 3240 CU_ASSERT(g_bserrno == 0); 3241 3242 /* Unload the blob store */ 3243 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3244 CU_ASSERT(g_bserrno == 0); 3245 g_bs = NULL; 3246 g_blob = NULL; 3247 g_blobid = 0; 3248 3249 /* Load an existing blob store */ 3250 dev = init_dev(); 3251 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3252 CU_ASSERT(g_bserrno == 0); 3253 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3254 3255 bs = g_bs; 3256 3257 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3258 CU_ASSERT(g_bserrno == 0); 3259 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3260 blob = g_blob; 3261 3262 /* Check that clusters allocation and size is still the same */ 3263 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3264 CU_ASSERT(blob->active.num_clusters == 3); 3265 3266 spdk_blob_close(blob, blob_op_complete, NULL); 3267 CU_ASSERT(g_bserrno == 0); 3268 3269 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3270 CU_ASSERT(g_bserrno == 0); 3271 3272 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3273 CU_ASSERT(g_bserrno == 0); 3274 g_bs = NULL; 3275 } 3276 3277 static void 3278 blob_insert_cluster_msg(void) 3279 { 3280 struct spdk_blob_store *bs; 3281 struct spdk_bs_dev *dev; 3282 struct spdk_blob *blob; 3283 struct spdk_blob_opts opts; 3284 spdk_blob_id blobid; 3285 uint64_t free_clusters; 3286 3287 dev = init_dev(); 3288 3289 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3290 CU_ASSERT(g_bserrno == 0); 3291 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3292 bs = g_bs; 3293 free_clusters = spdk_bs_free_cluster_count(bs); 3294 3295 /* Set blob as thin provisioned */ 3296 spdk_blob_opts_init(&opts); 3297 opts.thin_provision = true; 3298 opts.num_clusters = 4; 3299 3300 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3301 CU_ASSERT(g_bserrno == 0); 3302 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3303 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3304 blobid = g_blobid; 3305 3306 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3307 CU_ASSERT(g_bserrno == 0); 3308 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3309 blob = g_blob; 3310 3311 CU_ASSERT(blob->active.num_clusters == 4); 3312 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 4); 3313 CU_ASSERT(blob->active.clusters[1] == 0); 3314 3315 _spdk_bs_claim_cluster(bs, 0xF); 3316 _spdk_blob_insert_cluster_on_md_thread(blob, 1, 0xF, blob_op_complete, NULL); 3317 3318 CU_ASSERT(blob->active.clusters[1] != 0); 3319 3320 spdk_blob_close(blob, blob_op_complete, NULL); 3321 CU_ASSERT(g_bserrno == 0); 3322 3323 /* Unload the blob store */ 3324 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3325 CU_ASSERT(g_bserrno == 0); 3326 g_bs = NULL; 3327 g_blob = NULL; 3328 g_blobid = 0; 3329 3330 /* Load an existing blob store */ 3331 dev = init_dev(); 3332 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 3333 CU_ASSERT(g_bserrno == 0); 3334 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3335 3336 bs = g_bs; 3337 3338 spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL); 3339 CU_ASSERT(g_bserrno == 0); 3340 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3341 blob = g_blob; 3342 3343 CU_ASSERT(blob->active.clusters[1] != 0); 3344 3345 spdk_blob_close(blob, blob_op_complete, NULL); 3346 CU_ASSERT(g_bserrno == 0); 3347 3348 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3349 CU_ASSERT(g_bserrno == 0); 3350 3351 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3352 CU_ASSERT(g_bserrno == 0); 3353 g_bs = NULL; 3354 } 3355 3356 static void 3357 blob_thin_prov_rw(void) 3358 { 3359 static const uint8_t zero[10 * 4096] = { 0 }; 3360 struct spdk_blob_store *bs; 3361 struct spdk_bs_dev *dev; 3362 struct spdk_blob *blob; 3363 struct spdk_io_channel *channel; 3364 struct spdk_blob_opts opts; 3365 spdk_blob_id blobid; 3366 uint64_t free_clusters; 3367 uint8_t payload_read[10 * 4096]; 3368 uint8_t payload_write[10 * 4096]; 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, 0xFF, sizeof(payload_read)); 3411 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3412 CU_ASSERT(g_bserrno == 0); 3413 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3414 3415 memset(payload_write, 0xE5, sizeof(payload_write)); 3416 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3417 CU_ASSERT(g_bserrno == 0); 3418 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3419 3420 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3421 CU_ASSERT(g_bserrno == 0); 3422 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3423 3424 spdk_blob_close(blob, blob_op_complete, NULL); 3425 CU_ASSERT(g_bserrno == 0); 3426 3427 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3428 CU_ASSERT(g_bserrno == 0); 3429 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3430 3431 spdk_bs_free_io_channel(channel); 3432 3433 /* Unload the blob store */ 3434 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3435 CU_ASSERT(g_bserrno == 0); 3436 g_bs = NULL; 3437 g_blob = NULL; 3438 g_blobid = 0; 3439 } 3440 3441 static void 3442 blob_thin_prov_rw_iov(void) 3443 { 3444 static const uint8_t zero[10 * 4096] = { 0 }; 3445 struct spdk_blob_store *bs; 3446 struct spdk_bs_dev *dev; 3447 struct spdk_blob *blob; 3448 struct spdk_io_channel *channel; 3449 struct spdk_blob_opts opts; 3450 spdk_blob_id blobid; 3451 uint64_t free_clusters; 3452 uint8_t payload_read[10 * 4096]; 3453 uint8_t payload_write[10 * 4096]; 3454 struct iovec iov_read[3]; 3455 struct iovec iov_write[3]; 3456 3457 dev = init_dev(); 3458 3459 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3460 CU_ASSERT(g_bserrno == 0); 3461 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3462 bs = g_bs; 3463 free_clusters = spdk_bs_free_cluster_count(bs); 3464 3465 channel = spdk_bs_alloc_io_channel(bs); 3466 CU_ASSERT(channel != NULL); 3467 3468 spdk_blob_opts_init(&opts); 3469 opts.thin_provision = true; 3470 3471 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3472 CU_ASSERT(g_bserrno == 0); 3473 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3474 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3475 blobid = g_blobid; 3476 3477 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3478 CU_ASSERT(g_bserrno == 0); 3479 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3480 blob = g_blob; 3481 3482 CU_ASSERT(blob->active.num_clusters == 0); 3483 3484 /* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */ 3485 spdk_blob_resize(blob, 5, blob_op_complete, NULL); 3486 CU_ASSERT(g_bserrno == 0); 3487 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3488 CU_ASSERT(blob->active.num_clusters == 5); 3489 3490 spdk_blob_sync_md(blob, blob_op_complete, NULL); 3491 CU_ASSERT(g_bserrno == 0); 3492 /* Sync must not change anything */ 3493 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3494 CU_ASSERT(blob->active.num_clusters == 5); 3495 3496 /* Payload should be all zeros from unallocated clusters */ 3497 memset(payload_read, 0xAA, sizeof(payload_read)); 3498 iov_read[0].iov_base = payload_read; 3499 iov_read[0].iov_len = 3 * 4096; 3500 iov_read[1].iov_base = payload_read + 3 * 4096; 3501 iov_read[1].iov_len = 4 * 4096; 3502 iov_read[2].iov_base = payload_read + 7 * 4096; 3503 iov_read[2].iov_len = 3 * 4096; 3504 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3505 CU_ASSERT(g_bserrno == 0); 3506 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3507 3508 memset(payload_write, 0xE5, sizeof(payload_write)); 3509 iov_write[0].iov_base = payload_write; 3510 iov_write[0].iov_len = 1 * 4096; 3511 iov_write[1].iov_base = payload_write + 1 * 4096; 3512 iov_write[1].iov_len = 5 * 4096; 3513 iov_write[2].iov_base = payload_write + 6 * 4096; 3514 iov_write[2].iov_len = 4 * 4096; 3515 3516 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3517 CU_ASSERT(g_bserrno == 0); 3518 3519 memset(payload_read, 0xAA, sizeof(payload_read)); 3520 iov_read[0].iov_base = payload_read; 3521 iov_read[0].iov_len = 3 * 4096; 3522 iov_read[1].iov_base = payload_read + 3 * 4096; 3523 iov_read[1].iov_len = 4 * 4096; 3524 iov_read[2].iov_base = payload_read + 7 * 4096; 3525 iov_read[2].iov_len = 3 * 4096; 3526 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3527 CU_ASSERT(g_bserrno == 0); 3528 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3529 3530 spdk_blob_close(blob, blob_op_complete, NULL); 3531 CU_ASSERT(g_bserrno == 0); 3532 3533 spdk_bs_free_io_channel(channel); 3534 3535 /* Unload the blob store */ 3536 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3537 CU_ASSERT(g_bserrno == 0); 3538 g_bs = NULL; 3539 g_blob = NULL; 3540 g_blobid = 0; 3541 } 3542 3543 struct iter_ctx { 3544 int current_iter; 3545 spdk_blob_id blobid[4]; 3546 }; 3547 3548 static void 3549 test_iter(void *arg, struct spdk_blob *blob, int bserrno) 3550 { 3551 struct iter_ctx *iter_ctx = arg; 3552 spdk_blob_id blobid; 3553 3554 CU_ASSERT(bserrno == 0); 3555 blobid = spdk_blob_get_id(blob); 3556 CU_ASSERT(blobid == iter_ctx->blobid[iter_ctx->current_iter++]); 3557 } 3558 3559 static void 3560 bs_load_iter(void) 3561 { 3562 struct spdk_bs_dev *dev; 3563 struct iter_ctx iter_ctx = { 0 }; 3564 struct spdk_blob *blob; 3565 int i, rc; 3566 struct spdk_bs_opts opts; 3567 3568 dev = init_dev(); 3569 spdk_bs_opts_init(&opts); 3570 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3571 3572 /* Initialize a new blob store */ 3573 spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL); 3574 CU_ASSERT(g_bserrno == 0); 3575 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3576 3577 for (i = 0; i < 4; i++) { 3578 g_bserrno = -1; 3579 g_blobid = SPDK_BLOBID_INVALID; 3580 spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL); 3581 CU_ASSERT(g_bserrno == 0); 3582 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3583 iter_ctx.blobid[i] = g_blobid; 3584 3585 g_bserrno = -1; 3586 g_blob = NULL; 3587 spdk_bs_open_blob(g_bs, g_blobid, blob_op_with_handle_complete, NULL); 3588 CU_ASSERT(g_bserrno == 0); 3589 CU_ASSERT(g_blob != NULL); 3590 blob = g_blob; 3591 3592 /* Just save the blobid as an xattr for testing purposes. */ 3593 rc = spdk_blob_set_xattr(blob, "blobid", &g_blobid, sizeof(g_blobid)); 3594 CU_ASSERT(rc == 0); 3595 3596 /* Resize the blob */ 3597 spdk_blob_resize(blob, i, blob_op_complete, NULL); 3598 CU_ASSERT(g_bserrno == 0); 3599 3600 spdk_blob_close(blob, blob_op_complete, NULL); 3601 CU_ASSERT(g_bserrno == 0); 3602 } 3603 3604 g_bserrno = -1; 3605 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3606 CU_ASSERT(g_bserrno == 0); 3607 3608 dev = init_dev(); 3609 spdk_bs_opts_init(&opts); 3610 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3611 opts.iter_cb_fn = test_iter; 3612 opts.iter_cb_arg = &iter_ctx; 3613 3614 /* Test blob iteration during load after a clean shutdown. */ 3615 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3616 CU_ASSERT(g_bserrno == 0); 3617 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3618 3619 /* Dirty shutdown */ 3620 _spdk_bs_free(g_bs); 3621 3622 dev = init_dev(); 3623 spdk_bs_opts_init(&opts); 3624 snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE"); 3625 opts.iter_cb_fn = test_iter; 3626 iter_ctx.current_iter = 0; 3627 opts.iter_cb_arg = &iter_ctx; 3628 3629 /* Test blob iteration during load after a dirty shutdown. */ 3630 spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL); 3631 CU_ASSERT(g_bserrno == 0); 3632 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3633 3634 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3635 CU_ASSERT(g_bserrno == 0); 3636 g_bs = NULL; 3637 } 3638 3639 static void 3640 blob_snapshot_rw(void) 3641 { 3642 static const uint8_t zero[10 * 4096] = { 0 }; 3643 struct spdk_blob_store *bs; 3644 struct spdk_bs_dev *dev; 3645 struct spdk_blob *blob, *snapshot; 3646 struct spdk_io_channel *channel; 3647 struct spdk_blob_opts opts; 3648 spdk_blob_id blobid, snapshotid; 3649 uint64_t free_clusters; 3650 uint8_t payload_read[10 * 4096]; 3651 uint8_t payload_write[10 * 4096]; 3652 3653 dev = init_dev(); 3654 3655 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3656 CU_ASSERT(g_bserrno == 0); 3657 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3658 bs = g_bs; 3659 free_clusters = spdk_bs_free_cluster_count(bs); 3660 3661 channel = spdk_bs_alloc_io_channel(bs); 3662 CU_ASSERT(channel != NULL); 3663 3664 spdk_blob_opts_init(&opts); 3665 opts.thin_provision = true; 3666 opts.num_clusters = 5; 3667 3668 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3669 CU_ASSERT(g_bserrno == 0); 3670 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3671 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3672 blobid = g_blobid; 3673 3674 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3675 CU_ASSERT(g_bserrno == 0); 3676 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3677 blob = g_blob; 3678 3679 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3680 3681 memset(payload_read, 0xFF, sizeof(payload_read)); 3682 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3683 CU_ASSERT(g_bserrno == 0); 3684 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3685 3686 memset(payload_write, 0xE5, sizeof(payload_write)); 3687 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3688 CU_ASSERT(g_bserrno == 0); 3689 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3690 3691 /* Create snapshot from blob */ 3692 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3693 CU_ASSERT(g_bserrno == 0); 3694 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3695 snapshotid = g_blobid; 3696 3697 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3698 CU_ASSERT(g_bserrno == 0); 3699 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3700 snapshot = g_blob; 3701 CU_ASSERT(snapshot->data_ro == true) 3702 CU_ASSERT(snapshot->md_ro == true) 3703 3704 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3705 3706 memset(payload_write, 0xAA, sizeof(payload_write)); 3707 spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL); 3708 CU_ASSERT(g_bserrno == 0); 3709 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3710 3711 spdk_blob_io_read(blob, channel, payload_read, 4, 10, blob_op_complete, NULL); 3712 CU_ASSERT(g_bserrno == 0); 3713 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3714 3715 /* Data on snapshot should not change after write to clone */ 3716 memset(payload_write, 0xE5, sizeof(payload_write)); 3717 spdk_blob_io_read(snapshot, channel, payload_read, 4, 10, blob_op_complete, NULL); 3718 CU_ASSERT(g_bserrno == 0); 3719 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3720 3721 spdk_blob_close(blob, blob_op_complete, NULL); 3722 CU_ASSERT(g_bserrno == 0); 3723 3724 spdk_blob_close(snapshot, blob_op_complete, NULL); 3725 CU_ASSERT(g_bserrno == 0); 3726 3727 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 3728 CU_ASSERT(g_bserrno == 0); 3729 3730 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3731 CU_ASSERT(g_bserrno == 0); 3732 3733 spdk_bs_free_io_channel(channel); 3734 3735 /* Unload the blob store */ 3736 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3737 CU_ASSERT(g_bserrno == 0); 3738 g_bs = NULL; 3739 g_blob = NULL; 3740 g_blobid = 0; 3741 } 3742 3743 static void 3744 blob_snapshot_rw_iov(void) 3745 { 3746 static const uint8_t zero[10 * 4096] = { 0 }; 3747 struct spdk_blob_store *bs; 3748 struct spdk_bs_dev *dev; 3749 struct spdk_blob *blob, *snapshot; 3750 struct spdk_io_channel *channel; 3751 struct spdk_blob_opts opts; 3752 spdk_blob_id blobid, snapshotid; 3753 uint64_t free_clusters; 3754 uint8_t payload_read[10 * 4096]; 3755 uint8_t payload_write[10 * 4096]; 3756 struct iovec iov_read[3]; 3757 struct iovec iov_write[3]; 3758 3759 dev = init_dev(); 3760 3761 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3762 CU_ASSERT(g_bserrno == 0); 3763 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3764 bs = g_bs; 3765 free_clusters = spdk_bs_free_cluster_count(bs); 3766 3767 channel = spdk_bs_alloc_io_channel(bs); 3768 CU_ASSERT(channel != NULL); 3769 3770 spdk_blob_opts_init(&opts); 3771 opts.thin_provision = true; 3772 opts.num_clusters = 5; 3773 3774 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3775 CU_ASSERT(g_bserrno == 0); 3776 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3777 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3778 blobid = g_blobid; 3779 3780 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3781 CU_ASSERT(g_bserrno == 0); 3782 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3783 blob = g_blob; 3784 3785 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3786 3787 /* Create snapshot from blob */ 3788 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3789 CU_ASSERT(g_bserrno == 0); 3790 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3791 snapshotid = g_blobid; 3792 3793 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3794 CU_ASSERT(g_bserrno == 0); 3795 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3796 snapshot = g_blob; 3797 CU_ASSERT(snapshot->data_ro == true) 3798 CU_ASSERT(snapshot->md_ro == true) 3799 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5); 3800 3801 /* Payload should be all zeros from unallocated clusters */ 3802 memset(payload_read, 0xAA, sizeof(payload_read)); 3803 iov_read[0].iov_base = payload_read; 3804 iov_read[0].iov_len = 3 * 4096; 3805 iov_read[1].iov_base = payload_read + 3 * 4096; 3806 iov_read[1].iov_len = 4 * 4096; 3807 iov_read[2].iov_base = payload_read + 7 * 4096; 3808 iov_read[2].iov_len = 3 * 4096; 3809 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3810 CU_ASSERT(g_bserrno == 0); 3811 CU_ASSERT(memcmp(zero, payload_read, 10 * 4096) == 0); 3812 3813 memset(payload_write, 0xE5, sizeof(payload_write)); 3814 iov_write[0].iov_base = payload_write; 3815 iov_write[0].iov_len = 1 * 4096; 3816 iov_write[1].iov_base = payload_write + 1 * 4096; 3817 iov_write[1].iov_len = 5 * 4096; 3818 iov_write[2].iov_base = payload_write + 6 * 4096; 3819 iov_write[2].iov_len = 4 * 4096; 3820 3821 spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL); 3822 CU_ASSERT(g_bserrno == 0); 3823 3824 memset(payload_read, 0xAA, sizeof(payload_read)); 3825 iov_read[0].iov_base = payload_read; 3826 iov_read[0].iov_len = 3 * 4096; 3827 iov_read[1].iov_base = payload_read + 3 * 4096; 3828 iov_read[1].iov_len = 4 * 4096; 3829 iov_read[2].iov_base = payload_read + 7 * 4096; 3830 iov_read[2].iov_len = 3 * 4096; 3831 spdk_blob_io_readv(blob, channel, iov_read, 3, 250, 10, blob_op_complete, NULL); 3832 CU_ASSERT(g_bserrno == 0); 3833 CU_ASSERT(memcmp(payload_write, payload_read, 10 * 4096) == 0); 3834 3835 spdk_blob_close(blob, blob_op_complete, NULL); 3836 CU_ASSERT(g_bserrno == 0); 3837 3838 spdk_blob_close(snapshot, blob_op_complete, NULL); 3839 CU_ASSERT(g_bserrno == 0); 3840 3841 spdk_bs_free_io_channel(channel); 3842 3843 /* Unload the blob store */ 3844 spdk_bs_unload(g_bs, bs_op_complete, NULL); 3845 CU_ASSERT(g_bserrno == 0); 3846 g_bs = NULL; 3847 g_blob = NULL; 3848 g_blobid = 0; 3849 } 3850 3851 static void 3852 blob_inflate_rw(void) 3853 { 3854 static uint8_t *zero; 3855 struct spdk_blob_store *bs; 3856 struct spdk_bs_dev *dev; 3857 struct spdk_blob *blob, *snapshot; 3858 struct spdk_io_channel *channel; 3859 struct spdk_blob_opts opts; 3860 spdk_blob_id blobid, snapshotid; 3861 uint64_t free_clusters; 3862 uint64_t cluster_size; 3863 3864 uint64_t payload_size; 3865 uint8_t *payload_read; 3866 uint8_t *payload_write; 3867 uint8_t *payload_clone; 3868 3869 uint64_t pages_per_cluster; 3870 uint64_t pages_per_payload; 3871 3872 int i; 3873 3874 dev = init_dev(); 3875 3876 spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL); 3877 CU_ASSERT(g_bserrno == 0); 3878 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 3879 bs = g_bs; 3880 3881 free_clusters = spdk_bs_free_cluster_count(bs); 3882 cluster_size = spdk_bs_get_cluster_size(bs); 3883 pages_per_cluster = cluster_size / spdk_bs_get_page_size(bs); 3884 pages_per_payload = pages_per_cluster * 5; 3885 3886 payload_size = cluster_size * 5; 3887 3888 payload_read = malloc(payload_size); 3889 SPDK_CU_ASSERT_FATAL(payload_read != NULL); 3890 3891 payload_write = malloc(payload_size); 3892 SPDK_CU_ASSERT_FATAL(payload_write != NULL); 3893 3894 payload_clone = malloc(payload_size); 3895 SPDK_CU_ASSERT_FATAL(payload_clone != NULL); 3896 3897 zero = calloc(1, payload_size); 3898 SPDK_CU_ASSERT_FATAL(zero != NULL); 3899 3900 channel = spdk_bs_alloc_io_channel(bs); 3901 SPDK_CU_ASSERT_FATAL(channel != NULL); 3902 3903 /* Create blob */ 3904 spdk_blob_opts_init(&opts); 3905 opts.thin_provision = true; 3906 opts.num_clusters = 5; 3907 3908 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 3909 CU_ASSERT(g_bserrno == 0); 3910 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3911 CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs)); 3912 blobid = g_blobid; 3913 3914 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3915 CU_ASSERT(g_bserrno == 0); 3916 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3917 blob = g_blob; 3918 3919 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3920 3921 /* Initial read should return zeroed payload */ 3922 memset(payload_read, 0xFF, payload_size); 3923 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 3924 CU_ASSERT(g_bserrno == 0); 3925 CU_ASSERT(memcmp(zero, payload_read, payload_size) == 0); 3926 3927 /* Fill whole blob with a pattern */ 3928 memset(payload_write, 0xE5, payload_size); 3929 spdk_blob_io_write(blob, channel, payload_write, 0, pages_per_payload, 3930 blob_op_complete, NULL); 3931 CU_ASSERT(g_bserrno == 0); 3932 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3933 3934 /* Create snapshot from blob */ 3935 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 3936 CU_ASSERT(g_bserrno == 0); 3937 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 3938 snapshotid = g_blobid; 3939 3940 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 3941 CU_ASSERT(g_bserrno == 0); 3942 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3943 snapshot = g_blob; 3944 CU_ASSERT(snapshot->data_ro == true) 3945 CU_ASSERT(snapshot->md_ro == true) 3946 3947 CU_ASSERT(spdk_blob_get_num_clusters(snapshot) == 5) 3948 3949 /* Write every second cluster with a pattern. 3950 * 3951 * payload_clone stores expected result on "blob" read at the time and 3952 * is used only to check data consistency on clone before and after 3953 * inflation. Initially we fill it with a backing snapshots pattern 3954 * used before. 3955 */ 3956 memset(payload_clone, 0xE5, payload_size); 3957 memset(payload_write, 0xAA, payload_size); 3958 for (i = 1; i < 5; i += 2) { 3959 spdk_blob_io_write(blob, channel, payload_write, i * pages_per_cluster, 3960 pages_per_cluster, blob_op_complete, NULL); 3961 CU_ASSERT(g_bserrno == 0); 3962 3963 /* Update expected result */ 3964 memcpy(payload_clone + (cluster_size * i), payload_write, 3965 cluster_size); 3966 } 3967 CU_ASSERT(free_clusters != spdk_bs_free_cluster_count(bs)); 3968 3969 /* Check data consistency on clone */ 3970 memset(payload_read, 0xFF, payload_size); 3971 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, 3972 blob_op_complete, NULL); 3973 CU_ASSERT(g_bserrno == 0); 3974 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 3975 3976 /* Close all blobs */ 3977 spdk_blob_close(blob, blob_op_complete, NULL); 3978 CU_ASSERT(g_bserrno == 0); 3979 3980 spdk_blob_close(snapshot, blob_op_complete, NULL); 3981 CU_ASSERT(g_bserrno == 0); 3982 3983 /* Inflate blob */ 3984 spdk_bs_inflate_blob(bs, channel, blobid, blob_op_complete, NULL); 3985 CU_ASSERT(g_bserrno == 0); 3986 3987 /* Try to delete snapshot (should pass) */ 3988 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 3989 CU_ASSERT(g_bserrno == 0); 3990 3991 /* Reopen blob after snapshot deletion */ 3992 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 3993 CU_ASSERT(g_bserrno == 0); 3994 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 3995 blob = g_blob; 3996 3997 CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5); 3998 3999 /* Check data consistency on inflated blob */ 4000 memset(payload_read, 0xFF, payload_size); 4001 spdk_blob_io_read(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL); 4002 CU_ASSERT(g_bserrno == 0); 4003 CU_ASSERT(memcmp(payload_clone, payload_read, payload_size) == 0); 4004 4005 spdk_blob_close(blob, blob_op_complete, NULL); 4006 CU_ASSERT(g_bserrno == 0); 4007 4008 spdk_bs_free_io_channel(channel); 4009 4010 /* Unload the blob store */ 4011 spdk_bs_unload(g_bs, bs_op_complete, NULL); 4012 CU_ASSERT(g_bserrno == 0); 4013 g_bs = NULL; 4014 g_blob = NULL; 4015 g_blobid = 0; 4016 4017 free(payload_read); 4018 free(payload_write); 4019 free(payload_clone); 4020 free(zero); 4021 } 4022 4023 /** 4024 * Snapshot-clones relation test 4025 * 4026 * snapshot 4027 * | 4028 * +----+----+ 4029 * | | 4030 * blob clone 4031 * | 4032 * clone2 4033 */ 4034 static void 4035 blob_relations(void) 4036 { 4037 struct spdk_blob_store *bs; 4038 struct spdk_bs_dev *dev; 4039 struct spdk_bs_opts bs_opts; 4040 struct spdk_blob_opts opts; 4041 struct spdk_blob *blob, *snapshot, *clone, *clone2; 4042 spdk_blob_id blobid, cloneid, snapshotid, cloneid2; 4043 int rc; 4044 size_t count; 4045 spdk_blob_id ids[10]; 4046 4047 dev = init_dev(); 4048 spdk_bs_opts_init(&bs_opts); 4049 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4050 4051 spdk_bs_init(dev, &bs_opts, bs_op_with_handle_complete, NULL); 4052 CU_ASSERT(g_bserrno == 0); 4053 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4054 bs = g_bs; 4055 4056 /* 1. Create blob with 10 clusters */ 4057 4058 spdk_blob_opts_init(&opts); 4059 opts.num_clusters = 10; 4060 4061 spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL); 4062 CU_ASSERT(g_bserrno == 0); 4063 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4064 blobid = g_blobid; 4065 4066 spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL); 4067 CU_ASSERT(g_bserrno == 0); 4068 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4069 blob = g_blob; 4070 4071 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4072 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4073 CU_ASSERT(!spdk_blob_is_clone(blob)); 4074 CU_ASSERT(!spdk_blob_is_thin_provisioned(blob)); 4075 4076 /* blob should not have underlying snapshot nor clones */ 4077 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID); 4078 count = SPDK_COUNTOF(ids); 4079 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4080 CU_ASSERT(rc == 0); 4081 CU_ASSERT(count == 0); 4082 4083 4084 /* 2. Create snapshot */ 4085 4086 spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4087 CU_ASSERT(g_bserrno == 0); 4088 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4089 snapshotid = g_blobid; 4090 4091 spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL); 4092 CU_ASSERT(g_bserrno == 0); 4093 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4094 snapshot = g_blob; 4095 4096 CU_ASSERT(spdk_blob_is_read_only(snapshot)); 4097 CU_ASSERT(spdk_blob_is_snapshot(snapshot)); 4098 CU_ASSERT(!spdk_blob_is_clone(snapshot)); 4099 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4100 4101 /* Check if original blob is converted to the clone of snapshot */ 4102 CU_ASSERT(!spdk_blob_is_read_only(blob)); 4103 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4104 CU_ASSERT(spdk_blob_is_clone(blob)); 4105 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4106 4107 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4108 4109 count = SPDK_COUNTOF(ids); 4110 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4111 CU_ASSERT(rc == 0); 4112 CU_ASSERT(count == 1); 4113 CU_ASSERT(ids[0] == blobid); 4114 4115 4116 /* 3. Create clone from snapshot */ 4117 4118 spdk_bs_create_clone(bs, snapshotid, NULL, blob_op_with_id_complete, NULL); 4119 CU_ASSERT(g_bserrno == 0); 4120 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4121 cloneid = g_blobid; 4122 4123 spdk_bs_open_blob(bs, cloneid, blob_op_with_handle_complete, NULL); 4124 CU_ASSERT(g_bserrno == 0); 4125 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4126 clone = g_blob; 4127 4128 CU_ASSERT(!spdk_blob_is_read_only(clone)); 4129 CU_ASSERT(!spdk_blob_is_snapshot(clone)); 4130 CU_ASSERT(spdk_blob_is_clone(clone)); 4131 CU_ASSERT(spdk_blob_is_thin_provisioned(clone)); 4132 4133 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4134 4135 count = SPDK_COUNTOF(ids); 4136 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4137 CU_ASSERT(rc == 0); 4138 CU_ASSERT(count == 0); 4139 4140 /* Check if clone is on the snapshot's list */ 4141 count = SPDK_COUNTOF(ids); 4142 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4143 CU_ASSERT(rc == 0); 4144 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4145 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4146 4147 4148 /* 4. Try to create clone from read only blob */ 4149 4150 /* Mark blob as read only */ 4151 spdk_blob_set_read_only(blob); 4152 spdk_blob_sync_md(blob, blob_op_complete, NULL); 4153 CU_ASSERT(g_bserrno == 0); 4154 4155 /* Check if previously created blob is read only clone */ 4156 CU_ASSERT(spdk_blob_is_read_only(blob)); 4157 CU_ASSERT(!spdk_blob_is_snapshot(blob)); 4158 CU_ASSERT(spdk_blob_is_clone(blob)); 4159 CU_ASSERT(spdk_blob_is_thin_provisioned(blob)); 4160 4161 /* Create clone from read only blob */ 4162 spdk_bs_create_clone(bs, blobid, NULL, blob_op_with_id_complete, NULL); 4163 CU_ASSERT(g_bserrno == 0); 4164 CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID); 4165 cloneid2 = g_blobid; 4166 4167 spdk_bs_open_blob(bs, cloneid2, blob_op_with_handle_complete, NULL); 4168 CU_ASSERT(g_bserrno == 0); 4169 SPDK_CU_ASSERT_FATAL(g_blob != NULL); 4170 clone2 = g_blob; 4171 4172 CU_ASSERT(!spdk_blob_is_read_only(clone2)); 4173 CU_ASSERT(!spdk_blob_is_snapshot(clone2)); 4174 CU_ASSERT(spdk_blob_is_clone(clone2)); 4175 CU_ASSERT(spdk_blob_is_thin_provisioned(clone2)); 4176 4177 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4178 4179 count = SPDK_COUNTOF(ids); 4180 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4181 CU_ASSERT(rc == 0); 4182 4183 CU_ASSERT(count == 1); 4184 CU_ASSERT(ids[0] == cloneid2); 4185 4186 /* Close blobs */ 4187 4188 spdk_blob_close(clone2, blob_op_complete, NULL); 4189 CU_ASSERT(g_bserrno == 0); 4190 4191 spdk_blob_close(blob, blob_op_complete, NULL); 4192 CU_ASSERT(g_bserrno == 0); 4193 4194 spdk_blob_close(clone, blob_op_complete, NULL); 4195 CU_ASSERT(g_bserrno == 0); 4196 4197 spdk_blob_close(snapshot, blob_op_complete, NULL); 4198 CU_ASSERT(g_bserrno == 0); 4199 4200 /* Try to delete snapshot with created clones */ 4201 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4202 CU_ASSERT(g_bserrno != 0); 4203 4204 spdk_bs_unload(bs, bs_op_complete, NULL); 4205 CU_ASSERT(g_bserrno == 0); 4206 g_bs = NULL; 4207 4208 /* Load an existing blob store */ 4209 dev = init_dev(); 4210 snprintf(bs_opts.bstype.bstype, sizeof(bs_opts.bstype.bstype), "TESTTYPE"); 4211 4212 spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL); 4213 CU_ASSERT(g_bserrno == 0); 4214 SPDK_CU_ASSERT_FATAL(g_bs != NULL); 4215 bs = g_bs; 4216 4217 4218 /* NULL ids array should return number of clones in count */ 4219 count = SPDK_COUNTOF(ids); 4220 rc = spdk_blob_get_clones(bs, snapshotid, NULL, &count); 4221 CU_ASSERT(rc == -ENOMEM); 4222 CU_ASSERT(count == 2); 4223 4224 /* incorrect array size */ 4225 count = 1; 4226 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4227 CU_ASSERT(rc == -ENOMEM); 4228 CU_ASSERT(count == 2); 4229 4230 4231 /* Verify structure of loaded blob store */ 4232 4233 /* snapshot */ 4234 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, snapshotid) == SPDK_BLOBID_INVALID); 4235 4236 count = SPDK_COUNTOF(ids); 4237 rc = spdk_blob_get_clones(bs, snapshotid, ids, &count); 4238 CU_ASSERT(rc == 0); 4239 CU_ASSERT(count == 2); 4240 CU_ASSERT(ids[0] == blobid || ids[1] == blobid); 4241 CU_ASSERT(ids[0] == cloneid || ids[1] == cloneid); 4242 4243 /* blob */ 4244 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid); 4245 count = SPDK_COUNTOF(ids); 4246 rc = spdk_blob_get_clones(bs, blobid, ids, &count); 4247 CU_ASSERT(rc == 0); 4248 CU_ASSERT(count == 1); 4249 CU_ASSERT(ids[0] == cloneid2); 4250 4251 /* clone */ 4252 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid) == snapshotid); 4253 count = SPDK_COUNTOF(ids); 4254 rc = spdk_blob_get_clones(bs, cloneid, ids, &count); 4255 CU_ASSERT(rc == 0); 4256 CU_ASSERT(count == 0); 4257 4258 /* clone2 */ 4259 CU_ASSERT(spdk_blob_get_parent_snapshot(bs, cloneid2) == blobid); 4260 count = SPDK_COUNTOF(ids); 4261 rc = spdk_blob_get_clones(bs, cloneid2, ids, &count); 4262 CU_ASSERT(rc == 0); 4263 CU_ASSERT(count == 0); 4264 4265 /* Try to delete all blobs */ 4266 spdk_bs_delete_blob(bs, cloneid, blob_op_complete, NULL); 4267 CU_ASSERT(g_bserrno == 0); 4268 4269 /* Try to delete snapshot with clones */ 4270 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4271 CU_ASSERT(g_bserrno != 0); 4272 4273 /* Try to delete ro blob with clones */ 4274 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4275 CU_ASSERT(g_bserrno != 0); 4276 4277 spdk_bs_delete_blob(bs, cloneid2, blob_op_complete, NULL); 4278 CU_ASSERT(g_bserrno == 0); 4279 4280 spdk_bs_delete_blob(bs, blobid, blob_op_complete, NULL); 4281 CU_ASSERT(g_bserrno == 0); 4282 4283 spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL); 4284 CU_ASSERT(g_bserrno == 0); 4285 4286 spdk_bs_unload(bs, bs_op_complete, NULL); 4287 CU_ASSERT(g_bserrno == 0); 4288 4289 g_bs = NULL; 4290 } 4291 4292 int main(int argc, char **argv) 4293 { 4294 CU_pSuite suite = NULL; 4295 unsigned int num_failures; 4296 4297 if (CU_initialize_registry() != CUE_SUCCESS) { 4298 return CU_get_error(); 4299 } 4300 4301 suite = CU_add_suite("blob", NULL, NULL); 4302 if (suite == NULL) { 4303 CU_cleanup_registry(); 4304 return CU_get_error(); 4305 } 4306 4307 if ( 4308 CU_add_test(suite, "blob_init", blob_init) == NULL || 4309 CU_add_test(suite, "blob_open", blob_open) == NULL || 4310 CU_add_test(suite, "blob_create", blob_create) == NULL || 4311 CU_add_test(suite, "blob_create_internal", blob_create_internal) == NULL || 4312 CU_add_test(suite, "blob_thin_provision", blob_thin_provision) == NULL || 4313 CU_add_test(suite, "blob_snapshot", blob_snapshot) == NULL || 4314 CU_add_test(suite, "blob_clone", blob_clone) == NULL || 4315 CU_add_test(suite, "blob_inflate", blob_inflate) == NULL || 4316 CU_add_test(suite, "blob_delete", blob_delete) == NULL || 4317 CU_add_test(suite, "blob_resize", blob_resize) == NULL || 4318 CU_add_test(suite, "blob_read_only", blob_read_only) == NULL || 4319 CU_add_test(suite, "channel_ops", channel_ops) == NULL || 4320 CU_add_test(suite, "blob_super", blob_super) == NULL || 4321 CU_add_test(suite, "blob_write", blob_write) == NULL || 4322 CU_add_test(suite, "blob_read", blob_read) == NULL || 4323 CU_add_test(suite, "blob_rw_verify", blob_rw_verify) == NULL || 4324 CU_add_test(suite, "blob_rw_verify_iov", blob_rw_verify_iov) == NULL || 4325 CU_add_test(suite, "blob_rw_verify_iov_nomem", blob_rw_verify_iov_nomem) == NULL || 4326 CU_add_test(suite, "blob_rw_iov_read_only", blob_rw_iov_read_only) == NULL || 4327 CU_add_test(suite, "blob_unmap", blob_unmap) == NULL || 4328 CU_add_test(suite, "blob_iter", blob_iter) == NULL || 4329 CU_add_test(suite, "blob_xattr", blob_xattr) == NULL || 4330 CU_add_test(suite, "bs_load", bs_load) == NULL || 4331 CU_add_test(suite, "bs_unload", bs_unload) == NULL || 4332 CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL || 4333 CU_add_test(suite, "bs_usable_clusters", bs_usable_clusters) == NULL || 4334 CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL || 4335 CU_add_test(suite, "bs_destroy", bs_destroy) == NULL || 4336 CU_add_test(suite, "bs_type", bs_type) == NULL || 4337 CU_add_test(suite, "bs_super_block", bs_super_block) == NULL || 4338 CU_add_test(suite, "blob_serialize", blob_serialize) == NULL || 4339 CU_add_test(suite, "blob_crc", blob_crc) == NULL || 4340 CU_add_test(suite, "super_block_crc", super_block_crc) == NULL || 4341 CU_add_test(suite, "blob_dirty_shutdown", blob_dirty_shutdown) == NULL || 4342 CU_add_test(suite, "blob_flags", blob_flags) == NULL || 4343 CU_add_test(suite, "bs_version", bs_version) == NULL || 4344 CU_add_test(suite, "blob_set_xattrs", blob_set_xattrs) == NULL || 4345 CU_add_test(suite, "blob_thin_prov_alloc", blob_thin_prov_alloc) == NULL || 4346 CU_add_test(suite, "blob_insert_cluster_msg", blob_insert_cluster_msg) == NULL || 4347 CU_add_test(suite, "blob_thin_prov_rw", blob_thin_prov_rw) == NULL || 4348 CU_add_test(suite, "blob_thin_prov_rw_iov", blob_thin_prov_rw_iov) == NULL || 4349 CU_add_test(suite, "bs_load_iter", bs_load_iter) == NULL || 4350 CU_add_test(suite, "blob_snapshot_rw", blob_snapshot_rw) == NULL || 4351 CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL || 4352 CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL || 4353 CU_add_test(suite, "blob_relations", blob_relations) == NULL 4354 ) { 4355 CU_cleanup_registry(); 4356 return CU_get_error(); 4357 } 4358 4359 g_dev_buffer = calloc(1, DEV_BUFFER_SIZE); 4360 spdk_allocate_thread(_bs_send_msg, NULL, NULL, NULL, "thread0"); 4361 CU_basic_set_mode(CU_BRM_VERBOSE); 4362 CU_basic_run_tests(); 4363 num_failures = CU_get_number_of_failures(); 4364 CU_cleanup_registry(); 4365 spdk_free_thread(); 4366 free(g_dev_buffer); 4367 return num_failures; 4368 } 4369